Merge branch 'trunk' into fix-11903-pr-create-same-ref
This commit is contained in:
commit
c4fd102016
939 changed files with 1653 additions and 157151 deletions
23
.github/workflows/deployment.yml
vendored
23
.github/workflows/deployment.yml
vendored
|
|
@ -56,6 +56,12 @@ jobs:
|
|||
# our scripts, which rely on the specific file names generated by GoReleaser.
|
||||
version: v2.13.1
|
||||
install-only: true
|
||||
# We temporarily create a tag on HEAD to make the right version embedded
|
||||
# in the built binaries, BUT we don't push it to the remote.
|
||||
- name: Create temporary tag
|
||||
env:
|
||||
TAG_NAME: ${{ inputs.tag_name }}
|
||||
run: git tag "$TAG_NAME"
|
||||
- name: Build release binaries
|
||||
env:
|
||||
TAG_NAME: ${{ inputs.tag_name }}
|
||||
|
|
@ -111,6 +117,12 @@ jobs:
|
|||
# our scripts, which rely on the specific file names generated by GoReleaser.
|
||||
version: v2.13.1
|
||||
install-only: true
|
||||
# We temporarily create a tag on HEAD to make the right version embedded
|
||||
# in the built binaries, BUT we don't push it to the remote.
|
||||
- name: Create temporary tag
|
||||
env:
|
||||
TAG_NAME: ${{ inputs.tag_name }}
|
||||
run: git tag "$TAG_NAME"
|
||||
- name: Build release binaries
|
||||
env:
|
||||
TAG_NAME: ${{ inputs.tag_name }}
|
||||
|
|
@ -176,7 +188,7 @@ jobs:
|
|||
METADATA_PATH: ${{ runner.temp }}\acs\metadata.json
|
||||
run: |
|
||||
# Download Azure Code Signing client containing the DLL needed for signtool in script/sign
|
||||
Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Azure.CodeSigning.Client/1.0.43 -OutFile $Env:ACS_ZIP -Verbose
|
||||
Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Microsoft.Trusted.Signing.Client/1.0.95 -OutFile $Env:ACS_ZIP -Verbose
|
||||
Expand-Archive $Env:ACS_ZIP -Destination $Env:ACS_DIR -Force -Verbose
|
||||
|
||||
# Generate metadata file for signtool, used in signing box .exe and .msi
|
||||
|
|
@ -184,9 +196,16 @@ jobs:
|
|||
CertificateProfileName = "GitHubInc"
|
||||
CodeSigningAccountName = "GitHubInc"
|
||||
CorrelationId = $Env:CORRELATION_ID
|
||||
Endpoint = "https://wus.codesigning.azure.net/"
|
||||
Endpoint = "https://wus3.codesigning.azure.net/"
|
||||
} | ConvertTo-Json | Out-File -FilePath $Env:METADATA_PATH
|
||||
|
||||
# We temporarily create a tag on HEAD to make the right version embedded
|
||||
# in the built binaries, BUT we don't push it to the remote.
|
||||
- name: Create temporary tag
|
||||
shell: bash
|
||||
env:
|
||||
TAG_NAME: ${{ inputs.tag_name }}
|
||||
run: git tag "$TAG_NAME"
|
||||
# Azure Code Signing leverages the environment variables for secrets that complement the metadata.json
|
||||
# file generated above (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID)
|
||||
# For more information, see https://learn.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet
|
||||
|
|
|
|||
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
|
|
@ -59,7 +59,7 @@ jobs:
|
|||
run: |
|
||||
export GOROOT=$(go env GOROOT)
|
||||
export PATH=${GOROOT}/bin:$PATH
|
||||
go install github.com/google/go-licenses@5348b744d0983d85713295ea08a20cca1654a45e # v2.0.1
|
||||
go install github.com/google/go-licenses/v2@3e084b0caf710f7bfead967567539214f598c0a2 # v2.0.1
|
||||
make licenses-check
|
||||
|
||||
# Discover vulnerabilities within Go standard libraries used to build GitHub CLI using govulncheck.
|
||||
|
|
|
|||
|
|
@ -3,14 +3,27 @@ version: "2"
|
|||
linters:
|
||||
default: none
|
||||
enable:
|
||||
- bodyclose
|
||||
- copyloopvar
|
||||
- durationcheck
|
||||
- gocritic
|
||||
- govet
|
||||
- ineffassign
|
||||
- nilerr
|
||||
- nolintlint
|
||||
- asasalint # checks for pass []any as any in variadic func(...any)
|
||||
- asciicheck # checks that your code does not contain non-ASCII identifiers
|
||||
- bidichk # checks for dangerous unicode character sequences
|
||||
- bodyclose # checks whether HTTP response body is closed successfully
|
||||
- copyloopvar # detects places where loop variables are copied (Go 1.22+)
|
||||
- durationcheck # checks for two durations multiplied together
|
||||
- exptostd # detects functions from golang.org/x/exp/ that can be replaced by std functions
|
||||
- fatcontext # detects nested contexts in loops
|
||||
- gocheckcompilerdirectives # validates go compiler directive comments (//go:)
|
||||
- gochecksumtype # checks exhaustiveness on Go "sum types"
|
||||
- gocritic # provides diagnostics that check for bugs, performance and style issues
|
||||
- gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod
|
||||
- goprintffuncname # checks that printf-like functions are named with f at the end
|
||||
- govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
|
||||
- ineffassign # detects when assignments to existing variables are not used
|
||||
- nilerr # finds the code that returns nil even if it checks that the error is not nil
|
||||
- nolintlint # reports ill-formed or insufficient nolint directives
|
||||
- nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL
|
||||
- reassign # checks that package variables are not reassigned
|
||||
- unused # checks for unused constants, variables, functions and types
|
||||
|
||||
# To enable later due to too many issues, and confirm we need them:
|
||||
# - gosec
|
||||
# - staticcheck
|
||||
|
|
|
|||
127
go.mod
127
go.mod
|
|
@ -44,13 +44,13 @@ require (
|
|||
github.com/rivo/tview v0.42.0
|
||||
github.com/shurcooL/githubv4 v0.0.0-20240727222349-48295856cce7
|
||||
github.com/sigstore/protobuf-specs v0.5.0
|
||||
github.com/sigstore/sigstore-go v1.1.3
|
||||
github.com/sigstore/sigstore-go v1.1.4
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/spf13/pflag v1.0.10
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/theupdateframework/go-tuf/v2 v2.3.0
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1
|
||||
github.com/yuin/goldmark v1.7.13
|
||||
github.com/yuin/goldmark v1.7.16
|
||||
github.com/zalando/go-keyring v0.2.6
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/sync v0.19.0
|
||||
|
|
@ -64,21 +64,7 @@ require (
|
|||
|
||||
require (
|
||||
al.essio.dev/pkg/shellescape v1.6.0 // indirect
|
||||
cel.dev/expr v0.24.0 // indirect
|
||||
cloud.google.com/go v0.121.6 // indirect
|
||||
cloud.google.com/go/auth v0.16.5 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||
cloud.google.com/go/iam v1.5.2 // indirect
|
||||
cloud.google.com/go/longrunning v0.6.7 // indirect
|
||||
cloud.google.com/go/monitoring v1.24.2 // indirect
|
||||
cloud.google.com/go/spanner v1.84.1 // indirect
|
||||
cloud.google.com/go/storage v1.56.1 // indirect
|
||||
dario.cat/mergo v1.0.2 // indirect
|
||||
github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.3 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
|
||||
|
|
@ -88,18 +74,16 @@ require (
|
|||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/catppuccin/go v0.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 // indirect
|
||||
github.com/charmbracelet/bubbletea v1.3.6 // indirect
|
||||
github.com/charmbracelet/bubbletea v1.3.10 // indirect
|
||||
github.com/charmbracelet/colorprofile v0.3.1 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.9.3 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.10.2 // indirect
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
|
||||
github.com/charmbracelet/x/exp/slice v0.0.0-20250630141444-821143405392 // indirect
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20250630141444-821143405392 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.1 // indirect
|
||||
github.com/cli/browser v1.3.0 // indirect
|
||||
github.com/cli/shurcooL-graphql v0.0.4 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.18.1 // indirect
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect
|
||||
github.com/danieljoos/wincred v1.2.2 // indirect
|
||||
|
|
@ -110,50 +94,39 @@ require (
|
|||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.9.3 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/gdamore/encoding v1.0.1 // indirect
|
||||
github.com/go-chi/chi/v5 v5.2.3 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||
github.com/go-openapi/errors v0.22.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.1 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/loads v0.22.0 // indirect
|
||||
github.com/go-openapi/runtime v0.28.0 // indirect
|
||||
github.com/go-openapi/spec v0.21.0 // indirect
|
||||
github.com/go-openapi/strfmt v0.23.0 // indirect
|
||||
github.com/go-openapi/swag v0.24.1 // indirect
|
||||
github.com/go-openapi/swag/cmdutils v0.24.0 // indirect
|
||||
github.com/go-openapi/swag/conv v0.24.0 // indirect
|
||||
github.com/go-openapi/swag/fileutils v0.24.0 // indirect
|
||||
github.com/go-openapi/swag/jsonname v0.24.0 // indirect
|
||||
github.com/go-openapi/swag/jsonutils v0.24.0 // indirect
|
||||
github.com/go-openapi/swag/loading v0.24.0 // indirect
|
||||
github.com/go-openapi/swag/mangling v0.24.0 // indirect
|
||||
github.com/go-openapi/swag/netutils v0.24.0 // indirect
|
||||
github.com/go-openapi/swag/stringutils v0.24.0 // indirect
|
||||
github.com/go-openapi/swag/typeutils v0.24.0 // indirect
|
||||
github.com/go-openapi/swag/yamlutils v0.24.0 // indirect
|
||||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/go-openapi/analysis v0.24.1 // indirect
|
||||
github.com/go-openapi/errors v0.22.4 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.22.1 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.3 // indirect
|
||||
github.com/go-openapi/loads v0.23.2 // indirect
|
||||
github.com/go-openapi/runtime v0.29.2 // indirect
|
||||
github.com/go-openapi/spec v0.22.1 // indirect
|
||||
github.com/go-openapi/strfmt v0.25.0 // 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/validate v0.25.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/google/certificate-transparency-go v1.3.2 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
||||
github.com/gorilla/css v1.0.1 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/henvic/httpretty v0.1.4 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/in-toto/in-toto-golang v0.9.0 // indirect
|
||||
|
|
@ -161,18 +134,14 @@ require (
|
|||
github.com/itchyny/gojq v0.12.17 // indirect
|
||||
github.com/itchyny/timefmt-go v0.1.6 // indirect
|
||||
github.com/jedisct1/go-minisign v0.0.0-20241212093149-d2f9f49435c7 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.18.1 // indirect
|
||||
github.com/letsencrypt/boulder v0.20250630.0 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.17 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
|
|
@ -181,65 +150,39 @@ require (
|
|||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rodaine/table v1.3.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.9.0 // indirect
|
||||
github.com/sassoftware/relic v7.2.1+incompatible // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.9.1 // indirect
|
||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 // indirect
|
||||
github.com/sigstore/rekor v1.4.2 // indirect
|
||||
github.com/sigstore/rekor-tiles v0.1.11 // indirect
|
||||
github.com/sigstore/sigstore v1.9.6-0.20250729224751-181c5d3339b3 // indirect
|
||||
github.com/sigstore/timestamp-authority v1.2.9 // indirect
|
||||
github.com/sigstore/rekor v1.4.3 // indirect
|
||||
github.com/sigstore/rekor-tiles/v2 v2.0.1 // indirect
|
||||
github.com/sigstore/sigstore v1.10.0 // indirect
|
||||
github.com/sigstore/timestamp-authority/v2 v2.0.3 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.14.0 // indirect
|
||||
github.com/spf13/cast v1.9.2 // indirect
|
||||
github.com/spf13/viper v1.20.1 // indirect
|
||||
github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/theupdateframework/go-tuf v0.7.0 // indirect
|
||||
github.com/thlib/go-timezone-local v0.0.6 // indirect
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
|
||||
github.com/transparency-dev/formats v0.0.0-20250421220931-bb8ad4d07c26 // indirect
|
||||
github.com/transparency-dev/formats v0.0.0-20251017110053-404c0d5b696c // indirect
|
||||
github.com/transparency-dev/merkle v0.0.2 // indirect
|
||||
github.com/transparency-dev/tessera v1.0.0-rc3 // indirect
|
||||
github.com/vbatts/tar-split v0.12.2 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
github.com/yuin/goldmark-emoji v1.0.6 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.4 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.6 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.38.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.38.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
|
||||
golang.org/x/mod v0.30.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/oauth2 v0.33.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools v0.39.0 // indirect
|
||||
google.golang.org/api v0.248.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101 // indirect
|
||||
)
|
||||
|
|
|
|||
BIN
internal/zip/fixtures/myproject.zip
Normal file
BIN
internal/zip/fixtures/myproject.zip
Normal file
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
package download
|
||||
package zip
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
|
|
@ -17,7 +17,11 @@ const (
|
|||
execMode os.FileMode = 0755
|
||||
)
|
||||
|
||||
func extractZip(zr *zip.Reader, destDir safepaths.Absolute) error {
|
||||
// ExtractZip extracts the contents of a zip archive to destDir.
|
||||
// Files that would result in path traversal are silently skipped.
|
||||
// Files that would produce any other error cause the extraction to be aborted,
|
||||
// and the error is returned.
|
||||
func ExtractZip(zr *zip.Reader, destDir safepaths.Absolute) error {
|
||||
for _, zf := range zr.File {
|
||||
fpath, err := destDir.Join(zf.Name)
|
||||
if err != nil {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package download
|
||||
package zip
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
|
|
@ -19,7 +19,7 @@ func Test_extractZip(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer zipFile.Close()
|
||||
|
||||
err = extractZip(&zipFile.Reader, extractPath)
|
||||
err = ExtractZip(&zipFile.Reader, extractPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = os.Stat(filepath.Join(extractPath.String(), "src", "main.go"))
|
||||
455
pkg/cmd/copilot/copilot.go
Normal file
455
pkg/cmd/copilot/copilot.go
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
package copilot
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"archive/zip"
|
||||
"bufio"
|
||||
"compress/gzip"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/cli/cli/v2/internal/config"
|
||||
"github.com/cli/cli/v2/internal/prompter"
|
||||
"github.com/cli/cli/v2/internal/safepaths"
|
||||
"github.com/cli/cli/v2/internal/update"
|
||||
ghzip "github.com/cli/cli/v2/internal/zip"
|
||||
"github.com/cli/cli/v2/pkg/cmdutil"
|
||||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type CopilotOptions struct {
|
||||
IO *iostreams.IOStreams
|
||||
HttpClient func() (*http.Client, error)
|
||||
Prompter prompter.Prompter
|
||||
|
||||
CopilotArgs []string
|
||||
Remove bool
|
||||
}
|
||||
|
||||
func NewCmdCopilot(f *cmdutil.Factory, runF func(*CopilotOptions) error) *cobra.Command {
|
||||
opts := &CopilotOptions{
|
||||
IO: f.IOStreams,
|
||||
HttpClient: f.HttpClient,
|
||||
Prompter: f.Prompter,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "copilot [flags] [args]",
|
||||
Short: "Run the GitHub Copilot CLI (preview)",
|
||||
Long: heredoc.Docf(`
|
||||
Runs the GitHub Copilot CLI.
|
||||
|
||||
Executing the Copilot CLI through %[1]sgh%[1]s is currently in preview and subject to change.
|
||||
|
||||
If already installed, %[1]sgh%[1]s will execute the Copilot CLI found in your %[1]sPATH%[1]s.
|
||||
If the Copilot CLI is not installed, it will be downloaded to %[2]s.
|
||||
|
||||
Use %[1]s--remove%[1]s to remove the downloaded Copilot CLI.
|
||||
|
||||
This command is only supported on Windows, Linux, and Darwin, on amd64/x64
|
||||
or arm64 architectures.
|
||||
|
||||
To prevent %[1]sgh%[1]s from interpreting flags intended for Copilot,
|
||||
use %[1]s--%[1]s before Copilot flags and args.
|
||||
|
||||
Learn more at https://gh.io/copilot-cli
|
||||
`, "`", copilotInstallDir()),
|
||||
Example: heredoc.Doc(`
|
||||
# Download and run the Copilot CLI
|
||||
$ gh copilot
|
||||
|
||||
# Run the Copilot CLI
|
||||
$ gh copilot -p "Summarize this week's commits" --allow-tool 'shell(git)'
|
||||
|
||||
# Remove the Copilot CLI (if installed through gh)
|
||||
$ gh copilot --remove
|
||||
|
||||
# Run the Copilot CLI help command
|
||||
$ gh copilot -- --help
|
||||
`),
|
||||
DisableFlagParsing: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
stopParsePos := -1
|
||||
for i, arg := range args {
|
||||
if arg == "--" {
|
||||
stopParsePos = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
ghArgs := args
|
||||
opts.CopilotArgs = args
|
||||
if stopParsePos >= 0 {
|
||||
ghArgs = args[:stopParsePos]
|
||||
opts.CopilotArgs = args[stopParsePos+1:] // +1 to skip the "--" itself
|
||||
}
|
||||
|
||||
if slices.Contains(ghArgs, "--help") || slices.Contains(ghArgs, "-h") {
|
||||
return cmd.Help()
|
||||
}
|
||||
|
||||
if slices.Contains(ghArgs, "--remove") {
|
||||
hasOtherArgs := len(ghArgs) > 1
|
||||
if stopParsePos >= 0 {
|
||||
hasOtherArgs = hasOtherArgs || len(opts.CopilotArgs) > 0
|
||||
}
|
||||
if hasOtherArgs {
|
||||
return cmdutil.FlagErrorf("cannot use --remove with args")
|
||||
}
|
||||
opts.Remove = true
|
||||
opts.CopilotArgs = nil
|
||||
}
|
||||
|
||||
if runF != nil {
|
||||
return runF(opts)
|
||||
}
|
||||
|
||||
return runCopilot(opts)
|
||||
},
|
||||
}
|
||||
|
||||
cmdutil.DisableAuthCheck(cmd)
|
||||
|
||||
// We add this flag, even though flag parsing is disabled for this command
|
||||
// so the flag still appears in the help text.
|
||||
cmd.Flags().Bool("remove", false, "Remove the downloaded Copilot CLI")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runCopilot(opts *CopilotOptions) error {
|
||||
if opts.Remove {
|
||||
if err := removeCopilot(copilotInstallDir()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.IO.IsStdoutTTY() {
|
||||
fmt.Fprintln(opts.IO.ErrOut, "Copilot CLI removed successfully")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
copilotPath := findCopilotBinary()
|
||||
if copilotPath == "" {
|
||||
if opts.IO.CanPrompt() {
|
||||
confirmed, err := opts.Prompter.Confirm("GitHub Copilot CLI is not installed. Would you like to install it?", true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !confirmed {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Copilot CLI was not installed", opts.IO.ColorScheme().WarningIcon())
|
||||
return cmdutil.SilentError
|
||||
}
|
||||
} else if !update.IsCI() {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Copilot CLI not installed", opts.IO.ColorScheme().WarningIcon())
|
||||
return cmdutil.SilentError
|
||||
}
|
||||
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
copilotPath, err = downloadCopilot(httpClient, opts.IO, copilotInstallDir(), copilotBinaryPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
externalCmd := exec.Command(copilotPath, opts.CopilotArgs...)
|
||||
externalCmd.Stdin = opts.IO.In
|
||||
externalCmd.Stdout = opts.IO.Out
|
||||
externalCmd.Stderr = opts.IO.ErrOut
|
||||
|
||||
if err := externalCmd.Run(); err != nil {
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
// We terminate with os.Exit here, preserving the exit code from Copilot CLI,
|
||||
// and also preventing stdio writes by callers up the stack.
|
||||
os.Exit(exitErr.ExitCode())
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const copilotBinaryName = "copilot"
|
||||
|
||||
func copilotInstallDir() string {
|
||||
return filepath.Join(config.DataDir(), "copilot")
|
||||
}
|
||||
|
||||
func copilotBinaryPath() string {
|
||||
binaryName := copilotBinaryName
|
||||
if runtime.GOOS == "windows" {
|
||||
binaryName += ".exe"
|
||||
}
|
||||
return filepath.Join(copilotInstallDir(), binaryName)
|
||||
}
|
||||
|
||||
// findCopilotBinary returns the path to the Copilot CLI binary, if installed,
|
||||
// with the following order of precedence:
|
||||
// 1. `copilot` in the PATH
|
||||
// 2. `copilot` in gh's data directory
|
||||
//
|
||||
// If not installed, it returns an empty string.
|
||||
func findCopilotBinary() string {
|
||||
if path, err := exec.LookPath(copilotBinaryName); err == nil {
|
||||
return path
|
||||
}
|
||||
|
||||
localPath := copilotBinaryPath()
|
||||
if _, err := os.Stat(localPath); err != nil {
|
||||
return ""
|
||||
}
|
||||
return localPath
|
||||
}
|
||||
|
||||
// downloadCopilot downloads and installs the Copilot CLI to installDir.
|
||||
// It returns the path to the installed Copilot binary.
|
||||
func downloadCopilot(httpClient *http.Client, ios *iostreams.IOStreams, installDir, localPath string) (string, error) {
|
||||
platform := runtime.GOOS
|
||||
if platform == "windows" {
|
||||
platform = "win32"
|
||||
}
|
||||
|
||||
arch := runtime.GOARCH
|
||||
if arch == "amd64" {
|
||||
arch = "x64"
|
||||
}
|
||||
|
||||
if arch != "x64" && arch != "arm64" {
|
||||
return "", fmt.Errorf("unsupported architecture: %s (supported: x64, arm64)", arch)
|
||||
}
|
||||
|
||||
var archiveURL string
|
||||
var archiveName string
|
||||
var isZip bool
|
||||
switch platform {
|
||||
case "win32":
|
||||
archiveName = fmt.Sprintf("copilot-%s-%s.zip", platform, arch)
|
||||
archiveURL = fmt.Sprintf("https://github.com/github/copilot-cli/releases/latest/download/%s", archiveName)
|
||||
isZip = true
|
||||
case "linux", "darwin":
|
||||
archiveName = fmt.Sprintf("copilot-%s-%s.tar.gz", platform, arch)
|
||||
archiveURL = fmt.Sprintf("https://github.com/github/copilot-cli/releases/latest/download/%s", archiveName)
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported platform: %s (supported: linux, darwin, windows)", platform)
|
||||
}
|
||||
|
||||
checksumsURL := "https://github.com/github/copilot-cli/releases/latest/download/SHA256SUMS.txt"
|
||||
|
||||
expectedChecksum, err := fetchExpectedChecksum(httpClient, checksumsURL, archiveName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to fetch checksums: %w", err)
|
||||
}
|
||||
|
||||
ios.StartProgressIndicatorWithLabel(fmt.Sprintf("Downloading Copilot CLI from %s", archiveURL))
|
||||
defer ios.StopProgressIndicator()
|
||||
|
||||
resp, err := httpClient.Get(archiveURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to download: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("download failed with status: %s", resp.Status)
|
||||
}
|
||||
|
||||
// Download to temp file while calculating checksum
|
||||
tmpFile, err := os.CreateTemp("", "copilot-download-*")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create temp file: %w", err)
|
||||
}
|
||||
defer os.Remove(tmpFile.Name())
|
||||
defer tmpFile.Close()
|
||||
|
||||
hasher := sha256.New()
|
||||
if _, err := io.Copy(tmpFile, io.TeeReader(resp.Body, hasher)); err != nil {
|
||||
return "", fmt.Errorf("failed to download: %w", err)
|
||||
}
|
||||
|
||||
ios.StopProgressIndicator()
|
||||
|
||||
// Validate checksum
|
||||
actualChecksumHex := hex.EncodeToString(hasher.Sum(nil))
|
||||
if actualChecksumHex != expectedChecksum {
|
||||
return "", fmt.Errorf("checksum mismatch: expected %s, got %s", expectedChecksum, actualChecksumHex)
|
||||
}
|
||||
|
||||
if _, err := tmpFile.Seek(0, io.SeekStart); err != nil {
|
||||
return "", fmt.Errorf("failed to seek temp file: %w", err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(installDir, 0755); err != nil {
|
||||
return "", fmt.Errorf("failed to create install directory: %w", err)
|
||||
}
|
||||
|
||||
// Extract from the downloaded data
|
||||
if isZip {
|
||||
err = extractZip(tmpFile.Name(), installDir)
|
||||
} else {
|
||||
err = extractTarGz(tmpFile, installDir)
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(localPath); err != nil {
|
||||
return "", fmt.Errorf("copilot binary unavailable: %w", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(ios.ErrOut, "%s Copilot CLI installed successfully\n", ios.ColorScheme().SuccessIcon())
|
||||
return localPath, nil
|
||||
}
|
||||
|
||||
// fetchExpectedChecksum downloads the SHA256SUMS.txt file and returns the expected checksum for the given archive name.
|
||||
func fetchExpectedChecksum(httpClient *http.Client, checksumsURL, archiveName string) (string, error) {
|
||||
resp, err := httpClient.Get(checksumsURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("failed to download checksums: %s", resp.Status)
|
||||
}
|
||||
|
||||
// Parse the checksums file. Possible formats are:
|
||||
// - "<checksum> <filename>" (two whitespaces)
|
||||
// - "<checksum> <filename>"
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) >= 2 {
|
||||
checksum := fields[0]
|
||||
filename := fields[1]
|
||||
if filename == archiveName {
|
||||
return checksum, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return "", fmt.Errorf("failed to read checksums: %w", err)
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("checksum not found for %s", archiveName)
|
||||
}
|
||||
|
||||
// extractZip reads a ZIP archive at path and extracts its contents into destDir.
|
||||
// It returns an error if the archive cannot be read,
|
||||
// or if any file or directory within the archive cannot be created or written.
|
||||
func extractZip(path, destDir string) error {
|
||||
zipReader, err := zip.OpenReader(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open zip: %w", err)
|
||||
}
|
||||
defer zipReader.Close()
|
||||
|
||||
absPath, err := safepaths.ParseAbsolute(destDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// As of the time of writing, ghzip.ExtractZip will safely skip files that
|
||||
// would result in path traversal. This is an issue for our use-case because
|
||||
// we want to error out before extracting if there's any such file.
|
||||
// To avoid breaking the shared ghzip.ExtractZip code that expects unsafe
|
||||
// paths to be ignored and no error produced, we pre-validate here,
|
||||
// producing an error if any such file is found.
|
||||
for _, f := range zipReader.File {
|
||||
_, err := absPath.Join(f.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := ghzip.ExtractZip(&zipReader.Reader, absPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// extractTarGz reads a TAR.GZ archive from r and extracts its contents into destDir.
|
||||
// It returns an error if the archive cannot be read,
|
||||
// or if any file or directory within the archive cannot be created or written.
|
||||
func extractTarGz(r io.Reader, destDir string) error {
|
||||
gzr, err := gzip.NewReader(r)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create gzip reader: %w", err)
|
||||
}
|
||||
defer gzr.Close()
|
||||
|
||||
absDestDirPath, err := safepaths.ParseAbsolute(destDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tr := tar.NewReader(gzr)
|
||||
for {
|
||||
header, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read tar: %w", err)
|
||||
}
|
||||
|
||||
absFilePath, err := absDestDirPath.Join(header.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target := absFilePath.String()
|
||||
|
||||
if header.Typeflag == tar.TypeReg {
|
||||
if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil {
|
||||
return fmt.Errorf("failed to create parent directory: %w", err)
|
||||
}
|
||||
if err := extractFile(target, os.FileMode(header.Mode)&0777, tr); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// extractFile creates a file at target with the given mode and copies content from r.
|
||||
func extractFile(target string, mode os.FileMode, r io.Reader) (err error) {
|
||||
out, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create file: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if cerr := out.Close(); err == nil && cerr != nil {
|
||||
err = fmt.Errorf("failed to close file: %w", cerr)
|
||||
}
|
||||
}()
|
||||
if _, err := io.Copy(out, r); err != nil {
|
||||
return fmt.Errorf("failed to write file: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeCopilot(installDir string) error {
|
||||
if _, err := os.Stat(installDir); os.IsNotExist(err) {
|
||||
return fmt.Errorf("failed to remove Copilot CLI: Copilot CLI not installed through `gh`")
|
||||
}
|
||||
|
||||
if err := os.RemoveAll(installDir); err != nil {
|
||||
return fmt.Errorf("failed to remove Copilot CLI: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
588
pkg/cmd/copilot/copilot_test.go
Normal file
588
pkg/cmd/copilot/copilot_test.go
Normal file
|
|
@ -0,0 +1,588 @@
|
|||
package copilot
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/cli/cli/v2/pkg/cmdutil"
|
||||
"github.com/cli/cli/v2/pkg/httpmock"
|
||||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
"github.com/google/shlex"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewCmdCopilot(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args string
|
||||
wantOpts CopilotOptions
|
||||
wantErrString string
|
||||
wantHelp bool
|
||||
}{
|
||||
{
|
||||
name: "no argument",
|
||||
args: "",
|
||||
wantOpts: CopilotOptions{
|
||||
CopilotArgs: []string{},
|
||||
},
|
||||
wantErrString: "",
|
||||
},
|
||||
{
|
||||
name: "with arguments",
|
||||
args: "some-arg some-other-arg",
|
||||
wantOpts: CopilotOptions{
|
||||
CopilotArgs: []string{"some-arg", "some-other-arg"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with --remove alone",
|
||||
args: "--remove",
|
||||
wantOpts: CopilotOptions{
|
||||
Remove: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with non-gh flags passed to copilot",
|
||||
args: "-p testing --something-flag",
|
||||
wantOpts: CopilotOptions{
|
||||
CopilotArgs: []string{"-p", "testing", "--something-flag"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with --remove and arguments",
|
||||
args: "--remove some-arg",
|
||||
wantErrString: "cannot use --remove with args",
|
||||
},
|
||||
{
|
||||
name: "with --remove passed to copilot using --",
|
||||
args: "-- --remove",
|
||||
wantOpts: CopilotOptions{
|
||||
CopilotArgs: []string{"--remove"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with --remove and -- alone",
|
||||
args: "--remove --",
|
||||
wantOpts: CopilotOptions{
|
||||
Remove: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with --remove, some invalid arg, and --",
|
||||
args: "--remove invalid-arg --",
|
||||
wantErrString: "cannot use --remove with args",
|
||||
},
|
||||
{
|
||||
name: "with --remove and -- and random arguments",
|
||||
args: "--remove -- some-arg",
|
||||
wantErrString: "cannot use --remove with args",
|
||||
},
|
||||
{
|
||||
name: "with --help, shows gh help",
|
||||
args: "--help",
|
||||
wantErrString: "",
|
||||
wantHelp: true,
|
||||
},
|
||||
{
|
||||
name: "with --help and --, shows copilot help",
|
||||
args: "-- --help",
|
||||
wantOpts: CopilotOptions{
|
||||
CopilotArgs: []string{"--help"},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
f := &cmdutil.Factory{}
|
||||
|
||||
argv, err := shlex.Split(tt.args)
|
||||
assert.NoError(t, err)
|
||||
|
||||
var gotOpts *CopilotOptions
|
||||
cmd := NewCmdCopilot(f, func(opts *CopilotOptions) error {
|
||||
gotOpts = opts
|
||||
return nil
|
||||
})
|
||||
|
||||
cmd.SetArgs(argv)
|
||||
cmd.SetIn(&bytes.Buffer{})
|
||||
cmd.SetOut(&bytes.Buffer{})
|
||||
cmd.SetErr(&bytes.Buffer{})
|
||||
|
||||
_, err = cmd.ExecuteC()
|
||||
if tt.wantErrString != "" {
|
||||
require.EqualError(t, err, tt.wantErrString)
|
||||
return
|
||||
}
|
||||
|
||||
if tt.wantHelp {
|
||||
require.NoError(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.wantOpts.CopilotArgs, gotOpts.CopilotArgs, "opts.CopilotArgs not as expected")
|
||||
assert.Equal(t, tt.wantOpts.Remove, gotOpts.Remove, "opts.Remove not as expected")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveCopilot(t *testing.T) {
|
||||
t.Run("removes existing install directory", func(t *testing.T) {
|
||||
// Create a temporary directory to simulate the install directory
|
||||
tmpDir := t.TempDir()
|
||||
installDir := filepath.Join(tmpDir, "copilot")
|
||||
require.NoError(t, os.MkdirAll(installDir, 0755), "failed to create test directory")
|
||||
// Create a dummy file in the directory
|
||||
dummyFile := filepath.Join(installDir, "copilot")
|
||||
require.NoError(t, os.WriteFile(dummyFile, []byte("test"), 0755), "failed to create test file")
|
||||
|
||||
err := removeCopilot(installDir)
|
||||
require.NoError(t, err, "unexpected error")
|
||||
|
||||
_, err = os.Stat(installDir)
|
||||
require.True(t, os.IsNotExist(err), "expected install directory to be removed")
|
||||
})
|
||||
|
||||
t.Run("handles non-existent directory", func(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
installDir := filepath.Join(tmpDir, "copilot")
|
||||
|
||||
require.ErrorContains(t, removeCopilot(installDir), "failed to remove Copilot CLI")
|
||||
})
|
||||
}
|
||||
|
||||
// createTarGzBuffer creates a tar.gz archive in memory with the given files.
|
||||
func createTarGzBuffer(t *testing.T, files map[string][]byte) []byte {
|
||||
t.Helper()
|
||||
var buf bytes.Buffer
|
||||
gw := gzip.NewWriter(&buf)
|
||||
tw := tar.NewWriter(gw)
|
||||
|
||||
for name, content := range files {
|
||||
hdr := &tar.Header{
|
||||
Name: name,
|
||||
Mode: 0755,
|
||||
Size: int64(len(content)),
|
||||
}
|
||||
require.NoError(t, tw.WriteHeader(hdr), "failed to write tar header")
|
||||
_, err := tw.Write(content)
|
||||
require.NoError(t, err, "failed to write tar content")
|
||||
}
|
||||
|
||||
require.NoError(t, tw.Close(), "failed to close tar writer")
|
||||
require.NoError(t, gw.Close(), "failed to close gzip writer")
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// createZipBuffer creates a zip archive in memory with the given files.
|
||||
func createZipBuffer(t *testing.T, files map[string][]byte) []byte {
|
||||
t.Helper()
|
||||
var buf bytes.Buffer
|
||||
zw := zip.NewWriter(&buf)
|
||||
|
||||
for name, content := range files {
|
||||
fw, err := zw.Create(name)
|
||||
require.NoError(t, err, "failed to create zip entry")
|
||||
_, err = fw.Write(content)
|
||||
require.NoError(t, err, "failed to write zip content")
|
||||
}
|
||||
|
||||
require.NoError(t, zw.Close(), "failed to close zip writer")
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func TestExtractTarGz(t *testing.T) {
|
||||
t.Run("extracts files correctly", func(t *testing.T) {
|
||||
content := []byte("hello world")
|
||||
archive := createTarGzBuffer(t, map[string][]byte{
|
||||
"copilot": content,
|
||||
})
|
||||
|
||||
destDir := t.TempDir()
|
||||
|
||||
err := extractTarGz(bytes.NewReader(archive), destDir)
|
||||
require.NoError(t, err, "extractTarGz() error")
|
||||
|
||||
extracted, err := os.ReadFile(filepath.Join(destDir, "copilot"))
|
||||
require.NoError(t, err, "failed to read extracted file")
|
||||
require.Equal(t, content, extracted, "extracted content mismatch")
|
||||
})
|
||||
|
||||
t.Run("extracts nested files", func(t *testing.T) {
|
||||
content := []byte("nested content")
|
||||
archive := createTarGzBuffer(t, map[string][]byte{
|
||||
"subdir/file.txt": content,
|
||||
})
|
||||
|
||||
destDir := t.TempDir()
|
||||
|
||||
err := extractTarGz(bytes.NewReader(archive), destDir)
|
||||
require.NoError(t, err, "extractTarGz() error")
|
||||
|
||||
extracted, err := os.ReadFile(filepath.Join(destDir, "subdir", "file.txt"))
|
||||
require.NoError(t, err, "failed to read extracted file")
|
||||
require.Equal(t, content, extracted, "extracted content mismatch")
|
||||
})
|
||||
|
||||
t.Run("rejects path traversal", func(t *testing.T) {
|
||||
// Manually create a malicious tar.gz with path traversal
|
||||
var buf bytes.Buffer
|
||||
gw := gzip.NewWriter(&buf)
|
||||
tw := tar.NewWriter(gw)
|
||||
|
||||
hdr := &tar.Header{
|
||||
Name: "../evil.txt",
|
||||
Mode: 0755,
|
||||
Size: 4,
|
||||
}
|
||||
_ = tw.WriteHeader(hdr)
|
||||
_, _ = tw.Write([]byte("evil"))
|
||||
_ = tw.Close()
|
||||
_ = gw.Close()
|
||||
|
||||
destDir := t.TempDir()
|
||||
|
||||
err := extractTarGz(bytes.NewReader(buf.Bytes()), destDir)
|
||||
require.Error(t, err, "expected error for path traversal, got nil")
|
||||
})
|
||||
|
||||
t.Run("handles invalid gzip", func(t *testing.T) {
|
||||
destDir := t.TempDir()
|
||||
|
||||
err := extractTarGz(bytes.NewReader([]byte("not valid gzip")), destDir)
|
||||
require.Error(t, err, "expected error for invalid gzip, got nil")
|
||||
})
|
||||
}
|
||||
|
||||
func TestExtractZip(t *testing.T) {
|
||||
t.Run("extracts files correctly", func(t *testing.T) {
|
||||
zipDir := t.TempDir()
|
||||
zipPath := filepath.Join(zipDir, "archive.zip")
|
||||
content := []byte("hello world")
|
||||
archive := createZipBuffer(t, map[string][]byte{
|
||||
"copilot.exe": content,
|
||||
})
|
||||
require.NoError(t, os.WriteFile(zipPath, archive, 0x755))
|
||||
|
||||
destDir := t.TempDir()
|
||||
|
||||
err := extractZip(zipPath, destDir)
|
||||
require.NoError(t, err, "extractZip() error")
|
||||
|
||||
extracted, err := os.ReadFile(filepath.Join(destDir, "copilot.exe"))
|
||||
require.NoError(t, err, "failed to read extracted file")
|
||||
require.Equal(t, content, extracted, "extracted content mismatch")
|
||||
})
|
||||
|
||||
t.Run("extracts nested files", func(t *testing.T) {
|
||||
zipDir := t.TempDir()
|
||||
zipPath := filepath.Join(zipDir, "archive.zip")
|
||||
content := []byte("hello world")
|
||||
archive := createZipBuffer(t, map[string][]byte{
|
||||
"subdir/file.txt": content,
|
||||
})
|
||||
require.NoError(t, os.WriteFile(zipPath, archive, 0x755))
|
||||
|
||||
destDir := t.TempDir()
|
||||
|
||||
err := extractZip(zipPath, destDir)
|
||||
require.NoError(t, err, "extractZip() error")
|
||||
|
||||
extracted, err := os.ReadFile(filepath.Join(destDir, "subdir", "file.txt"))
|
||||
require.NoError(t, err, "failed to read extracted file")
|
||||
require.Equal(t, content, extracted, "extracted content mismatch")
|
||||
})
|
||||
|
||||
t.Run("rejects path traversal", func(t *testing.T) {
|
||||
zipDir := t.TempDir()
|
||||
zipPath := filepath.Join(zipDir, "archive.zip")
|
||||
|
||||
var buf bytes.Buffer
|
||||
zw := zip.NewWriter(&buf)
|
||||
|
||||
fh := &zip.FileHeader{
|
||||
Name: "../evil.txt",
|
||||
Method: zip.Store,
|
||||
}
|
||||
fw, _ := zw.CreateHeader(fh)
|
||||
_, _ = fw.Write([]byte("evil"))
|
||||
_ = zw.Close()
|
||||
|
||||
require.NoError(t, os.WriteFile(zipPath, buf.Bytes(), 0x755))
|
||||
destDir := t.TempDir()
|
||||
|
||||
err := extractZip(zipPath, destDir)
|
||||
require.Error(t, err, "expected error for path traversal, got nil")
|
||||
})
|
||||
}
|
||||
|
||||
func TestFetchExpectedChecksum(t *testing.T) {
|
||||
t.Run("parses checksums file correctly", func(t *testing.T) {
|
||||
reg := &httpmock.Registry{}
|
||||
checksums := "abc123def456 copilot-linux-x64.tar.gz\n789xyz copilot-darwin-arm64.tar.gz\n"
|
||||
reg.Register(
|
||||
httpmock.MatchAny,
|
||||
httpmock.StringResponse(checksums),
|
||||
)
|
||||
|
||||
client := &http.Client{Transport: reg}
|
||||
checksum, err := fetchExpectedChecksum(client, "https://example.com/checksums", "copilot-linux-x64.tar.gz")
|
||||
require.NoError(t, err, "unexpected error")
|
||||
require.Equal(t, "abc123def456", checksum, "checksum mismatch")
|
||||
})
|
||||
|
||||
t.Run("returns error for missing archive", func(t *testing.T) {
|
||||
reg := &httpmock.Registry{}
|
||||
checksums := "abc123 copilot-linux-x64.tar.gz\n"
|
||||
reg.Register(
|
||||
httpmock.MatchAny,
|
||||
httpmock.StringResponse(checksums),
|
||||
)
|
||||
|
||||
client := &http.Client{Transport: reg}
|
||||
_, err := fetchExpectedChecksum(client, "https://example.com/checksums", "copilot-win32-x64.zip")
|
||||
require.Error(t, err, "expected error for missing archive")
|
||||
require.Equal(t, "checksum not found for copilot-win32-x64.zip", err.Error(), "unexpected error")
|
||||
})
|
||||
|
||||
t.Run("handles single space separator", func(t *testing.T) {
|
||||
reg := &httpmock.Registry{}
|
||||
checksums := "abc123 copilot-darwin-x64.tar.gz\n"
|
||||
reg.Register(
|
||||
httpmock.MatchAny,
|
||||
httpmock.StringResponse(checksums),
|
||||
)
|
||||
|
||||
client := &http.Client{Transport: reg}
|
||||
checksum, err := fetchExpectedChecksum(client, "https://example.com/checksums", "copilot-darwin-x64.tar.gz")
|
||||
require.NoError(t, err, "unexpected error")
|
||||
require.Equal(t, "abc123", checksum, "checksum mismatch")
|
||||
})
|
||||
|
||||
t.Run("handles HTTP error", func(t *testing.T) {
|
||||
reg := &httpmock.Registry{}
|
||||
reg.Register(
|
||||
httpmock.MatchAny,
|
||||
httpmock.StatusStringResponse(http.StatusNotFound, "not found"),
|
||||
)
|
||||
|
||||
client := &http.Client{Transport: reg}
|
||||
_, err := fetchExpectedChecksum(client, "https://example.com/checksums", "copilot-linux-x64.tar.gz")
|
||||
require.Error(t, err, "expected error for HTTP 404")
|
||||
})
|
||||
}
|
||||
|
||||
func archString() string {
|
||||
arch := runtime.GOARCH
|
||||
if arch == "amd64" {
|
||||
return "x64"
|
||||
}
|
||||
return arch
|
||||
}
|
||||
|
||||
func TestDownloadCopilot(t *testing.T) {
|
||||
// Skip on unsupported architectures
|
||||
if runtime.GOARCH != "amd64" && runtime.GOARCH != "arm64" {
|
||||
t.Skip("skipping test on unsupported architecture")
|
||||
}
|
||||
|
||||
t.Run("downloads and extracts tar.gz with valid checksum", func(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("skipping tar.gz test on windows")
|
||||
}
|
||||
|
||||
ios, _, _, stderr := iostreams.Test()
|
||||
tmpDir := t.TempDir()
|
||||
installDir := filepath.Join(tmpDir, "copilot")
|
||||
localPath := filepath.Join(installDir, "copilot")
|
||||
|
||||
// Create mock archive with copilot binary
|
||||
binaryContent := []byte("#!/bin/sh\necho copilot")
|
||||
archive := createTarGzBuffer(t, map[string][]byte{
|
||||
"copilot": binaryContent,
|
||||
})
|
||||
|
||||
// Calculate checksum
|
||||
checksum := sha256.Sum256(archive)
|
||||
checksumHex := hex.EncodeToString(checksum[:])
|
||||
archiveName := fmt.Sprintf("copilot-%s-%s.tar.gz", runtime.GOOS, archString())
|
||||
checksumFile := fmt.Sprintf("%s %s\n", checksumHex, archiveName)
|
||||
|
||||
reg := &httpmock.Registry{}
|
||||
// Register checksum endpoint
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "github/copilot-cli/releases/latest/download/SHA256SUMS.txt"),
|
||||
httpmock.StringResponse(checksumFile),
|
||||
)
|
||||
// Register archive endpoint
|
||||
reg.Register(
|
||||
httpmock.REST("GET", fmt.Sprintf("github/copilot-cli/releases/latest/download/%s", archiveName)),
|
||||
httpmock.BinaryResponse(archive),
|
||||
)
|
||||
|
||||
httpClient := &http.Client{Transport: reg}
|
||||
|
||||
path, err := downloadCopilot(httpClient, ios, installDir, localPath)
|
||||
require.NoError(t, err, "downloadCopilot() error")
|
||||
require.Equal(t, localPath, path, "downloadCopilot() path mismatch")
|
||||
|
||||
// Verify binary was extracted
|
||||
extracted, err := os.ReadFile(localPath)
|
||||
require.NoError(t, err, "failed to read extracted binary")
|
||||
require.Equal(t, binaryContent, extracted, "extracted content mismatch")
|
||||
|
||||
// Verify output messages
|
||||
require.Contains(t, stderr.String(), "installed successfully", "expected success message in stderr")
|
||||
})
|
||||
|
||||
t.Run("fails with checksum mismatch", func(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("skipping tar.gz test on windows")
|
||||
}
|
||||
|
||||
ios, _, _, _ := iostreams.Test()
|
||||
tmpDir := t.TempDir()
|
||||
installDir := filepath.Join(tmpDir, "copilot")
|
||||
localPath := filepath.Join(installDir, "copilot")
|
||||
|
||||
binaryContent := []byte("#!/bin/sh\necho copilot")
|
||||
archive := createTarGzBuffer(t, map[string][]byte{
|
||||
"copilot": binaryContent,
|
||||
})
|
||||
|
||||
// Use wrong checksum
|
||||
archiveName := fmt.Sprintf("copilot-%s-%s.tar.gz", runtime.GOOS, archString())
|
||||
checksumFile := fmt.Sprintf("%s %s\n", "0000000000000000000000000000000000000000000000000000000000000000", archiveName)
|
||||
|
||||
reg := &httpmock.Registry{}
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "github/copilot-cli/releases/latest/download/SHA256SUMS.txt"),
|
||||
httpmock.StringResponse(checksumFile),
|
||||
)
|
||||
reg.Register(
|
||||
httpmock.REST("GET", fmt.Sprintf("github/copilot-cli/releases/latest/download/%s", archiveName)),
|
||||
httpmock.BinaryResponse(archive),
|
||||
)
|
||||
|
||||
httpClient := &http.Client{Transport: reg}
|
||||
|
||||
_, err := downloadCopilot(httpClient, ios, installDir, localPath)
|
||||
require.Error(t, err, "expected error for checksum mismatch, got nil")
|
||||
require.Contains(t, err.Error(), "checksum mismatch", "expected checksum mismatch error")
|
||||
})
|
||||
|
||||
t.Run("handles HTTP error on archive download", func(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("skipping tar.gz test on windows")
|
||||
}
|
||||
|
||||
ios, _, _, _ := iostreams.Test()
|
||||
tmpDir := t.TempDir()
|
||||
installDir := filepath.Join(tmpDir, "copilot")
|
||||
localPath := filepath.Join(installDir, "copilot")
|
||||
|
||||
archiveName := fmt.Sprintf("copilot-%s-%s.tar.gz", runtime.GOOS, archString())
|
||||
checksumFile := fmt.Sprintf("%s %s\n", "abc123", archiveName)
|
||||
|
||||
reg := &httpmock.Registry{}
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "github/copilot-cli/releases/latest/download/SHA256SUMS.txt"),
|
||||
httpmock.StringResponse(checksumFile),
|
||||
)
|
||||
reg.Register(
|
||||
httpmock.REST("GET", fmt.Sprintf("github/copilot-cli/releases/latest/download/%s", archiveName)),
|
||||
httpmock.StatusStringResponse(http.StatusNotFound, "not found"),
|
||||
)
|
||||
|
||||
httpClient := &http.Client{Transport: reg}
|
||||
|
||||
_, err := downloadCopilot(httpClient, ios, installDir, localPath)
|
||||
require.Error(t, err, "expected error for HTTP 404, got nil")
|
||||
require.Contains(t, err.Error(), "download failed", "expected error to contain 'download failed'")
|
||||
})
|
||||
|
||||
t.Run("handles missing binary after extraction", func(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("skipping tar.gz test on windows")
|
||||
}
|
||||
|
||||
ios, _, _, _ := iostreams.Test()
|
||||
tmpDir := t.TempDir()
|
||||
installDir := filepath.Join(tmpDir, "copilot")
|
||||
localPath := filepath.Join(installDir, "copilot")
|
||||
|
||||
// Create archive without the expected binary name
|
||||
archive := createTarGzBuffer(t, map[string][]byte{
|
||||
"wrong-name": []byte("content"),
|
||||
})
|
||||
|
||||
checksum := sha256.Sum256(archive)
|
||||
checksumHex := hex.EncodeToString(checksum[:])
|
||||
archiveName := fmt.Sprintf("copilot-%s-%s.tar.gz", runtime.GOOS, archString())
|
||||
checksumFile := fmt.Sprintf("%s %s\n", checksumHex, archiveName)
|
||||
|
||||
reg := &httpmock.Registry{}
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "github/copilot-cli/releases/latest/download/SHA256SUMS.txt"),
|
||||
httpmock.StringResponse(checksumFile),
|
||||
)
|
||||
reg.Register(
|
||||
httpmock.REST("GET", fmt.Sprintf("github/copilot-cli/releases/latest/download/%s", archiveName)),
|
||||
httpmock.BinaryResponse(archive),
|
||||
)
|
||||
|
||||
httpClient := &http.Client{Transport: reg}
|
||||
|
||||
_, err := downloadCopilot(httpClient, ios, installDir, localPath)
|
||||
assert.ErrorContains(t, err, "copilot binary unavailable")
|
||||
})
|
||||
|
||||
t.Run("downloads and extracts zip on windows", func(t *testing.T) {
|
||||
if runtime.GOOS != "windows" {
|
||||
t.Skip("skipping zip test on non-windows")
|
||||
}
|
||||
|
||||
ios, _, _, _ := iostreams.Test()
|
||||
tmpDir := t.TempDir()
|
||||
installDir := filepath.Join(tmpDir, "copilot")
|
||||
localPath := filepath.Join(installDir, "copilot.exe")
|
||||
|
||||
binaryContent := []byte("MZ fake exe content")
|
||||
archive := createZipBuffer(t, map[string][]byte{
|
||||
"copilot.exe": binaryContent,
|
||||
})
|
||||
|
||||
checksum := sha256.Sum256(archive)
|
||||
checksumHex := hex.EncodeToString(checksum[:])
|
||||
archiveName := fmt.Sprintf("copilot-%s-%s.zip", "win32", archString())
|
||||
checksumFile := fmt.Sprintf("%s %s\n", checksumHex, archiveName)
|
||||
|
||||
reg := &httpmock.Registry{}
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "github/copilot-cli/releases/latest/download/SHA256SUMS.txt"),
|
||||
httpmock.StringResponse(checksumFile),
|
||||
)
|
||||
reg.Register(
|
||||
httpmock.REST("GET", fmt.Sprintf("github/copilot-cli/releases/latest/download/%s", archiveName)),
|
||||
httpmock.BinaryResponse(archive),
|
||||
)
|
||||
|
||||
httpClient := &http.Client{Transport: reg}
|
||||
|
||||
path, err := downloadCopilot(httpClient, ios, installDir, localPath)
|
||||
require.NoError(t, err, "downloadCopilot() error")
|
||||
require.Equal(t, localPath, path, "downloadCopilot() path mismatch")
|
||||
})
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: cli/gh-extension-precompile@v2
|
||||
with:
|
||||
generate_attestations: true
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ jobs:
|
|||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: cli/gh-extension-precompile@v2
|
||||
with:
|
||||
build_script_override: "script/build.sh"
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ func NewCmdSetDefault(f *cmdutil.Factory, runF func(*SetDefaultOptions) error) *
|
|||
# Set a repository explicitly
|
||||
$ gh repo set-default owner/repo
|
||||
|
||||
# Set a repository using a git remote name
|
||||
$ gh repo set-default origin
|
||||
|
||||
# View the current default repository
|
||||
$ gh repo set-default --view
|
||||
|
||||
|
|
@ -79,11 +82,26 @@ func NewCmdSetDefault(f *cmdutil.Factory, runF func(*SetDefaultOptions) error) *
|
|||
`),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if isLocal, err := opts.GitClient.IsLocalGitRepo(cmd.Context()); err != nil {
|
||||
return err
|
||||
} else if !isLocal {
|
||||
return errors.New("must be run from inside a git repository")
|
||||
}
|
||||
|
||||
if len(args) > 0 {
|
||||
var err error
|
||||
opts.Repo, err = ghrepo.FromFullName(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
remotes, remoteErr := opts.Remotes()
|
||||
if remoteErr != nil {
|
||||
return remoteErr
|
||||
}
|
||||
|
||||
remote, findErr := remotes.FindByName(args[0])
|
||||
if findErr != nil {
|
||||
return fmt.Errorf("given arg is not a valid repo or git remote: %w", err)
|
||||
}
|
||||
opts.Repo = remote.Repo
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,12 +109,6 @@ func NewCmdSetDefault(f *cmdutil.Factory, runF func(*SetDefaultOptions) error) *
|
|||
return cmdutil.FlagErrorf("repository required when not running interactively")
|
||||
}
|
||||
|
||||
if isLocal, err := opts.GitClient.IsLocalGitRepo(cmd.Context()); err != nil {
|
||||
return err
|
||||
} else if !isLocal {
|
||||
return errors.New("must be run from inside a git repository")
|
||||
}
|
||||
|
||||
if runF != nil {
|
||||
return runF(opts)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ func TestNewCmdSetDefault(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
gitStubs func(*run.CommandStubber)
|
||||
remotes func() (context.Remotes, error)
|
||||
input string
|
||||
output SetDefaultOptions
|
||||
wantErr bool
|
||||
|
|
@ -43,11 +44,13 @@ func TestNewCmdSetDefault(t *testing.T) {
|
|||
output: SetDefaultOptions{Repo: ghrepo.New("cli", "cli")},
|
||||
},
|
||||
{
|
||||
name: "invalid repo argument",
|
||||
gitStubs: func(cs *run.CommandStubber) {},
|
||||
input: "some_invalid_format",
|
||||
wantErr: true,
|
||||
errMsg: `expected the "[HOST/]OWNER/REPO" format, got "some_invalid_format"`,
|
||||
name: "invalid repo argument",
|
||||
gitStubs: func(cs *run.CommandStubber) {
|
||||
cs.Register(`git rev-parse --git-dir`, 0, ".git")
|
||||
},
|
||||
input: "some_invalid_format",
|
||||
wantErr: true,
|
||||
errMsg: `given arg is not a valid repo or git remote: expected the "[HOST/]OWNER/REPO" format, got "some_invalid_format"`,
|
||||
},
|
||||
{
|
||||
name: "view flag",
|
||||
|
|
@ -74,6 +77,38 @@ func TestNewCmdSetDefault(t *testing.T) {
|
|||
wantErr: true,
|
||||
errMsg: "must be run from inside a git repository",
|
||||
},
|
||||
{
|
||||
name: "remote name argument",
|
||||
gitStubs: func(cs *run.CommandStubber) {
|
||||
cs.Register(`git rev-parse --git-dir`, 0, ".git")
|
||||
},
|
||||
remotes: func() (context.Remotes, error) {
|
||||
return context.Remotes{
|
||||
{
|
||||
Remote: &git.Remote{Name: "origin"},
|
||||
Repo: ghrepo.New("OWNER", "REPO"),
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
input: "origin",
|
||||
output: SetDefaultOptions{Repo: ghrepo.New("OWNER", "REPO")},
|
||||
},
|
||||
{
|
||||
name: "repo argument despite remote name matching owner/repo",
|
||||
gitStubs: func(cs *run.CommandStubber) {
|
||||
cs.Register(`git rev-parse --git-dir`, 0, ".git")
|
||||
},
|
||||
remotes: func() (context.Remotes, error) {
|
||||
return context.Remotes{
|
||||
{
|
||||
Remote: &git.Remote{Name: "OWNER/REPO"},
|
||||
Repo: ghrepo.New("OTHER", "REPO"),
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
input: "OWNER/REPO",
|
||||
output: SetDefaultOptions{Repo: ghrepo.New("OWNER", "REPO")},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
@ -81,9 +116,17 @@ func TestNewCmdSetDefault(t *testing.T) {
|
|||
io.SetStdoutTTY(true)
|
||||
io.SetStdinTTY(true)
|
||||
io.SetStderrTTY(true)
|
||||
remotesFunc := tt.remotes
|
||||
if remotesFunc == nil {
|
||||
remotesFunc = func() (context.Remotes, error) {
|
||||
return context.Remotes{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
f := &cmdutil.Factory{
|
||||
IOStreams: io,
|
||||
GitClient: &git.Client{GitPath: "/fake/path/to/git"},
|
||||
Remotes: remotesFunc,
|
||||
}
|
||||
|
||||
var gotOpts *SetDefaultOptions
|
||||
|
|
|
|||
97
pkg/cmd/root/extension_registration_test.go
Normal file
97
pkg/cmd/root/extension_registration_test.go
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
package root
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cli/cli/v2/internal/browser"
|
||||
"github.com/cli/cli/v2/internal/config"
|
||||
"github.com/cli/cli/v2/internal/gh"
|
||||
"github.com/cli/cli/v2/pkg/cmdutil"
|
||||
"github.com/cli/cli/v2/pkg/extensions"
|
||||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewCmdRoot_ExtensionRegistration(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
extensions []string
|
||||
wantRegistered []string
|
||||
wantSkipped []string
|
||||
}{
|
||||
{
|
||||
name: "extension conflicts with core command 'copilot'",
|
||||
extensions: []string{"copilot"},
|
||||
wantSkipped: []string{"copilot"},
|
||||
wantRegistered: []string{},
|
||||
},
|
||||
{
|
||||
name: "extension does not conflict with any core command",
|
||||
extensions: []string{"my-custom-extension"},
|
||||
wantSkipped: []string{},
|
||||
wantRegistered: []string{"my-custom-extension"},
|
||||
},
|
||||
{
|
||||
name: "extension that conflicts with a core command's alias",
|
||||
extensions: []string{"agent"},
|
||||
wantSkipped: []string{"agent"},
|
||||
wantRegistered: []string{},
|
||||
},
|
||||
{
|
||||
name: "multiple extensions with some conflicts",
|
||||
extensions: []string{"pr", "custom-ext", "issue", "another-ext"},
|
||||
wantSkipped: []string{"pr", "issue"},
|
||||
wantRegistered: []string{"custom-ext", "another-ext"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ios, _, _, _ := iostreams.Test()
|
||||
|
||||
var extMocks []extensions.Extension
|
||||
for _, extName := range tt.extensions {
|
||||
extMocks = append(extMocks, &extensions.ExtensionMock{
|
||||
NameFunc: func() string {
|
||||
return extName
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
em := &extensions.ExtensionManagerMock{
|
||||
ListFunc: func() []extensions.Extension {
|
||||
return extMocks
|
||||
},
|
||||
}
|
||||
|
||||
f := &cmdutil.Factory{
|
||||
IOStreams: ios,
|
||||
Config: func() (gh.Config, error) {
|
||||
return config.NewBlankConfig(), nil
|
||||
},
|
||||
Browser: &browser.Stub{},
|
||||
ExtensionManager: em,
|
||||
}
|
||||
|
||||
cmd, err := NewCmdRoot(f, "", "")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify skipped extensions (should find core command registered, not extension)
|
||||
for _, extName := range tt.wantSkipped {
|
||||
foundCmd, _, findErr := cmd.Find([]string{extName})
|
||||
assert.NoError(t, findErr, "command %q should be found", extName)
|
||||
assert.NotNil(t, foundCmd, "command %q should exist", extName)
|
||||
assert.NotEqual(t, "extension", foundCmd.GroupID, "command %q should be core command, not extension", extName)
|
||||
}
|
||||
|
||||
// Verify registered extensions (should find extension command registered)
|
||||
for _, extName := range tt.wantRegistered {
|
||||
foundCmd, _, findErr := cmd.Find([]string{extName})
|
||||
assert.NoError(t, findErr, "extension %q should be found", extName)
|
||||
assert.NotNil(t, foundCmd, "extension %q should exist", extName)
|
||||
assert.Equal(t, "extension", foundCmd.GroupID, "command %q should be extension command", extName)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ import (
|
|||
codespaceCmd "github.com/cli/cli/v2/pkg/cmd/codespace"
|
||||
completionCmd "github.com/cli/cli/v2/pkg/cmd/completion"
|
||||
configCmd "github.com/cli/cli/v2/pkg/cmd/config"
|
||||
copilotCmd "github.com/cli/cli/v2/pkg/cmd/copilot"
|
||||
extensionCmd "github.com/cli/cli/v2/pkg/cmd/extension"
|
||||
"github.com/cli/cli/v2/pkg/cmd/factory"
|
||||
gistCmd "github.com/cli/cli/v2/pkg/cmd/gist"
|
||||
|
|
@ -131,7 +132,6 @@ func NewCmdRoot(f *cmdutil.Factory, version, buildDate string) (*cobra.Command,
|
|||
cmd.AddCommand(authCmd.NewCmdAuth(f))
|
||||
cmd.AddCommand(attestationCmd.NewCmdAttestation(f))
|
||||
cmd.AddCommand(configCmd.NewCmdConfig(f))
|
||||
cmd.AddCommand(creditsCmd.NewCmdCredits(f, nil))
|
||||
cmd.AddCommand(gistCmd.NewCmdGist(f))
|
||||
cmd.AddCommand(gpgKeyCmd.NewCmdGPGKey(f))
|
||||
cmd.AddCommand(completionCmd.NewCmdCompletion(f.IOStreams))
|
||||
|
|
@ -140,11 +140,15 @@ func NewCmdRoot(f *cmdutil.Factory, version, buildDate string) (*cobra.Command,
|
|||
cmd.AddCommand(secretCmd.NewCmdSecret(f))
|
||||
cmd.AddCommand(variableCmd.NewCmdVariable(f))
|
||||
cmd.AddCommand(sshKeyCmd.NewCmdSSHKey(f))
|
||||
cmd.AddCommand(statusCmd.NewCmdStatus(f, nil))
|
||||
cmd.AddCommand(codespaceCmd.NewCmdCodespace(f))
|
||||
cmd.AddCommand(projectCmd.NewCmdProject(f))
|
||||
cmd.AddCommand(previewCmd.NewCmdPreview(f))
|
||||
|
||||
// Root commands with standalone functionality and no subcommands
|
||||
cmd.AddCommand(copilotCmd.NewCmdCopilot(f, nil))
|
||||
cmd.AddCommand(statusCmd.NewCmdStatus(f, nil))
|
||||
cmd.AddCommand(creditsCmd.NewCmdCredits(f, nil))
|
||||
|
||||
// below here at the commands that require the "intelligent" BaseRepo resolver
|
||||
repoResolvingCmdFactory := *f
|
||||
repoResolvingCmdFactory.BaseRepo = factory.SmartBaseRepoFunc(f)
|
||||
|
|
@ -179,6 +183,13 @@ func NewCmdRoot(f *cmdutil.Factory, version, buildDate string) (*cobra.Command,
|
|||
em := f.ExtensionManager
|
||||
for _, e := range em.List() {
|
||||
extensionCmd := NewCmdExtension(io, em, e, nil)
|
||||
// Don't register an extension command if it would
|
||||
// conflict with a core command.
|
||||
_, _, err := cmd.Find([]string{extensionCmd.Name()})
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
cmd.AddCommand(extensionCmd)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/cli/cli/v2/api"
|
||||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
"github.com/cli/cli/v2/internal/safepaths"
|
||||
ghzip "github.com/cli/cli/v2/internal/zip"
|
||||
"github.com/cli/cli/v2/pkg/cmd/run/shared"
|
||||
)
|
||||
|
||||
|
|
@ -62,7 +63,7 @@ func downloadArtifact(httpClient *http.Client, url string, destDir safepaths.Abs
|
|||
if err != nil {
|
||||
return fmt.Errorf("error extracting zip archive: %w", err)
|
||||
}
|
||||
if err := extractZip(zipfile, destDir); err != nil {
|
||||
if err := ghzip.ExtractZip(zipfile, destDir); err != nil {
|
||||
return fmt.Errorf("error extracting zip archive: %w", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Manage go-licenses version externally for CI
|
||||
if [ "$CI" != "true" ]; then
|
||||
go install github.com/google/go-licenses@latest
|
||||
go install github.com/google/go-licenses/v2@latest
|
||||
fi
|
||||
|
||||
# Verify go-licenses is available
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Manage go-licenses version externally for CI
|
||||
if [ "$CI" != "true" ]; then
|
||||
go install github.com/google/go-licenses@latest
|
||||
go install github.com/google/go-licenses/v2@latest
|
||||
fi
|
||||
|
||||
# Setup temporary directory for generated license reports
|
||||
|
|
|
|||
|
|
@ -8,23 +8,9 @@ Some packages may only be included on certain architectures or operating systems
|
|||
|
||||
|
||||
- [al.essio.dev/pkg/shellescape](https://pkg.go.dev/al.essio.dev/pkg/shellescape) ([MIT](https://github.com/alessio/shellescape/blob/v1.6.0/LICENSE))
|
||||
- [cel.dev/expr](https://pkg.go.dev/cel.dev/expr) ([Apache-2.0](https://github.com/google/cel-spec/blob/v0.24.0/LICENSE))
|
||||
- [cloud.google.com/go](https://pkg.go.dev/cloud.google.com/go) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/v0.121.6/LICENSE))
|
||||
- [cloud.google.com/go/auth](https://pkg.go.dev/cloud.google.com/go/auth) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/auth/v0.16.5/auth/LICENSE))
|
||||
- [cloud.google.com/go/auth/oauth2adapt](https://pkg.go.dev/cloud.google.com/go/auth/oauth2adapt) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/auth/oauth2adapt/v0.2.8/auth/oauth2adapt/LICENSE))
|
||||
- [cloud.google.com/go/compute/metadata](https://pkg.go.dev/cloud.google.com/go/compute/metadata) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/compute/metadata/v0.9.0/compute/metadata/LICENSE))
|
||||
- [cloud.google.com/go/iam](https://pkg.go.dev/cloud.google.com/go/iam) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/iam/v1.5.2/iam/LICENSE))
|
||||
- [cloud.google.com/go/longrunning](https://pkg.go.dev/cloud.google.com/go/longrunning) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/longrunning/v0.6.7/longrunning/LICENSE))
|
||||
- [cloud.google.com/go/monitoring](https://pkg.go.dev/cloud.google.com/go/monitoring) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/monitoring/v1.24.2/monitoring/LICENSE))
|
||||
- [cloud.google.com/go/spanner](https://pkg.go.dev/cloud.google.com/go/spanner) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/spanner/v1.84.1/spanner/LICENSE))
|
||||
- [cloud.google.com/go/storage](https://pkg.go.dev/cloud.google.com/go/storage) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/storage/v1.56.1/storage/LICENSE))
|
||||
- [dario.cat/mergo](https://pkg.go.dev/dario.cat/mergo) ([BSD-3-Clause](https://github.com/imdario/mergo/blob/v1.0.2/LICENSE))
|
||||
- [github.com/AlecAivazis/survey/v2](https://pkg.go.dev/github.com/AlecAivazis/survey/v2) ([MIT](https://github.com/AlecAivazis/survey/blob/v2.3.7/LICENSE))
|
||||
- [github.com/AlecAivazis/survey/v2/terminal](https://pkg.go.dev/github.com/AlecAivazis/survey/v2/terminal) ([MIT](https://github.com/AlecAivazis/survey/blob/v2.3.7/terminal/LICENSE.txt))
|
||||
- [github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp](https://pkg.go.dev/github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp) ([Apache-2.0](https://github.com/GoogleCloudPlatform/grpc-gcp-go/blob/grpcgcp/v1.5.3/grpcgcp/LICENSE))
|
||||
- [github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp](https://pkg.go.dev/github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp) ([Apache-2.0](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/detectors/gcp/v1.30.0/detectors/gcp/LICENSE))
|
||||
- [github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric](https://pkg.go.dev/github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric) ([Apache-2.0](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/exporter/metric/v0.53.0/exporter/metric/LICENSE))
|
||||
- [github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping](https://pkg.go.dev/github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping) ([Apache-2.0](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/internal/resourcemapping/v0.53.0/internal/resourcemapping/LICENSE))
|
||||
- [github.com/MakeNowJust/heredoc](https://pkg.go.dev/github.com/MakeNowJust/heredoc) ([MIT](https://github.com/MakeNowJust/heredoc/blob/v1.0.0/LICENSE))
|
||||
- [github.com/Masterminds/goutils](https://pkg.go.dev/github.com/Masterminds/goutils) ([Apache-2.0](https://github.com/Masterminds/goutils/blob/v1.1.1/LICENSE.txt))
|
||||
- [github.com/Masterminds/semver/v3](https://pkg.go.dev/github.com/Masterminds/semver/v3) ([MIT](https://github.com/Masterminds/semver/blob/v3.4.0/LICENSE.txt))
|
||||
|
|
@ -39,14 +25,13 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/catppuccin/go](https://pkg.go.dev/github.com/catppuccin/go) ([MIT](https://github.com/catppuccin/go/blob/v0.3.0/LICENSE))
|
||||
- [github.com/cenkalti/backoff/v4](https://pkg.go.dev/github.com/cenkalti/backoff/v4) ([MIT](https://github.com/cenkalti/backoff/blob/v4.3.0/LICENSE))
|
||||
- [github.com/cenkalti/backoff/v5](https://pkg.go.dev/github.com/cenkalti/backoff/v5) ([MIT](https://github.com/cenkalti/backoff/blob/v5.0.3/LICENSE))
|
||||
- [github.com/cespare/xxhash/v2](https://pkg.go.dev/github.com/cespare/xxhash/v2) ([MIT](https://github.com/cespare/xxhash/blob/v2.3.0/LICENSE.txt))
|
||||
- [github.com/charmbracelet/bubbles](https://pkg.go.dev/github.com/charmbracelet/bubbles) ([MIT](https://github.com/charmbracelet/bubbles/blob/23b8fd6302d7/LICENSE))
|
||||
- [github.com/charmbracelet/bubbletea](https://pkg.go.dev/github.com/charmbracelet/bubbletea) ([MIT](https://github.com/charmbracelet/bubbletea/blob/v1.3.6/LICENSE))
|
||||
- [github.com/charmbracelet/bubbletea](https://pkg.go.dev/github.com/charmbracelet/bubbletea) ([MIT](https://github.com/charmbracelet/bubbletea/blob/v1.3.10/LICENSE))
|
||||
- [github.com/charmbracelet/colorprofile](https://pkg.go.dev/github.com/charmbracelet/colorprofile) ([MIT](https://github.com/charmbracelet/colorprofile/blob/v0.3.1/LICENSE))
|
||||
- [github.com/charmbracelet/glamour](https://pkg.go.dev/github.com/charmbracelet/glamour) ([MIT](https://github.com/charmbracelet/glamour/blob/v0.10.0/LICENSE))
|
||||
- [github.com/charmbracelet/huh](https://pkg.go.dev/github.com/charmbracelet/huh) ([MIT](https://github.com/charmbracelet/huh/blob/v0.8.0/LICENSE))
|
||||
- [github.com/charmbracelet/lipgloss](https://pkg.go.dev/github.com/charmbracelet/lipgloss) ([MIT](https://github.com/charmbracelet/lipgloss/blob/76690c660834/LICENSE))
|
||||
- [github.com/charmbracelet/x/ansi](https://pkg.go.dev/github.com/charmbracelet/x/ansi) ([MIT](https://github.com/charmbracelet/x/blob/ansi/v0.9.3/ansi/LICENSE))
|
||||
- [github.com/charmbracelet/x/ansi](https://pkg.go.dev/github.com/charmbracelet/x/ansi) ([MIT](https://github.com/charmbracelet/x/blob/ansi/v0.10.2/ansi/LICENSE))
|
||||
- [github.com/charmbracelet/x/cellbuf](https://pkg.go.dev/github.com/charmbracelet/x/cellbuf) ([MIT](https://github.com/charmbracelet/x/blob/cellbuf/v0.0.13/cellbuf/LICENSE))
|
||||
- [github.com/charmbracelet/x/exp/slice](https://pkg.go.dev/github.com/charmbracelet/x/exp/slice) ([MIT](https://github.com/charmbracelet/x/blob/821143405392/exp/slice/LICENSE))
|
||||
- [github.com/charmbracelet/x/exp/strings](https://pkg.go.dev/github.com/charmbracelet/x/exp/strings) ([MIT](https://github.com/charmbracelet/x/blob/821143405392/exp/strings/LICENSE))
|
||||
|
|
@ -56,10 +41,9 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/cli/oauth](https://pkg.go.dev/github.com/cli/oauth) ([MIT](https://github.com/cli/oauth/blob/v1.2.1/LICENSE))
|
||||
- [github.com/cli/safeexec](https://pkg.go.dev/github.com/cli/safeexec) ([BSD-2-Clause](https://github.com/cli/safeexec/blob/v1.0.1/LICENSE))
|
||||
- [github.com/cli/shurcooL-graphql](https://pkg.go.dev/github.com/cli/shurcooL-graphql) ([MIT](https://github.com/cli/shurcooL-graphql/blob/v0.0.4/LICENSE))
|
||||
- [github.com/cncf/xds/go](https://pkg.go.dev/github.com/cncf/xds/go) ([Apache-2.0](https://github.com/cncf/xds/blob/0feb69152e9f/go/LICENSE))
|
||||
- [github.com/containerd/stargz-snapshotter/estargz](https://pkg.go.dev/github.com/containerd/stargz-snapshotter/estargz) ([Apache-2.0](https://github.com/containerd/stargz-snapshotter/blob/estargz/v0.18.1/estargz/LICENSE))
|
||||
- [github.com/cpuguy83/go-md2man/v2/md2man](https://pkg.go.dev/github.com/cpuguy83/go-md2man/v2/md2man) ([MIT](https://github.com/cpuguy83/go-md2man/blob/v2.0.7/LICENSE.md))
|
||||
- [github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer](https://pkg.go.dev/github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer) ([Apache-2.0](https://github.com/cyberphone/json-canonicalization/blob/19d51d7fe467/LICENSE))
|
||||
- [github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer](https://pkg.go.dev/github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer) ([Unknown](Unknown))
|
||||
- [github.com/davecgh/go-spew/spew](https://pkg.go.dev/github.com/davecgh/go-spew/spew) ([ISC](https://github.com/davecgh/go-spew/blob/d8f796af33cc/LICENSE))
|
||||
- [github.com/digitorus/pkcs7](https://pkg.go.dev/github.com/digitorus/pkcs7) ([MIT](https://github.com/digitorus/pkcs7/blob/3a137a874352/LICENSE))
|
||||
- [github.com/digitorus/timestamp](https://pkg.go.dev/github.com/digitorus/timestamp) ([BSD-2-Clause](https://github.com/digitorus/timestamp/blob/c45532741eea/LICENSE))
|
||||
|
|
@ -69,84 +53,71 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/docker/distribution/registry/client/auth/challenge](https://pkg.go.dev/github.com/docker/distribution/registry/client/auth/challenge) ([Apache-2.0](https://github.com/docker/distribution/blob/v2.8.3/LICENSE))
|
||||
- [github.com/docker/docker-credential-helpers](https://pkg.go.dev/github.com/docker/docker-credential-helpers) ([MIT](https://github.com/docker/docker-credential-helpers/blob/v0.9.3/LICENSE))
|
||||
- [github.com/dustin/go-humanize](https://pkg.go.dev/github.com/dustin/go-humanize) ([MIT](https://github.com/dustin/go-humanize/blob/v1.0.1/LICENSE))
|
||||
- [github.com/envoyproxy/go-control-plane/envoy](https://pkg.go.dev/github.com/envoyproxy/go-control-plane/envoy) ([Apache-2.0](https://github.com/envoyproxy/go-control-plane/blob/envoy/v1.35.0/envoy/LICENSE))
|
||||
- [github.com/envoyproxy/protoc-gen-validate/validate](https://pkg.go.dev/github.com/envoyproxy/protoc-gen-validate/validate) ([Apache-2.0](https://github.com/envoyproxy/protoc-gen-validate/blob/v1.2.1/LICENSE))
|
||||
- [github.com/fatih/color](https://pkg.go.dev/github.com/fatih/color) ([MIT](https://github.com/fatih/color/blob/v1.18.0/LICENSE.md))
|
||||
- [github.com/felixge/httpsnoop](https://pkg.go.dev/github.com/felixge/httpsnoop) ([MIT](https://github.com/felixge/httpsnoop/blob/v1.0.4/LICENSE.txt))
|
||||
- [github.com/fsnotify/fsnotify](https://pkg.go.dev/github.com/fsnotify/fsnotify) ([BSD-3-Clause](https://github.com/fsnotify/fsnotify/blob/v1.9.0/LICENSE))
|
||||
- [github.com/gabriel-vasile/mimetype](https://pkg.go.dev/github.com/gabriel-vasile/mimetype) ([MIT](https://github.com/gabriel-vasile/mimetype/blob/v1.4.11/LICENSE))
|
||||
- [github.com/gdamore/encoding](https://pkg.go.dev/github.com/gdamore/encoding) ([Apache-2.0](https://github.com/gdamore/encoding/blob/v1.0.1/LICENSE))
|
||||
- [github.com/gdamore/tcell/v2](https://pkg.go.dev/github.com/gdamore/tcell/v2) ([Apache-2.0](https://github.com/gdamore/tcell/blob/v2.13.4/LICENSE))
|
||||
- [github.com/go-chi/chi/v5](https://pkg.go.dev/github.com/go-chi/chi/v5) ([MIT](https://github.com/go-chi/chi/blob/v5.2.3/LICENSE))
|
||||
- [github.com/go-jose/go-jose/v4](https://pkg.go.dev/github.com/go-jose/go-jose/v4) ([Apache-2.0](https://github.com/go-jose/go-jose/blob/v4.1.3/LICENSE))
|
||||
- [github.com/go-jose/go-jose/v4/json](https://pkg.go.dev/github.com/go-jose/go-jose/v4/json) ([BSD-3-Clause](https://github.com/go-jose/go-jose/blob/v4.1.3/json/LICENSE))
|
||||
- [github.com/go-logr/logr](https://pkg.go.dev/github.com/go-logr/logr) ([Apache-2.0](https://github.com/go-logr/logr/blob/v1.4.3/LICENSE))
|
||||
- [github.com/go-logr/stdr](https://pkg.go.dev/github.com/go-logr/stdr) ([Apache-2.0](https://github.com/go-logr/stdr/blob/v1.2.2/LICENSE))
|
||||
- [github.com/go-openapi/analysis](https://pkg.go.dev/github.com/go-openapi/analysis) ([Apache-2.0](https://github.com/go-openapi/analysis/blob/v0.23.0/LICENSE))
|
||||
- [github.com/go-openapi/errors](https://pkg.go.dev/github.com/go-openapi/errors) ([Apache-2.0](https://github.com/go-openapi/errors/blob/v0.22.2/LICENSE))
|
||||
- [github.com/go-openapi/jsonpointer](https://pkg.go.dev/github.com/go-openapi/jsonpointer) ([Apache-2.0](https://github.com/go-openapi/jsonpointer/blob/v0.21.1/LICENSE))
|
||||
- [github.com/go-openapi/jsonreference](https://pkg.go.dev/github.com/go-openapi/jsonreference) ([Apache-2.0](https://github.com/go-openapi/jsonreference/blob/v0.21.0/LICENSE))
|
||||
- [github.com/go-openapi/loads](https://pkg.go.dev/github.com/go-openapi/loads) ([Apache-2.0](https://github.com/go-openapi/loads/blob/v0.22.0/LICENSE))
|
||||
- [github.com/go-openapi/runtime](https://pkg.go.dev/github.com/go-openapi/runtime) ([Apache-2.0](https://github.com/go-openapi/runtime/blob/v0.28.0/LICENSE))
|
||||
- [github.com/go-openapi/runtime/middleware/denco](https://pkg.go.dev/github.com/go-openapi/runtime/middleware/denco) ([MIT](https://github.com/go-openapi/runtime/blob/v0.28.0/middleware/denco/LICENSE))
|
||||
- [github.com/go-openapi/spec](https://pkg.go.dev/github.com/go-openapi/spec) ([Apache-2.0](https://github.com/go-openapi/spec/blob/v0.21.0/LICENSE))
|
||||
- [github.com/go-openapi/strfmt](https://pkg.go.dev/github.com/go-openapi/strfmt) ([Apache-2.0](https://github.com/go-openapi/strfmt/blob/v0.23.0/LICENSE))
|
||||
- [github.com/go-openapi/swag](https://pkg.go.dev/github.com/go-openapi/swag) ([Apache-2.0](https://github.com/go-openapi/swag/blob/v0.24.1/LICENSE))
|
||||
- [github.com/go-openapi/swag/cmdutils](https://pkg.go.dev/github.com/go-openapi/swag/cmdutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/cmdutils/v0.24.0/cmdutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/conv](https://pkg.go.dev/github.com/go-openapi/swag/conv) ([Apache-2.0](https://github.com/go-openapi/swag/blob/conv/v0.24.0/conv/LICENSE))
|
||||
- [github.com/go-openapi/swag/fileutils](https://pkg.go.dev/github.com/go-openapi/swag/fileutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/fileutils/v0.24.0/fileutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonname](https://pkg.go.dev/github.com/go-openapi/swag/jsonname) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonname/v0.24.0/jsonname/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonutils](https://pkg.go.dev/github.com/go-openapi/swag/jsonutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonutils/v0.24.0/jsonutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/loading](https://pkg.go.dev/github.com/go-openapi/swag/loading) ([Apache-2.0](https://github.com/go-openapi/swag/blob/loading/v0.24.0/loading/LICENSE))
|
||||
- [github.com/go-openapi/swag/mangling](https://pkg.go.dev/github.com/go-openapi/swag/mangling) ([Apache-2.0](https://github.com/go-openapi/swag/blob/mangling/v0.24.0/mangling/LICENSE))
|
||||
- [github.com/go-openapi/swag/netutils](https://pkg.go.dev/github.com/go-openapi/swag/netutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/netutils/v0.24.0/netutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/stringutils](https://pkg.go.dev/github.com/go-openapi/swag/stringutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/stringutils/v0.24.0/stringutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/typeutils](https://pkg.go.dev/github.com/go-openapi/swag/typeutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/typeutils/v0.24.0/typeutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/yamlutils](https://pkg.go.dev/github.com/go-openapi/swag/yamlutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/yamlutils/v0.24.0/yamlutils/LICENSE))
|
||||
- [github.com/go-openapi/validate](https://pkg.go.dev/github.com/go-openapi/validate) ([Apache-2.0](https://github.com/go-openapi/validate/blob/v0.24.0/LICENSE))
|
||||
- [github.com/go-openapi/analysis](https://pkg.go.dev/github.com/go-openapi/analysis) ([Apache-2.0](https://github.com/go-openapi/analysis/blob/v0.24.1/LICENSE))
|
||||
- [github.com/go-openapi/errors](https://pkg.go.dev/github.com/go-openapi/errors) ([Apache-2.0](https://github.com/go-openapi/errors/blob/v0.22.4/LICENSE))
|
||||
- [github.com/go-openapi/jsonpointer](https://pkg.go.dev/github.com/go-openapi/jsonpointer) ([Apache-2.0](https://github.com/go-openapi/jsonpointer/blob/v0.22.1/LICENSE))
|
||||
- [github.com/go-openapi/jsonreference](https://pkg.go.dev/github.com/go-openapi/jsonreference) ([Apache-2.0](https://github.com/go-openapi/jsonreference/blob/v0.21.3/LICENSE))
|
||||
- [github.com/go-openapi/loads](https://pkg.go.dev/github.com/go-openapi/loads) ([Apache-2.0](https://github.com/go-openapi/loads/blob/v0.23.2/LICENSE))
|
||||
- [github.com/go-openapi/runtime](https://pkg.go.dev/github.com/go-openapi/runtime) ([Apache-2.0](https://github.com/go-openapi/runtime/blob/v0.29.2/LICENSE))
|
||||
- [github.com/go-openapi/runtime/middleware/denco](https://pkg.go.dev/github.com/go-openapi/runtime/middleware/denco) ([MIT](https://github.com/go-openapi/runtime/blob/v0.29.2/middleware/denco/LICENSE))
|
||||
- [github.com/go-openapi/spec](https://pkg.go.dev/github.com/go-openapi/spec) ([Apache-2.0](https://github.com/go-openapi/spec/blob/v0.22.1/LICENSE))
|
||||
- [github.com/go-openapi/strfmt](https://pkg.go.dev/github.com/go-openapi/strfmt) ([Apache-2.0](https://github.com/go-openapi/strfmt/blob/v0.25.0/LICENSE))
|
||||
- [github.com/go-openapi/swag](https://pkg.go.dev/github.com/go-openapi/swag) ([Apache-2.0](https://github.com/go-openapi/swag/blob/v0.25.4/LICENSE))
|
||||
- [github.com/go-openapi/swag/cmdutils](https://pkg.go.dev/github.com/go-openapi/swag/cmdutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/cmdutils/v0.25.4/cmdutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/conv](https://pkg.go.dev/github.com/go-openapi/swag/conv) ([Apache-2.0](https://github.com/go-openapi/swag/blob/conv/v0.25.4/conv/LICENSE))
|
||||
- [github.com/go-openapi/swag/fileutils](https://pkg.go.dev/github.com/go-openapi/swag/fileutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/fileutils/v0.25.4/fileutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonname](https://pkg.go.dev/github.com/go-openapi/swag/jsonname) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonname/v0.25.4/jsonname/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonutils](https://pkg.go.dev/github.com/go-openapi/swag/jsonutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonutils/v0.25.4/jsonutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/loading](https://pkg.go.dev/github.com/go-openapi/swag/loading) ([Apache-2.0](https://github.com/go-openapi/swag/blob/loading/v0.25.4/loading/LICENSE))
|
||||
- [github.com/go-openapi/swag/mangling](https://pkg.go.dev/github.com/go-openapi/swag/mangling) ([Apache-2.0](https://github.com/go-openapi/swag/blob/mangling/v0.25.4/mangling/LICENSE))
|
||||
- [github.com/go-openapi/swag/netutils](https://pkg.go.dev/github.com/go-openapi/swag/netutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/netutils/v0.25.4/netutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/stringutils](https://pkg.go.dev/github.com/go-openapi/swag/stringutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/stringutils/v0.25.4/stringutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/typeutils](https://pkg.go.dev/github.com/go-openapi/swag/typeutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/typeutils/v0.25.4/typeutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/yamlutils](https://pkg.go.dev/github.com/go-openapi/swag/yamlutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/yamlutils/v0.25.4/yamlutils/LICENSE))
|
||||
- [github.com/go-openapi/validate](https://pkg.go.dev/github.com/go-openapi/validate) ([Apache-2.0](https://github.com/go-openapi/validate/blob/v0.25.1/LICENSE))
|
||||
- [github.com/go-viper/mapstructure/v2](https://pkg.go.dev/github.com/go-viper/mapstructure/v2) ([MIT](https://github.com/go-viper/mapstructure/blob/v2.4.0/LICENSE))
|
||||
- [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/2c02b8208cf8/LICENSE))
|
||||
- [github.com/golang/snappy](https://pkg.go.dev/github.com/golang/snappy) ([BSD-3-Clause](https://github.com/golang/snappy/blob/v1.0.0/LICENSE))
|
||||
- [github.com/google/certificate-transparency-go](https://pkg.go.dev/github.com/google/certificate-transparency-go) ([Apache-2.0](https://github.com/google/certificate-transparency-go/blob/v1.3.2/LICENSE))
|
||||
- [github.com/google/go-cmp/cmp](https://pkg.go.dev/github.com/google/go-cmp/cmp) ([BSD-3-Clause](https://github.com/google/go-cmp/blob/v0.7.0/LICENSE))
|
||||
- [github.com/google/go-containerregistry](https://pkg.go.dev/github.com/google/go-containerregistry) ([Apache-2.0](https://github.com/google/go-containerregistry/blob/v0.20.7/LICENSE))
|
||||
- [github.com/google/s2a-go](https://pkg.go.dev/github.com/google/s2a-go) ([Apache-2.0](https://github.com/google/s2a-go/blob/v0.1.9/LICENSE.md))
|
||||
- [github.com/google/shlex](https://pkg.go.dev/github.com/google/shlex) ([Apache-2.0](https://github.com/google/shlex/blob/e7afc7fbc510/COPYING))
|
||||
- [github.com/google/uuid](https://pkg.go.dev/github.com/google/uuid) ([BSD-3-Clause](https://github.com/google/uuid/blob/v1.6.0/LICENSE))
|
||||
- [github.com/googleapis/enterprise-certificate-proxy/client](https://pkg.go.dev/github.com/googleapis/enterprise-certificate-proxy/client) ([Apache-2.0](https://github.com/googleapis/enterprise-certificate-proxy/blob/v0.3.6/LICENSE))
|
||||
- [github.com/googleapis/gax-go/v2](https://pkg.go.dev/github.com/googleapis/gax-go/v2) ([BSD-3-Clause](https://github.com/googleapis/gax-go/blob/v2.15.0/v2/LICENSE))
|
||||
- [github.com/gorilla/css/scanner](https://pkg.go.dev/github.com/gorilla/css/scanner) ([BSD-3-Clause](https://github.com/gorilla/css/blob/v1.0.1/LICENSE))
|
||||
- [github.com/gorilla/websocket](https://pkg.go.dev/github.com/gorilla/websocket) ([BSD-2-Clause](https://github.com/gorilla/websocket/blob/v1.5.3/LICENSE))
|
||||
- [github.com/grpc-ecosystem/grpc-gateway/v2](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/v2) ([BSD-3-Clause](https://github.com/grpc-ecosystem/grpc-gateway/blob/v2.27.2/LICENSE))
|
||||
- [github.com/grpc-ecosystem/grpc-gateway/v2](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/v2) ([BSD-3-Clause](https://github.com/grpc-ecosystem/grpc-gateway/blob/v2.27.3/LICENSE))
|
||||
- [github.com/hashicorp/go-version](https://pkg.go.dev/github.com/hashicorp/go-version) ([MPL-2.0](https://github.com/hashicorp/go-version/blob/v1.8.0/LICENSE))
|
||||
- [github.com/hashicorp/golang-lru/v2](https://pkg.go.dev/github.com/hashicorp/golang-lru/v2) ([MPL-2.0](https://github.com/hashicorp/golang-lru/blob/v2.0.7/LICENSE))
|
||||
- [github.com/hashicorp/golang-lru/v2/simplelru](https://pkg.go.dev/github.com/hashicorp/golang-lru/v2/simplelru) ([BSD-3-Clause](https://github.com/hashicorp/golang-lru/blob/v2.0.7/simplelru/LICENSE_list))
|
||||
- [github.com/henvic/httpretty](https://pkg.go.dev/github.com/henvic/httpretty) ([MIT](https://github.com/henvic/httpretty/blob/v0.1.4/LICENSE.md))
|
||||
- [github.com/huandu/xstrings](https://pkg.go.dev/github.com/huandu/xstrings) ([MIT](https://github.com/huandu/xstrings/blob/v1.5.0/LICENSE))
|
||||
- [github.com/in-toto/attestation/go/v1](https://pkg.go.dev/github.com/in-toto/attestation/go/v1) ([Apache-2.0](https://github.com/in-toto/attestation/blob/v1.1.2/LICENSE))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto) ([Apache-2.0](https://github.com/in-toto/in-toto-golang/blob/v0.9.0/LICENSE))
|
||||
- [github.com/in-toto/attestation/go/v1](https://pkg.go.dev/github.com/in-toto/attestation/go/v1) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1) ([Unknown](Unknown))
|
||||
- [github.com/itchyny/gojq](https://pkg.go.dev/github.com/itchyny/gojq) ([MIT](https://github.com/itchyny/gojq/blob/v0.12.17/LICENSE))
|
||||
- [github.com/itchyny/timefmt-go](https://pkg.go.dev/github.com/itchyny/timefmt-go) ([MIT](https://github.com/itchyny/timefmt-go/blob/v0.1.6/LICENSE))
|
||||
- [github.com/jedisct1/go-minisign](https://pkg.go.dev/github.com/jedisct1/go-minisign) ([MIT](https://github.com/jedisct1/go-minisign/blob/d2f9f49435c7/LICENSE))
|
||||
- [github.com/joho/godotenv](https://pkg.go.dev/github.com/joho/godotenv) ([MIT](https://github.com/joho/godotenv/blob/v1.5.1/LICENCE))
|
||||
- [github.com/josharian/intern](https://pkg.go.dev/github.com/josharian/intern) ([MIT](https://github.com/josharian/intern/blob/v1.0.0/license.md))
|
||||
- [github.com/kballard/go-shellquote](https://pkg.go.dev/github.com/kballard/go-shellquote) ([MIT](https://github.com/kballard/go-shellquote/blob/95032a82bc51/LICENSE))
|
||||
- [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([MIT](https://github.com/klauspost/compress/blob/v1.18.1/LICENSE))
|
||||
- [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.18.1/LICENSE))
|
||||
- [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.18.1/LICENSE))
|
||||
- [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.18.1/internal/snapref/LICENSE))
|
||||
- [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.18.1/zstd/internal/xxhash/LICENSE.txt))
|
||||
- [github.com/letsencrypt/boulder](https://pkg.go.dev/github.com/letsencrypt/boulder) ([MPL-2.0](https://github.com/letsencrypt/boulder/blob/v0.20250630.0/LICENSE.txt))
|
||||
- [github.com/lucasb-eyer/go-colorful](https://pkg.go.dev/github.com/lucasb-eyer/go-colorful) ([MIT](https://github.com/lucasb-eyer/go-colorful/blob/v1.3.0/LICENSE))
|
||||
- [github.com/mailru/easyjson](https://pkg.go.dev/github.com/mailru/easyjson) ([MIT](https://github.com/mailru/easyjson/blob/v0.9.0/LICENSE))
|
||||
- [github.com/mattn/go-colorable](https://pkg.go.dev/github.com/mattn/go-colorable) ([MIT](https://github.com/mattn/go-colorable/blob/v0.1.14/LICENSE))
|
||||
- [github.com/mattn/go-isatty](https://pkg.go.dev/github.com/mattn/go-isatty) ([MIT](https://github.com/mattn/go-isatty/blob/v0.0.20/LICENSE))
|
||||
- [github.com/mattn/go-runewidth](https://pkg.go.dev/github.com/mattn/go-runewidth) ([MIT](https://github.com/mattn/go-runewidth/blob/v0.0.16/LICENSE))
|
||||
- [github.com/mattn/go-runewidth](https://pkg.go.dev/github.com/mattn/go-runewidth) ([MIT](https://github.com/mattn/go-runewidth/blob/v0.0.17/LICENSE))
|
||||
- [github.com/mgutz/ansi](https://pkg.go.dev/github.com/mgutz/ansi) ([MIT](https://github.com/mgutz/ansi/blob/d51e80ef957d/LICENSE))
|
||||
- [github.com/microcosm-cc/bluemonday](https://pkg.go.dev/github.com/microcosm-cc/bluemonday) ([BSD-3-Clause](https://github.com/microcosm-cc/bluemonday/blob/v1.0.27/LICENSE.md))
|
||||
- [github.com/microsoft/dev-tunnels/go/tunnels](https://pkg.go.dev/github.com/microsoft/dev-tunnels/go/tunnels) ([MIT](https://github.com/microsoft/dev-tunnels/blob/v0.1.19/LICENSE))
|
||||
- [github.com/mitchellh/copystructure](https://pkg.go.dev/github.com/mitchellh/copystructure) ([MIT](https://github.com/mitchellh/copystructure/blob/v1.2.0/LICENSE))
|
||||
- [github.com/mitchellh/go-homedir](https://pkg.go.dev/github.com/mitchellh/go-homedir) ([MIT](https://github.com/mitchellh/go-homedir/blob/v1.1.0/LICENSE))
|
||||
- [github.com/mitchellh/hashstructure/v2](https://pkg.go.dev/github.com/mitchellh/hashstructure/v2) ([MIT](https://github.com/mitchellh/hashstructure/blob/v2.0.2/LICENSE))
|
||||
- [github.com/mitchellh/mapstructure](https://pkg.go.dev/github.com/mitchellh/mapstructure) ([MIT](https://github.com/mitchellh/mapstructure/blob/v1.5.0/LICENSE))
|
||||
- [github.com/mitchellh/reflectwalk](https://pkg.go.dev/github.com/mitchellh/reflectwalk) ([MIT](https://github.com/mitchellh/reflectwalk/blob/v1.0.2/LICENSE))
|
||||
- [github.com/muesli/ansi](https://pkg.go.dev/github.com/muesli/ansi) ([MIT](https://github.com/muesli/ansi/blob/276c6243b2f6/LICENSE))
|
||||
- [github.com/muesli/cancelreader](https://pkg.go.dev/github.com/muesli/cancelreader) ([MIT](https://github.com/muesli/cancelreader/blob/v0.2.2/LICENSE))
|
||||
|
|
@ -157,83 +128,60 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/opencontainers/go-digest](https://pkg.go.dev/github.com/opencontainers/go-digest) ([Apache-2.0](https://github.com/opencontainers/go-digest/blob/v1.0.0/LICENSE))
|
||||
- [github.com/opencontainers/image-spec/specs-go](https://pkg.go.dev/github.com/opencontainers/image-spec/specs-go) ([Apache-2.0](https://github.com/opencontainers/image-spec/blob/v1.1.1/LICENSE))
|
||||
- [github.com/opentracing/opentracing-go](https://pkg.go.dev/github.com/opentracing/opentracing-go) ([Apache-2.0](https://github.com/opentracing/opentracing-go/blob/v1.2.0/LICENSE))
|
||||
- [github.com/pelletier/go-toml/v2](https://pkg.go.dev/github.com/pelletier/go-toml/v2) ([MIT](https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE))
|
||||
- [github.com/pkg/errors](https://pkg.go.dev/github.com/pkg/errors) ([BSD-2-Clause](https://github.com/pkg/errors/blob/v0.9.1/LICENSE))
|
||||
- [github.com/pmezard/go-difflib/difflib](https://pkg.go.dev/github.com/pmezard/go-difflib/difflib) ([BSD-3-Clause](https://github.com/pmezard/go-difflib/blob/5d4384ee4fb2/LICENSE))
|
||||
- [github.com/rivo/tview](https://pkg.go.dev/github.com/rivo/tview) ([MIT](https://github.com/rivo/tview/blob/v0.42.0/LICENSE.txt))
|
||||
- [github.com/rivo/uniseg](https://pkg.go.dev/github.com/rivo/uniseg) ([MIT](https://github.com/rivo/uniseg/blob/v0.4.7/LICENSE.txt))
|
||||
- [github.com/rodaine/table](https://pkg.go.dev/github.com/rodaine/table) ([MIT](https://github.com/rodaine/table/blob/v1.3.0/license))
|
||||
- [github.com/russross/blackfriday/v2](https://pkg.go.dev/github.com/russross/blackfriday/v2) ([BSD-2-Clause](https://github.com/russross/blackfriday/blob/v2.1.0/LICENSE.txt))
|
||||
- [github.com/sagikazarmark/locafero](https://pkg.go.dev/github.com/sagikazarmark/locafero) ([MIT](https://github.com/sagikazarmark/locafero/blob/v0.9.0/LICENSE))
|
||||
- [github.com/sassoftware/relic/lib](https://pkg.go.dev/github.com/sassoftware/relic/lib) ([Apache-2.0](https://github.com/sassoftware/relic/blob/v7.2.1/LICENSE))
|
||||
- [github.com/secure-systems-lab/go-securesystemslib](https://pkg.go.dev/github.com/secure-systems-lab/go-securesystemslib) ([MIT](https://github.com/secure-systems-lab/go-securesystemslib/blob/v0.9.1/LICENSE))
|
||||
- [github.com/shibumi/go-pathspec](https://pkg.go.dev/github.com/shibumi/go-pathspec) ([Apache-2.0](https://github.com/shibumi/go-pathspec/blob/v1.3.0/LICENSE))
|
||||
- [github.com/shopspring/decimal](https://pkg.go.dev/github.com/shopspring/decimal) ([MIT](https://github.com/shopspring/decimal/blob/v1.4.0/LICENSE))
|
||||
- [github.com/shurcooL/githubv4](https://pkg.go.dev/github.com/shurcooL/githubv4) ([MIT](https://github.com/shurcooL/githubv4/blob/48295856cce7/LICENSE))
|
||||
- [github.com/shurcooL/graphql](https://pkg.go.dev/github.com/shurcooL/graphql) ([MIT](https://github.com/shurcooL/graphql/blob/ed46e5a46466/LICENSE))
|
||||
- [github.com/sigstore/protobuf-specs/gen/pb-go](https://pkg.go.dev/github.com/sigstore/protobuf-specs/gen/pb-go) ([Apache-2.0](https://github.com/sigstore/protobuf-specs/blob/v0.5.0/LICENSE))
|
||||
- [github.com/sigstore/rekor-tiles](https://pkg.go.dev/github.com/sigstore/rekor-tiles) ([Apache-2.0](https://github.com/sigstore/rekor-tiles/blob/v0.1.11/LICENSE))
|
||||
- [github.com/sigstore/rekor/pkg](https://pkg.go.dev/github.com/sigstore/rekor/pkg) ([Apache-2.0](https://github.com/sigstore/rekor/blob/v1.4.2/LICENSE))
|
||||
- [github.com/sigstore/sigstore-go/pkg](https://pkg.go.dev/github.com/sigstore/sigstore-go/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore-go/blob/v1.1.3/LICENSE))
|
||||
- [github.com/sigstore/sigstore/pkg](https://pkg.go.dev/github.com/sigstore/sigstore/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore/blob/181c5d3339b3/LICENSE))
|
||||
- [github.com/sigstore/timestamp-authority/pkg/verification](https://pkg.go.dev/github.com/sigstore/timestamp-authority/pkg/verification) ([Apache-2.0](https://github.com/sigstore/timestamp-authority/blob/v1.2.9/LICENSE))
|
||||
- [github.com/sigstore/rekor-tiles/v2](https://pkg.go.dev/github.com/sigstore/rekor-tiles/v2) ([Apache-2.0](https://github.com/sigstore/rekor-tiles/blob/v2.0.1/LICENSE))
|
||||
- [github.com/sigstore/rekor/pkg](https://pkg.go.dev/github.com/sigstore/rekor/pkg) ([Apache-2.0](https://github.com/sigstore/rekor/blob/v1.4.3/LICENSE))
|
||||
- [github.com/sigstore/sigstore-go/pkg](https://pkg.go.dev/github.com/sigstore/sigstore-go/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore-go/blob/v1.1.4/LICENSE))
|
||||
- [github.com/sigstore/sigstore/pkg](https://pkg.go.dev/github.com/sigstore/sigstore/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore/blob/v1.10.0/LICENSE))
|
||||
- [github.com/sigstore/timestamp-authority/v2/pkg/verification](https://pkg.go.dev/github.com/sigstore/timestamp-authority/v2/pkg/verification) ([Apache-2.0](https://github.com/sigstore/timestamp-authority/blob/v2.0.3/LICENSE))
|
||||
- [github.com/sirupsen/logrus](https://pkg.go.dev/github.com/sirupsen/logrus) ([MIT](https://github.com/sirupsen/logrus/blob/v1.9.3/LICENSE))
|
||||
- [github.com/sourcegraph/conc](https://pkg.go.dev/github.com/sourcegraph/conc) ([MIT](https://github.com/sourcegraph/conc/blob/v0.3.0/LICENSE))
|
||||
- [github.com/spf13/afero](https://pkg.go.dev/github.com/spf13/afero) ([Apache-2.0](https://github.com/spf13/afero/blob/v1.14.0/LICENSE.txt))
|
||||
- [github.com/spf13/cast](https://pkg.go.dev/github.com/spf13/cast) ([MIT](https://github.com/spf13/cast/blob/v1.9.2/LICENSE))
|
||||
- [github.com/spf13/cast](https://pkg.go.dev/github.com/spf13/cast) ([MIT](https://github.com/spf13/cast/blob/v1.10.0/LICENSE))
|
||||
- [github.com/spf13/cobra](https://pkg.go.dev/github.com/spf13/cobra) ([Apache-2.0](https://github.com/spf13/cobra/blob/v1.10.2/LICENSE.txt))
|
||||
- [github.com/spf13/pflag](https://pkg.go.dev/github.com/spf13/pflag) ([BSD-3-Clause](https://github.com/spf13/pflag/blob/v1.0.10/LICENSE))
|
||||
- [github.com/spf13/viper](https://pkg.go.dev/github.com/spf13/viper) ([MIT](https://github.com/spf13/viper/blob/v1.20.1/LICENSE))
|
||||
- [github.com/spiffe/go-spiffe/v2](https://pkg.go.dev/github.com/spiffe/go-spiffe/v2) ([Apache-2.0](https://github.com/spiffe/go-spiffe/blob/v2.6.0/LICENSE))
|
||||
- [github.com/stretchr/objx](https://pkg.go.dev/github.com/stretchr/objx) ([MIT](https://github.com/stretchr/objx/blob/v0.5.2/LICENSE))
|
||||
- [github.com/stretchr/testify](https://pkg.go.dev/github.com/stretchr/testify) ([MIT](https://github.com/stretchr/testify/blob/v1.11.1/LICENSE))
|
||||
- [github.com/subosito/gotenv](https://pkg.go.dev/github.com/subosito/gotenv) ([MIT](https://github.com/subosito/gotenv/blob/v1.6.0/LICENSE))
|
||||
- [github.com/theupdateframework/go-tuf](https://pkg.go.dev/github.com/theupdateframework/go-tuf) ([BSD-3-Clause](https://github.com/theupdateframework/go-tuf/blob/v0.7.0/LICENSE))
|
||||
- [github.com/theupdateframework/go-tuf/v2/metadata](https://pkg.go.dev/github.com/theupdateframework/go-tuf/v2/metadata) ([Apache-2.0](https://github.com/theupdateframework/go-tuf/blob/v2.3.0/LICENSE))
|
||||
- [github.com/thlib/go-timezone-local/tzlocal](https://pkg.go.dev/github.com/thlib/go-timezone-local/tzlocal) ([Unlicense](https://github.com/thlib/go-timezone-local/blob/v0.0.6/LICENSE))
|
||||
- [github.com/titanous/rocacheck](https://pkg.go.dev/github.com/titanous/rocacheck) ([MIT](https://github.com/titanous/rocacheck/blob/afe73141d399/LICENSE))
|
||||
- [github.com/transparency-dev/formats](https://pkg.go.dev/github.com/transparency-dev/formats) ([Apache-2.0](https://github.com/transparency-dev/formats/blob/bb8ad4d07c26/LICENSE))
|
||||
- [github.com/transparency-dev/formats/log](https://pkg.go.dev/github.com/transparency-dev/formats/log) ([Apache-2.0](https://github.com/transparency-dev/formats/blob/404c0d5b696c/LICENSE))
|
||||
- [github.com/transparency-dev/merkle](https://pkg.go.dev/github.com/transparency-dev/merkle) ([Apache-2.0](https://github.com/transparency-dev/merkle/blob/v0.0.2/LICENSE))
|
||||
- [github.com/transparency-dev/tessera](https://pkg.go.dev/github.com/transparency-dev/tessera) ([Apache-2.0](https://github.com/transparency-dev/tessera/blob/v1.0.0-rc3/LICENSE))
|
||||
- [github.com/vbatts/tar-split/archive/tar](https://pkg.go.dev/github.com/vbatts/tar-split/archive/tar) ([BSD-3-Clause](https://github.com/vbatts/tar-split/blob/v0.12.2/LICENSE))
|
||||
- [github.com/vmihailenco/msgpack/v5](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5) ([BSD-2-Clause](https://github.com/vmihailenco/msgpack/blob/v5.4.1/LICENSE))
|
||||
- [github.com/vmihailenco/tagparser/v2](https://pkg.go.dev/github.com/vmihailenco/tagparser/v2) ([BSD-2-Clause](https://github.com/vmihailenco/tagparser/blob/v2.0.0/LICENSE))
|
||||
- [github.com/xo/terminfo](https://pkg.go.dev/github.com/xo/terminfo) ([MIT](https://github.com/xo/terminfo/blob/abceb7e1c41e/LICENSE))
|
||||
- [github.com/yuin/goldmark](https://pkg.go.dev/github.com/yuin/goldmark) ([MIT](https://github.com/yuin/goldmark/blob/v1.7.13/LICENSE))
|
||||
- [github.com/yuin/goldmark](https://pkg.go.dev/github.com/yuin/goldmark) ([MIT](https://github.com/yuin/goldmark/blob/v1.7.16/LICENSE))
|
||||
- [github.com/yuin/goldmark-emoji](https://pkg.go.dev/github.com/yuin/goldmark-emoji) ([MIT](https://github.com/yuin/goldmark-emoji/blob/v1.0.6/LICENSE))
|
||||
- [github.com/zalando/go-keyring](https://pkg.go.dev/github.com/zalando/go-keyring) ([MIT](https://github.com/zalando/go-keyring/blob/v0.2.6/LICENSE))
|
||||
- [go.mongodb.org/mongo-driver](https://pkg.go.dev/go.mongodb.org/mongo-driver) ([Apache-2.0](https://github.com/mongodb/mongo-go-driver/blob/v1.17.4/LICENSE))
|
||||
- [go.opencensus.io](https://pkg.go.dev/go.opencensus.io) ([Apache-2.0](https://github.com/census-instrumentation/opencensus-go/blob/v0.24.0/LICENSE))
|
||||
- [go.mongodb.org/mongo-driver](https://pkg.go.dev/go.mongodb.org/mongo-driver) ([Apache-2.0](https://github.com/mongodb/mongo-go-driver/blob/v1.17.6/LICENSE))
|
||||
- [go.opentelemetry.io/auto/sdk](https://pkg.go.dev/go.opentelemetry.io/auto/sdk) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-instrumentation/blob/sdk/v1.2.1/sdk/LICENSE))
|
||||
- [go.opentelemetry.io/contrib/detectors/gcp](https://pkg.go.dev/go.opentelemetry.io/contrib/detectors/gcp) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/detectors/gcp/v1.38.0/detectors/gcp/LICENSE))
|
||||
- [go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc](https://pkg.go.dev/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/instrumentation/google.golang.org/grpc/otelgrpc/v0.61.0/instrumentation/google.golang.org/grpc/otelgrpc/LICENSE))
|
||||
- [go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp](https://pkg.go.dev/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/instrumentation/net/http/otelhttp/v0.61.0/instrumentation/net/http/otelhttp/LICENSE))
|
||||
- [go.opentelemetry.io/otel](https://pkg.go.dev/go.opentelemetry.io/otel) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/v1.38.0/LICENSE))
|
||||
- [go.opentelemetry.io/otel](https://pkg.go.dev/go.opentelemetry.io/otel) ([BSD-3-Clause](https://github.com/open-telemetry/opentelemetry-go/blob/v1.38.0/LICENSE))
|
||||
- [go.opentelemetry.io/otel/metric](https://pkg.go.dev/go.opentelemetry.io/otel/metric) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/metric/v1.38.0/metric/LICENSE))
|
||||
- [go.opentelemetry.io/otel/sdk](https://pkg.go.dev/go.opentelemetry.io/otel/sdk) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/sdk/v1.38.0/sdk/LICENSE))
|
||||
- [go.opentelemetry.io/otel/sdk/metric](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/sdk/metric/v1.38.0/sdk/metric/LICENSE))
|
||||
- [go.opentelemetry.io/otel/metric](https://pkg.go.dev/go.opentelemetry.io/otel/metric) ([BSD-3-Clause](https://github.com/open-telemetry/opentelemetry-go/blob/metric/v1.38.0/metric/LICENSE))
|
||||
- [go.opentelemetry.io/otel/trace](https://pkg.go.dev/go.opentelemetry.io/otel/trace) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/trace/v1.38.0/trace/LICENSE))
|
||||
- [go.uber.org/multierr](https://pkg.go.dev/go.uber.org/multierr) ([MIT](https://github.com/uber-go/multierr/blob/v1.11.0/LICENSE.txt))
|
||||
- [go.uber.org/zap](https://pkg.go.dev/go.uber.org/zap) ([MIT](https://github.com/uber-go/zap/blob/v1.27.0/LICENSE))
|
||||
- [go.opentelemetry.io/otel/trace](https://pkg.go.dev/go.opentelemetry.io/otel/trace) ([BSD-3-Clause](https://github.com/open-telemetry/opentelemetry-go/blob/trace/v1.38.0/trace/LICENSE))
|
||||
- [go.yaml.in/yaml/v3](https://pkg.go.dev/go.yaml.in/yaml/v3) ([MIT](https://github.com/yaml/go-yaml/blob/v3.0.4/LICENSE))
|
||||
- [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.46.0:LICENSE))
|
||||
- [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/b7579e27:LICENSE))
|
||||
- [golang.org/x/mod](https://pkg.go.dev/golang.org/x/mod) ([BSD-3-Clause](https://cs.opensource.google/go/x/mod/+/v0.30.0:LICENSE))
|
||||
- [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.47.0:LICENSE))
|
||||
- [golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) ([BSD-3-Clause](https://cs.opensource.google/go/x/oauth2/+/v0.33.0:LICENSE))
|
||||
- [golang.org/x/sync](https://pkg.go.dev/golang.org/x/sync) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.19.0:LICENSE))
|
||||
- [golang.org/x/sync/errgroup](https://pkg.go.dev/golang.org/x/sync/errgroup) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.19.0:LICENSE))
|
||||
- [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.39.0:LICENSE))
|
||||
- [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.38.0:LICENSE))
|
||||
- [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.32.0:LICENSE))
|
||||
- [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.12.0:LICENSE))
|
||||
- [google.golang.org/api](https://pkg.go.dev/google.golang.org/api) ([BSD-3-Clause](https://github.com/googleapis/google-api-go-client/blob/v0.248.0/LICENSE))
|
||||
- [google.golang.org/api/internal/third_party/uritemplates](https://pkg.go.dev/google.golang.org/api/internal/third_party/uritemplates) ([BSD-3-Clause](https://github.com/googleapis/google-api-go-client/blob/v0.248.0/internal/third_party/uritemplates/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/api](https://pkg.go.dev/google.golang.org/genproto/googleapis/api) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/3a174f9686a8/googleapis/api/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/rpc](https://pkg.go.dev/google.golang.org/genproto/googleapis/rpc) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/3a174f9686a8/googleapis/rpc/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/type](https://pkg.go.dev/google.golang.org/genproto/googleapis/type) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/513f23925822/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/rpc/status](https://pkg.go.dev/google.golang.org/genproto/googleapis/rpc/status) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/f26f9409b101/googleapis/rpc/LICENSE))
|
||||
- [google.golang.org/grpc](https://pkg.go.dev/google.golang.org/grpc) ([Apache-2.0](https://github.com/grpc/grpc-go/blob/v1.77.0/LICENSE))
|
||||
- [google.golang.org/protobuf](https://pkg.go.dev/google.golang.org/protobuf) ([BSD-3-Clause](https://github.com/protocolbuffers/protobuf-go/blob/v1.36.10/LICENSE))
|
||||
- [gopkg.in/yaml.v3](https://pkg.go.dev/gopkg.in/yaml.v3) ([MIT](https://github.com/go-yaml/yaml/blob/v3.0.1/LICENSE))
|
||||
- [k8s.io/klog/v2](https://pkg.go.dev/k8s.io/klog/v2) ([Apache-2.0](https://github.com/kubernetes/klog/blob/v2.130.1/LICENSE))
|
||||
|
||||
[cli/cli]: https://github.com/cli/cli
|
||||
|
|
|
|||
|
|
@ -7,23 +7,9 @@ The following open source dependencies are used to build the [cli/cli][] GitHub
|
|||
Some packages may only be included on certain architectures or operating systems.
|
||||
|
||||
|
||||
- [cel.dev/expr](https://pkg.go.dev/cel.dev/expr) ([Apache-2.0](https://github.com/google/cel-spec/blob/v0.24.0/LICENSE))
|
||||
- [cloud.google.com/go](https://pkg.go.dev/cloud.google.com/go) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/v0.121.6/LICENSE))
|
||||
- [cloud.google.com/go/auth](https://pkg.go.dev/cloud.google.com/go/auth) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/auth/v0.16.5/auth/LICENSE))
|
||||
- [cloud.google.com/go/auth/oauth2adapt](https://pkg.go.dev/cloud.google.com/go/auth/oauth2adapt) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/auth/oauth2adapt/v0.2.8/auth/oauth2adapt/LICENSE))
|
||||
- [cloud.google.com/go/compute/metadata](https://pkg.go.dev/cloud.google.com/go/compute/metadata) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/compute/metadata/v0.9.0/compute/metadata/LICENSE))
|
||||
- [cloud.google.com/go/iam](https://pkg.go.dev/cloud.google.com/go/iam) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/iam/v1.5.2/iam/LICENSE))
|
||||
- [cloud.google.com/go/longrunning](https://pkg.go.dev/cloud.google.com/go/longrunning) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/longrunning/v0.6.7/longrunning/LICENSE))
|
||||
- [cloud.google.com/go/monitoring](https://pkg.go.dev/cloud.google.com/go/monitoring) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/monitoring/v1.24.2/monitoring/LICENSE))
|
||||
- [cloud.google.com/go/spanner](https://pkg.go.dev/cloud.google.com/go/spanner) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/spanner/v1.84.1/spanner/LICENSE))
|
||||
- [cloud.google.com/go/storage](https://pkg.go.dev/cloud.google.com/go/storage) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/storage/v1.56.1/storage/LICENSE))
|
||||
- [dario.cat/mergo](https://pkg.go.dev/dario.cat/mergo) ([BSD-3-Clause](https://github.com/imdario/mergo/blob/v1.0.2/LICENSE))
|
||||
- [github.com/AlecAivazis/survey/v2](https://pkg.go.dev/github.com/AlecAivazis/survey/v2) ([MIT](https://github.com/AlecAivazis/survey/blob/v2.3.7/LICENSE))
|
||||
- [github.com/AlecAivazis/survey/v2/terminal](https://pkg.go.dev/github.com/AlecAivazis/survey/v2/terminal) ([MIT](https://github.com/AlecAivazis/survey/blob/v2.3.7/terminal/LICENSE.txt))
|
||||
- [github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp](https://pkg.go.dev/github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp) ([Apache-2.0](https://github.com/GoogleCloudPlatform/grpc-gcp-go/blob/grpcgcp/v1.5.3/grpcgcp/LICENSE))
|
||||
- [github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp](https://pkg.go.dev/github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp) ([Apache-2.0](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/detectors/gcp/v1.30.0/detectors/gcp/LICENSE))
|
||||
- [github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric](https://pkg.go.dev/github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric) ([Apache-2.0](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/exporter/metric/v0.53.0/exporter/metric/LICENSE))
|
||||
- [github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping](https://pkg.go.dev/github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping) ([Apache-2.0](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/internal/resourcemapping/v0.53.0/internal/resourcemapping/LICENSE))
|
||||
- [github.com/MakeNowJust/heredoc](https://pkg.go.dev/github.com/MakeNowJust/heredoc) ([MIT](https://github.com/MakeNowJust/heredoc/blob/v1.0.0/LICENSE))
|
||||
- [github.com/Masterminds/goutils](https://pkg.go.dev/github.com/Masterminds/goutils) ([Apache-2.0](https://github.com/Masterminds/goutils/blob/v1.1.1/LICENSE.txt))
|
||||
- [github.com/Masterminds/semver/v3](https://pkg.go.dev/github.com/Masterminds/semver/v3) ([MIT](https://github.com/Masterminds/semver/blob/v3.4.0/LICENSE.txt))
|
||||
|
|
@ -38,14 +24,13 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/catppuccin/go](https://pkg.go.dev/github.com/catppuccin/go) ([MIT](https://github.com/catppuccin/go/blob/v0.3.0/LICENSE))
|
||||
- [github.com/cenkalti/backoff/v4](https://pkg.go.dev/github.com/cenkalti/backoff/v4) ([MIT](https://github.com/cenkalti/backoff/blob/v4.3.0/LICENSE))
|
||||
- [github.com/cenkalti/backoff/v5](https://pkg.go.dev/github.com/cenkalti/backoff/v5) ([MIT](https://github.com/cenkalti/backoff/blob/v5.0.3/LICENSE))
|
||||
- [github.com/cespare/xxhash/v2](https://pkg.go.dev/github.com/cespare/xxhash/v2) ([MIT](https://github.com/cespare/xxhash/blob/v2.3.0/LICENSE.txt))
|
||||
- [github.com/charmbracelet/bubbles](https://pkg.go.dev/github.com/charmbracelet/bubbles) ([MIT](https://github.com/charmbracelet/bubbles/blob/23b8fd6302d7/LICENSE))
|
||||
- [github.com/charmbracelet/bubbletea](https://pkg.go.dev/github.com/charmbracelet/bubbletea) ([MIT](https://github.com/charmbracelet/bubbletea/blob/v1.3.6/LICENSE))
|
||||
- [github.com/charmbracelet/bubbletea](https://pkg.go.dev/github.com/charmbracelet/bubbletea) ([MIT](https://github.com/charmbracelet/bubbletea/blob/v1.3.10/LICENSE))
|
||||
- [github.com/charmbracelet/colorprofile](https://pkg.go.dev/github.com/charmbracelet/colorprofile) ([MIT](https://github.com/charmbracelet/colorprofile/blob/v0.3.1/LICENSE))
|
||||
- [github.com/charmbracelet/glamour](https://pkg.go.dev/github.com/charmbracelet/glamour) ([MIT](https://github.com/charmbracelet/glamour/blob/v0.10.0/LICENSE))
|
||||
- [github.com/charmbracelet/huh](https://pkg.go.dev/github.com/charmbracelet/huh) ([MIT](https://github.com/charmbracelet/huh/blob/v0.8.0/LICENSE))
|
||||
- [github.com/charmbracelet/lipgloss](https://pkg.go.dev/github.com/charmbracelet/lipgloss) ([MIT](https://github.com/charmbracelet/lipgloss/blob/76690c660834/LICENSE))
|
||||
- [github.com/charmbracelet/x/ansi](https://pkg.go.dev/github.com/charmbracelet/x/ansi) ([MIT](https://github.com/charmbracelet/x/blob/ansi/v0.9.3/ansi/LICENSE))
|
||||
- [github.com/charmbracelet/x/ansi](https://pkg.go.dev/github.com/charmbracelet/x/ansi) ([MIT](https://github.com/charmbracelet/x/blob/ansi/v0.10.2/ansi/LICENSE))
|
||||
- [github.com/charmbracelet/x/cellbuf](https://pkg.go.dev/github.com/charmbracelet/x/cellbuf) ([MIT](https://github.com/charmbracelet/x/blob/cellbuf/v0.0.13/cellbuf/LICENSE))
|
||||
- [github.com/charmbracelet/x/exp/slice](https://pkg.go.dev/github.com/charmbracelet/x/exp/slice) ([MIT](https://github.com/charmbracelet/x/blob/821143405392/exp/slice/LICENSE))
|
||||
- [github.com/charmbracelet/x/exp/strings](https://pkg.go.dev/github.com/charmbracelet/x/exp/strings) ([MIT](https://github.com/charmbracelet/x/blob/821143405392/exp/strings/LICENSE))
|
||||
|
|
@ -55,10 +40,9 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/cli/oauth](https://pkg.go.dev/github.com/cli/oauth) ([MIT](https://github.com/cli/oauth/blob/v1.2.1/LICENSE))
|
||||
- [github.com/cli/safeexec](https://pkg.go.dev/github.com/cli/safeexec) ([BSD-2-Clause](https://github.com/cli/safeexec/blob/v1.0.1/LICENSE))
|
||||
- [github.com/cli/shurcooL-graphql](https://pkg.go.dev/github.com/cli/shurcooL-graphql) ([MIT](https://github.com/cli/shurcooL-graphql/blob/v0.0.4/LICENSE))
|
||||
- [github.com/cncf/xds/go](https://pkg.go.dev/github.com/cncf/xds/go) ([Apache-2.0](https://github.com/cncf/xds/blob/0feb69152e9f/go/LICENSE))
|
||||
- [github.com/containerd/stargz-snapshotter/estargz](https://pkg.go.dev/github.com/containerd/stargz-snapshotter/estargz) ([Apache-2.0](https://github.com/containerd/stargz-snapshotter/blob/estargz/v0.18.1/estargz/LICENSE))
|
||||
- [github.com/cpuguy83/go-md2man/v2/md2man](https://pkg.go.dev/github.com/cpuguy83/go-md2man/v2/md2man) ([MIT](https://github.com/cpuguy83/go-md2man/blob/v2.0.7/LICENSE.md))
|
||||
- [github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer](https://pkg.go.dev/github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer) ([Apache-2.0](https://github.com/cyberphone/json-canonicalization/blob/19d51d7fe467/LICENSE))
|
||||
- [github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer](https://pkg.go.dev/github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer) ([Unknown](Unknown))
|
||||
- [github.com/davecgh/go-spew/spew](https://pkg.go.dev/github.com/davecgh/go-spew/spew) ([ISC](https://github.com/davecgh/go-spew/blob/d8f796af33cc/LICENSE))
|
||||
- [github.com/digitorus/pkcs7](https://pkg.go.dev/github.com/digitorus/pkcs7) ([MIT](https://github.com/digitorus/pkcs7/blob/3a137a874352/LICENSE))
|
||||
- [github.com/digitorus/timestamp](https://pkg.go.dev/github.com/digitorus/timestamp) ([BSD-2-Clause](https://github.com/digitorus/timestamp/blob/c45532741eea/LICENSE))
|
||||
|
|
@ -68,85 +52,72 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/docker/distribution/registry/client/auth/challenge](https://pkg.go.dev/github.com/docker/distribution/registry/client/auth/challenge) ([Apache-2.0](https://github.com/docker/distribution/blob/v2.8.3/LICENSE))
|
||||
- [github.com/docker/docker-credential-helpers](https://pkg.go.dev/github.com/docker/docker-credential-helpers) ([MIT](https://github.com/docker/docker-credential-helpers/blob/v0.9.3/LICENSE))
|
||||
- [github.com/dustin/go-humanize](https://pkg.go.dev/github.com/dustin/go-humanize) ([MIT](https://github.com/dustin/go-humanize/blob/v1.0.1/LICENSE))
|
||||
- [github.com/envoyproxy/go-control-plane/envoy](https://pkg.go.dev/github.com/envoyproxy/go-control-plane/envoy) ([Apache-2.0](https://github.com/envoyproxy/go-control-plane/blob/envoy/v1.35.0/envoy/LICENSE))
|
||||
- [github.com/envoyproxy/protoc-gen-validate/validate](https://pkg.go.dev/github.com/envoyproxy/protoc-gen-validate/validate) ([Apache-2.0](https://github.com/envoyproxy/protoc-gen-validate/blob/v1.2.1/LICENSE))
|
||||
- [github.com/fatih/color](https://pkg.go.dev/github.com/fatih/color) ([MIT](https://github.com/fatih/color/blob/v1.18.0/LICENSE.md))
|
||||
- [github.com/felixge/httpsnoop](https://pkg.go.dev/github.com/felixge/httpsnoop) ([MIT](https://github.com/felixge/httpsnoop/blob/v1.0.4/LICENSE.txt))
|
||||
- [github.com/fsnotify/fsnotify](https://pkg.go.dev/github.com/fsnotify/fsnotify) ([BSD-3-Clause](https://github.com/fsnotify/fsnotify/blob/v1.9.0/LICENSE))
|
||||
- [github.com/gabriel-vasile/mimetype](https://pkg.go.dev/github.com/gabriel-vasile/mimetype) ([MIT](https://github.com/gabriel-vasile/mimetype/blob/v1.4.11/LICENSE))
|
||||
- [github.com/gdamore/encoding](https://pkg.go.dev/github.com/gdamore/encoding) ([Apache-2.0](https://github.com/gdamore/encoding/blob/v1.0.1/LICENSE))
|
||||
- [github.com/gdamore/tcell/v2](https://pkg.go.dev/github.com/gdamore/tcell/v2) ([Apache-2.0](https://github.com/gdamore/tcell/blob/v2.13.4/LICENSE))
|
||||
- [github.com/go-chi/chi/v5](https://pkg.go.dev/github.com/go-chi/chi/v5) ([MIT](https://github.com/go-chi/chi/blob/v5.2.3/LICENSE))
|
||||
- [github.com/go-jose/go-jose/v4](https://pkg.go.dev/github.com/go-jose/go-jose/v4) ([Apache-2.0](https://github.com/go-jose/go-jose/blob/v4.1.3/LICENSE))
|
||||
- [github.com/go-jose/go-jose/v4/json](https://pkg.go.dev/github.com/go-jose/go-jose/v4/json) ([BSD-3-Clause](https://github.com/go-jose/go-jose/blob/v4.1.3/json/LICENSE))
|
||||
- [github.com/go-logr/logr](https://pkg.go.dev/github.com/go-logr/logr) ([Apache-2.0](https://github.com/go-logr/logr/blob/v1.4.3/LICENSE))
|
||||
- [github.com/go-logr/stdr](https://pkg.go.dev/github.com/go-logr/stdr) ([Apache-2.0](https://github.com/go-logr/stdr/blob/v1.2.2/LICENSE))
|
||||
- [github.com/go-openapi/analysis](https://pkg.go.dev/github.com/go-openapi/analysis) ([Apache-2.0](https://github.com/go-openapi/analysis/blob/v0.23.0/LICENSE))
|
||||
- [github.com/go-openapi/errors](https://pkg.go.dev/github.com/go-openapi/errors) ([Apache-2.0](https://github.com/go-openapi/errors/blob/v0.22.2/LICENSE))
|
||||
- [github.com/go-openapi/jsonpointer](https://pkg.go.dev/github.com/go-openapi/jsonpointer) ([Apache-2.0](https://github.com/go-openapi/jsonpointer/blob/v0.21.1/LICENSE))
|
||||
- [github.com/go-openapi/jsonreference](https://pkg.go.dev/github.com/go-openapi/jsonreference) ([Apache-2.0](https://github.com/go-openapi/jsonreference/blob/v0.21.0/LICENSE))
|
||||
- [github.com/go-openapi/loads](https://pkg.go.dev/github.com/go-openapi/loads) ([Apache-2.0](https://github.com/go-openapi/loads/blob/v0.22.0/LICENSE))
|
||||
- [github.com/go-openapi/runtime](https://pkg.go.dev/github.com/go-openapi/runtime) ([Apache-2.0](https://github.com/go-openapi/runtime/blob/v0.28.0/LICENSE))
|
||||
- [github.com/go-openapi/runtime/middleware/denco](https://pkg.go.dev/github.com/go-openapi/runtime/middleware/denco) ([MIT](https://github.com/go-openapi/runtime/blob/v0.28.0/middleware/denco/LICENSE))
|
||||
- [github.com/go-openapi/spec](https://pkg.go.dev/github.com/go-openapi/spec) ([Apache-2.0](https://github.com/go-openapi/spec/blob/v0.21.0/LICENSE))
|
||||
- [github.com/go-openapi/strfmt](https://pkg.go.dev/github.com/go-openapi/strfmt) ([Apache-2.0](https://github.com/go-openapi/strfmt/blob/v0.23.0/LICENSE))
|
||||
- [github.com/go-openapi/swag](https://pkg.go.dev/github.com/go-openapi/swag) ([Apache-2.0](https://github.com/go-openapi/swag/blob/v0.24.1/LICENSE))
|
||||
- [github.com/go-openapi/swag/cmdutils](https://pkg.go.dev/github.com/go-openapi/swag/cmdutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/cmdutils/v0.24.0/cmdutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/conv](https://pkg.go.dev/github.com/go-openapi/swag/conv) ([Apache-2.0](https://github.com/go-openapi/swag/blob/conv/v0.24.0/conv/LICENSE))
|
||||
- [github.com/go-openapi/swag/fileutils](https://pkg.go.dev/github.com/go-openapi/swag/fileutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/fileutils/v0.24.0/fileutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonname](https://pkg.go.dev/github.com/go-openapi/swag/jsonname) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonname/v0.24.0/jsonname/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonutils](https://pkg.go.dev/github.com/go-openapi/swag/jsonutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonutils/v0.24.0/jsonutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/loading](https://pkg.go.dev/github.com/go-openapi/swag/loading) ([Apache-2.0](https://github.com/go-openapi/swag/blob/loading/v0.24.0/loading/LICENSE))
|
||||
- [github.com/go-openapi/swag/mangling](https://pkg.go.dev/github.com/go-openapi/swag/mangling) ([Apache-2.0](https://github.com/go-openapi/swag/blob/mangling/v0.24.0/mangling/LICENSE))
|
||||
- [github.com/go-openapi/swag/netutils](https://pkg.go.dev/github.com/go-openapi/swag/netutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/netutils/v0.24.0/netutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/stringutils](https://pkg.go.dev/github.com/go-openapi/swag/stringutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/stringutils/v0.24.0/stringutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/typeutils](https://pkg.go.dev/github.com/go-openapi/swag/typeutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/typeutils/v0.24.0/typeutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/yamlutils](https://pkg.go.dev/github.com/go-openapi/swag/yamlutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/yamlutils/v0.24.0/yamlutils/LICENSE))
|
||||
- [github.com/go-openapi/validate](https://pkg.go.dev/github.com/go-openapi/validate) ([Apache-2.0](https://github.com/go-openapi/validate/blob/v0.24.0/LICENSE))
|
||||
- [github.com/go-openapi/analysis](https://pkg.go.dev/github.com/go-openapi/analysis) ([Apache-2.0](https://github.com/go-openapi/analysis/blob/v0.24.1/LICENSE))
|
||||
- [github.com/go-openapi/errors](https://pkg.go.dev/github.com/go-openapi/errors) ([Apache-2.0](https://github.com/go-openapi/errors/blob/v0.22.4/LICENSE))
|
||||
- [github.com/go-openapi/jsonpointer](https://pkg.go.dev/github.com/go-openapi/jsonpointer) ([Apache-2.0](https://github.com/go-openapi/jsonpointer/blob/v0.22.1/LICENSE))
|
||||
- [github.com/go-openapi/jsonreference](https://pkg.go.dev/github.com/go-openapi/jsonreference) ([Apache-2.0](https://github.com/go-openapi/jsonreference/blob/v0.21.3/LICENSE))
|
||||
- [github.com/go-openapi/loads](https://pkg.go.dev/github.com/go-openapi/loads) ([Apache-2.0](https://github.com/go-openapi/loads/blob/v0.23.2/LICENSE))
|
||||
- [github.com/go-openapi/runtime](https://pkg.go.dev/github.com/go-openapi/runtime) ([Apache-2.0](https://github.com/go-openapi/runtime/blob/v0.29.2/LICENSE))
|
||||
- [github.com/go-openapi/runtime/middleware/denco](https://pkg.go.dev/github.com/go-openapi/runtime/middleware/denco) ([MIT](https://github.com/go-openapi/runtime/blob/v0.29.2/middleware/denco/LICENSE))
|
||||
- [github.com/go-openapi/spec](https://pkg.go.dev/github.com/go-openapi/spec) ([Apache-2.0](https://github.com/go-openapi/spec/blob/v0.22.1/LICENSE))
|
||||
- [github.com/go-openapi/strfmt](https://pkg.go.dev/github.com/go-openapi/strfmt) ([Apache-2.0](https://github.com/go-openapi/strfmt/blob/v0.25.0/LICENSE))
|
||||
- [github.com/go-openapi/swag](https://pkg.go.dev/github.com/go-openapi/swag) ([Apache-2.0](https://github.com/go-openapi/swag/blob/v0.25.4/LICENSE))
|
||||
- [github.com/go-openapi/swag/cmdutils](https://pkg.go.dev/github.com/go-openapi/swag/cmdutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/cmdutils/v0.25.4/cmdutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/conv](https://pkg.go.dev/github.com/go-openapi/swag/conv) ([Apache-2.0](https://github.com/go-openapi/swag/blob/conv/v0.25.4/conv/LICENSE))
|
||||
- [github.com/go-openapi/swag/fileutils](https://pkg.go.dev/github.com/go-openapi/swag/fileutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/fileutils/v0.25.4/fileutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonname](https://pkg.go.dev/github.com/go-openapi/swag/jsonname) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonname/v0.25.4/jsonname/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonutils](https://pkg.go.dev/github.com/go-openapi/swag/jsonutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonutils/v0.25.4/jsonutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/loading](https://pkg.go.dev/github.com/go-openapi/swag/loading) ([Apache-2.0](https://github.com/go-openapi/swag/blob/loading/v0.25.4/loading/LICENSE))
|
||||
- [github.com/go-openapi/swag/mangling](https://pkg.go.dev/github.com/go-openapi/swag/mangling) ([Apache-2.0](https://github.com/go-openapi/swag/blob/mangling/v0.25.4/mangling/LICENSE))
|
||||
- [github.com/go-openapi/swag/netutils](https://pkg.go.dev/github.com/go-openapi/swag/netutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/netutils/v0.25.4/netutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/stringutils](https://pkg.go.dev/github.com/go-openapi/swag/stringutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/stringutils/v0.25.4/stringutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/typeutils](https://pkg.go.dev/github.com/go-openapi/swag/typeutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/typeutils/v0.25.4/typeutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/yamlutils](https://pkg.go.dev/github.com/go-openapi/swag/yamlutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/yamlutils/v0.25.4/yamlutils/LICENSE))
|
||||
- [github.com/go-openapi/validate](https://pkg.go.dev/github.com/go-openapi/validate) ([Apache-2.0](https://github.com/go-openapi/validate/blob/v0.25.1/LICENSE))
|
||||
- [github.com/go-viper/mapstructure/v2](https://pkg.go.dev/github.com/go-viper/mapstructure/v2) ([MIT](https://github.com/go-viper/mapstructure/blob/v2.4.0/LICENSE))
|
||||
- [github.com/godbus/dbus/v5](https://pkg.go.dev/github.com/godbus/dbus/v5) ([BSD-2-Clause](https://github.com/godbus/dbus/blob/v5.1.0/LICENSE))
|
||||
- [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/2c02b8208cf8/LICENSE))
|
||||
- [github.com/golang/snappy](https://pkg.go.dev/github.com/golang/snappy) ([BSD-3-Clause](https://github.com/golang/snappy/blob/v1.0.0/LICENSE))
|
||||
- [github.com/google/certificate-transparency-go](https://pkg.go.dev/github.com/google/certificate-transparency-go) ([Apache-2.0](https://github.com/google/certificate-transparency-go/blob/v1.3.2/LICENSE))
|
||||
- [github.com/google/go-cmp/cmp](https://pkg.go.dev/github.com/google/go-cmp/cmp) ([BSD-3-Clause](https://github.com/google/go-cmp/blob/v0.7.0/LICENSE))
|
||||
- [github.com/google/go-containerregistry](https://pkg.go.dev/github.com/google/go-containerregistry) ([Apache-2.0](https://github.com/google/go-containerregistry/blob/v0.20.7/LICENSE))
|
||||
- [github.com/google/s2a-go](https://pkg.go.dev/github.com/google/s2a-go) ([Apache-2.0](https://github.com/google/s2a-go/blob/v0.1.9/LICENSE.md))
|
||||
- [github.com/google/shlex](https://pkg.go.dev/github.com/google/shlex) ([Apache-2.0](https://github.com/google/shlex/blob/e7afc7fbc510/COPYING))
|
||||
- [github.com/google/uuid](https://pkg.go.dev/github.com/google/uuid) ([BSD-3-Clause](https://github.com/google/uuid/blob/v1.6.0/LICENSE))
|
||||
- [github.com/googleapis/enterprise-certificate-proxy/client](https://pkg.go.dev/github.com/googleapis/enterprise-certificate-proxy/client) ([Apache-2.0](https://github.com/googleapis/enterprise-certificate-proxy/blob/v0.3.6/LICENSE))
|
||||
- [github.com/googleapis/gax-go/v2](https://pkg.go.dev/github.com/googleapis/gax-go/v2) ([BSD-3-Clause](https://github.com/googleapis/gax-go/blob/v2.15.0/v2/LICENSE))
|
||||
- [github.com/gorilla/css/scanner](https://pkg.go.dev/github.com/gorilla/css/scanner) ([BSD-3-Clause](https://github.com/gorilla/css/blob/v1.0.1/LICENSE))
|
||||
- [github.com/gorilla/websocket](https://pkg.go.dev/github.com/gorilla/websocket) ([BSD-2-Clause](https://github.com/gorilla/websocket/blob/v1.5.3/LICENSE))
|
||||
- [github.com/grpc-ecosystem/grpc-gateway/v2](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/v2) ([BSD-3-Clause](https://github.com/grpc-ecosystem/grpc-gateway/blob/v2.27.2/LICENSE))
|
||||
- [github.com/grpc-ecosystem/grpc-gateway/v2](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/v2) ([BSD-3-Clause](https://github.com/grpc-ecosystem/grpc-gateway/blob/v2.27.3/LICENSE))
|
||||
- [github.com/hashicorp/go-version](https://pkg.go.dev/github.com/hashicorp/go-version) ([MPL-2.0](https://github.com/hashicorp/go-version/blob/v1.8.0/LICENSE))
|
||||
- [github.com/hashicorp/golang-lru/v2](https://pkg.go.dev/github.com/hashicorp/golang-lru/v2) ([MPL-2.0](https://github.com/hashicorp/golang-lru/blob/v2.0.7/LICENSE))
|
||||
- [github.com/hashicorp/golang-lru/v2/simplelru](https://pkg.go.dev/github.com/hashicorp/golang-lru/v2/simplelru) ([BSD-3-Clause](https://github.com/hashicorp/golang-lru/blob/v2.0.7/simplelru/LICENSE_list))
|
||||
- [github.com/henvic/httpretty](https://pkg.go.dev/github.com/henvic/httpretty) ([MIT](https://github.com/henvic/httpretty/blob/v0.1.4/LICENSE.md))
|
||||
- [github.com/huandu/xstrings](https://pkg.go.dev/github.com/huandu/xstrings) ([MIT](https://github.com/huandu/xstrings/blob/v1.5.0/LICENSE))
|
||||
- [github.com/in-toto/attestation/go/v1](https://pkg.go.dev/github.com/in-toto/attestation/go/v1) ([Apache-2.0](https://github.com/in-toto/attestation/blob/v1.1.2/LICENSE))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto) ([Apache-2.0](https://github.com/in-toto/in-toto-golang/blob/v0.9.0/LICENSE))
|
||||
- [github.com/in-toto/attestation/go/v1](https://pkg.go.dev/github.com/in-toto/attestation/go/v1) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1) ([Unknown](Unknown))
|
||||
- [github.com/itchyny/gojq](https://pkg.go.dev/github.com/itchyny/gojq) ([MIT](https://github.com/itchyny/gojq/blob/v0.12.17/LICENSE))
|
||||
- [github.com/itchyny/timefmt-go](https://pkg.go.dev/github.com/itchyny/timefmt-go) ([MIT](https://github.com/itchyny/timefmt-go/blob/v0.1.6/LICENSE))
|
||||
- [github.com/jedisct1/go-minisign](https://pkg.go.dev/github.com/jedisct1/go-minisign) ([MIT](https://github.com/jedisct1/go-minisign/blob/d2f9f49435c7/LICENSE))
|
||||
- [github.com/joho/godotenv](https://pkg.go.dev/github.com/joho/godotenv) ([MIT](https://github.com/joho/godotenv/blob/v1.5.1/LICENCE))
|
||||
- [github.com/josharian/intern](https://pkg.go.dev/github.com/josharian/intern) ([MIT](https://github.com/josharian/intern/blob/v1.0.0/license.md))
|
||||
- [github.com/kballard/go-shellquote](https://pkg.go.dev/github.com/kballard/go-shellquote) ([MIT](https://github.com/kballard/go-shellquote/blob/95032a82bc51/LICENSE))
|
||||
- [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([MIT](https://github.com/klauspost/compress/blob/v1.18.1/LICENSE))
|
||||
- [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.18.1/LICENSE))
|
||||
- [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.18.1/LICENSE))
|
||||
- [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.18.1/internal/snapref/LICENSE))
|
||||
- [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.18.1/zstd/internal/xxhash/LICENSE.txt))
|
||||
- [github.com/letsencrypt/boulder](https://pkg.go.dev/github.com/letsencrypt/boulder) ([MPL-2.0](https://github.com/letsencrypt/boulder/blob/v0.20250630.0/LICENSE.txt))
|
||||
- [github.com/lucasb-eyer/go-colorful](https://pkg.go.dev/github.com/lucasb-eyer/go-colorful) ([MIT](https://github.com/lucasb-eyer/go-colorful/blob/v1.3.0/LICENSE))
|
||||
- [github.com/mailru/easyjson](https://pkg.go.dev/github.com/mailru/easyjson) ([MIT](https://github.com/mailru/easyjson/blob/v0.9.0/LICENSE))
|
||||
- [github.com/mattn/go-colorable](https://pkg.go.dev/github.com/mattn/go-colorable) ([MIT](https://github.com/mattn/go-colorable/blob/v0.1.14/LICENSE))
|
||||
- [github.com/mattn/go-isatty](https://pkg.go.dev/github.com/mattn/go-isatty) ([MIT](https://github.com/mattn/go-isatty/blob/v0.0.20/LICENSE))
|
||||
- [github.com/mattn/go-runewidth](https://pkg.go.dev/github.com/mattn/go-runewidth) ([MIT](https://github.com/mattn/go-runewidth/blob/v0.0.16/LICENSE))
|
||||
- [github.com/mattn/go-runewidth](https://pkg.go.dev/github.com/mattn/go-runewidth) ([MIT](https://github.com/mattn/go-runewidth/blob/v0.0.17/LICENSE))
|
||||
- [github.com/mgutz/ansi](https://pkg.go.dev/github.com/mgutz/ansi) ([MIT](https://github.com/mgutz/ansi/blob/d51e80ef957d/LICENSE))
|
||||
- [github.com/microcosm-cc/bluemonday](https://pkg.go.dev/github.com/microcosm-cc/bluemonday) ([BSD-3-Clause](https://github.com/microcosm-cc/bluemonday/blob/v1.0.27/LICENSE.md))
|
||||
- [github.com/microsoft/dev-tunnels/go/tunnels](https://pkg.go.dev/github.com/microsoft/dev-tunnels/go/tunnels) ([MIT](https://github.com/microsoft/dev-tunnels/blob/v0.1.19/LICENSE))
|
||||
- [github.com/mitchellh/copystructure](https://pkg.go.dev/github.com/mitchellh/copystructure) ([MIT](https://github.com/mitchellh/copystructure/blob/v1.2.0/LICENSE))
|
||||
- [github.com/mitchellh/go-homedir](https://pkg.go.dev/github.com/mitchellh/go-homedir) ([MIT](https://github.com/mitchellh/go-homedir/blob/v1.1.0/LICENSE))
|
||||
- [github.com/mitchellh/hashstructure/v2](https://pkg.go.dev/github.com/mitchellh/hashstructure/v2) ([MIT](https://github.com/mitchellh/hashstructure/blob/v2.0.2/LICENSE))
|
||||
- [github.com/mitchellh/mapstructure](https://pkg.go.dev/github.com/mitchellh/mapstructure) ([MIT](https://github.com/mitchellh/mapstructure/blob/v1.5.0/LICENSE))
|
||||
- [github.com/mitchellh/reflectwalk](https://pkg.go.dev/github.com/mitchellh/reflectwalk) ([MIT](https://github.com/mitchellh/reflectwalk/blob/v1.0.2/LICENSE))
|
||||
- [github.com/muesli/ansi](https://pkg.go.dev/github.com/muesli/ansi) ([MIT](https://github.com/muesli/ansi/blob/276c6243b2f6/LICENSE))
|
||||
- [github.com/muesli/cancelreader](https://pkg.go.dev/github.com/muesli/cancelreader) ([MIT](https://github.com/muesli/cancelreader/blob/v0.2.2/LICENSE))
|
||||
|
|
@ -157,83 +128,60 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/opencontainers/go-digest](https://pkg.go.dev/github.com/opencontainers/go-digest) ([Apache-2.0](https://github.com/opencontainers/go-digest/blob/v1.0.0/LICENSE))
|
||||
- [github.com/opencontainers/image-spec/specs-go](https://pkg.go.dev/github.com/opencontainers/image-spec/specs-go) ([Apache-2.0](https://github.com/opencontainers/image-spec/blob/v1.1.1/LICENSE))
|
||||
- [github.com/opentracing/opentracing-go](https://pkg.go.dev/github.com/opentracing/opentracing-go) ([Apache-2.0](https://github.com/opentracing/opentracing-go/blob/v1.2.0/LICENSE))
|
||||
- [github.com/pelletier/go-toml/v2](https://pkg.go.dev/github.com/pelletier/go-toml/v2) ([MIT](https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE))
|
||||
- [github.com/pkg/errors](https://pkg.go.dev/github.com/pkg/errors) ([BSD-2-Clause](https://github.com/pkg/errors/blob/v0.9.1/LICENSE))
|
||||
- [github.com/pmezard/go-difflib/difflib](https://pkg.go.dev/github.com/pmezard/go-difflib/difflib) ([BSD-3-Clause](https://github.com/pmezard/go-difflib/blob/5d4384ee4fb2/LICENSE))
|
||||
- [github.com/rivo/tview](https://pkg.go.dev/github.com/rivo/tview) ([MIT](https://github.com/rivo/tview/blob/v0.42.0/LICENSE.txt))
|
||||
- [github.com/rivo/uniseg](https://pkg.go.dev/github.com/rivo/uniseg) ([MIT](https://github.com/rivo/uniseg/blob/v0.4.7/LICENSE.txt))
|
||||
- [github.com/rodaine/table](https://pkg.go.dev/github.com/rodaine/table) ([MIT](https://github.com/rodaine/table/blob/v1.3.0/license))
|
||||
- [github.com/russross/blackfriday/v2](https://pkg.go.dev/github.com/russross/blackfriday/v2) ([BSD-2-Clause](https://github.com/russross/blackfriday/blob/v2.1.0/LICENSE.txt))
|
||||
- [github.com/sagikazarmark/locafero](https://pkg.go.dev/github.com/sagikazarmark/locafero) ([MIT](https://github.com/sagikazarmark/locafero/blob/v0.9.0/LICENSE))
|
||||
- [github.com/sassoftware/relic/lib](https://pkg.go.dev/github.com/sassoftware/relic/lib) ([Apache-2.0](https://github.com/sassoftware/relic/blob/v7.2.1/LICENSE))
|
||||
- [github.com/secure-systems-lab/go-securesystemslib](https://pkg.go.dev/github.com/secure-systems-lab/go-securesystemslib) ([MIT](https://github.com/secure-systems-lab/go-securesystemslib/blob/v0.9.1/LICENSE))
|
||||
- [github.com/shibumi/go-pathspec](https://pkg.go.dev/github.com/shibumi/go-pathspec) ([Apache-2.0](https://github.com/shibumi/go-pathspec/blob/v1.3.0/LICENSE))
|
||||
- [github.com/shopspring/decimal](https://pkg.go.dev/github.com/shopspring/decimal) ([MIT](https://github.com/shopspring/decimal/blob/v1.4.0/LICENSE))
|
||||
- [github.com/shurcooL/githubv4](https://pkg.go.dev/github.com/shurcooL/githubv4) ([MIT](https://github.com/shurcooL/githubv4/blob/48295856cce7/LICENSE))
|
||||
- [github.com/shurcooL/graphql](https://pkg.go.dev/github.com/shurcooL/graphql) ([MIT](https://github.com/shurcooL/graphql/blob/ed46e5a46466/LICENSE))
|
||||
- [github.com/sigstore/protobuf-specs/gen/pb-go](https://pkg.go.dev/github.com/sigstore/protobuf-specs/gen/pb-go) ([Apache-2.0](https://github.com/sigstore/protobuf-specs/blob/v0.5.0/LICENSE))
|
||||
- [github.com/sigstore/rekor-tiles](https://pkg.go.dev/github.com/sigstore/rekor-tiles) ([Apache-2.0](https://github.com/sigstore/rekor-tiles/blob/v0.1.11/LICENSE))
|
||||
- [github.com/sigstore/rekor/pkg](https://pkg.go.dev/github.com/sigstore/rekor/pkg) ([Apache-2.0](https://github.com/sigstore/rekor/blob/v1.4.2/LICENSE))
|
||||
- [github.com/sigstore/sigstore-go/pkg](https://pkg.go.dev/github.com/sigstore/sigstore-go/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore-go/blob/v1.1.3/LICENSE))
|
||||
- [github.com/sigstore/sigstore/pkg](https://pkg.go.dev/github.com/sigstore/sigstore/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore/blob/181c5d3339b3/LICENSE))
|
||||
- [github.com/sigstore/timestamp-authority/pkg/verification](https://pkg.go.dev/github.com/sigstore/timestamp-authority/pkg/verification) ([Apache-2.0](https://github.com/sigstore/timestamp-authority/blob/v1.2.9/LICENSE))
|
||||
- [github.com/sigstore/rekor-tiles/v2](https://pkg.go.dev/github.com/sigstore/rekor-tiles/v2) ([Apache-2.0](https://github.com/sigstore/rekor-tiles/blob/v2.0.1/LICENSE))
|
||||
- [github.com/sigstore/rekor/pkg](https://pkg.go.dev/github.com/sigstore/rekor/pkg) ([Apache-2.0](https://github.com/sigstore/rekor/blob/v1.4.3/LICENSE))
|
||||
- [github.com/sigstore/sigstore-go/pkg](https://pkg.go.dev/github.com/sigstore/sigstore-go/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore-go/blob/v1.1.4/LICENSE))
|
||||
- [github.com/sigstore/sigstore/pkg](https://pkg.go.dev/github.com/sigstore/sigstore/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore/blob/v1.10.0/LICENSE))
|
||||
- [github.com/sigstore/timestamp-authority/v2/pkg/verification](https://pkg.go.dev/github.com/sigstore/timestamp-authority/v2/pkg/verification) ([Apache-2.0](https://github.com/sigstore/timestamp-authority/blob/v2.0.3/LICENSE))
|
||||
- [github.com/sirupsen/logrus](https://pkg.go.dev/github.com/sirupsen/logrus) ([MIT](https://github.com/sirupsen/logrus/blob/v1.9.3/LICENSE))
|
||||
- [github.com/sourcegraph/conc](https://pkg.go.dev/github.com/sourcegraph/conc) ([MIT](https://github.com/sourcegraph/conc/blob/v0.3.0/LICENSE))
|
||||
- [github.com/spf13/afero](https://pkg.go.dev/github.com/spf13/afero) ([Apache-2.0](https://github.com/spf13/afero/blob/v1.14.0/LICENSE.txt))
|
||||
- [github.com/spf13/cast](https://pkg.go.dev/github.com/spf13/cast) ([MIT](https://github.com/spf13/cast/blob/v1.9.2/LICENSE))
|
||||
- [github.com/spf13/cast](https://pkg.go.dev/github.com/spf13/cast) ([MIT](https://github.com/spf13/cast/blob/v1.10.0/LICENSE))
|
||||
- [github.com/spf13/cobra](https://pkg.go.dev/github.com/spf13/cobra) ([Apache-2.0](https://github.com/spf13/cobra/blob/v1.10.2/LICENSE.txt))
|
||||
- [github.com/spf13/pflag](https://pkg.go.dev/github.com/spf13/pflag) ([BSD-3-Clause](https://github.com/spf13/pflag/blob/v1.0.10/LICENSE))
|
||||
- [github.com/spf13/viper](https://pkg.go.dev/github.com/spf13/viper) ([MIT](https://github.com/spf13/viper/blob/v1.20.1/LICENSE))
|
||||
- [github.com/spiffe/go-spiffe/v2](https://pkg.go.dev/github.com/spiffe/go-spiffe/v2) ([Apache-2.0](https://github.com/spiffe/go-spiffe/blob/v2.6.0/LICENSE))
|
||||
- [github.com/stretchr/objx](https://pkg.go.dev/github.com/stretchr/objx) ([MIT](https://github.com/stretchr/objx/blob/v0.5.2/LICENSE))
|
||||
- [github.com/stretchr/testify](https://pkg.go.dev/github.com/stretchr/testify) ([MIT](https://github.com/stretchr/testify/blob/v1.11.1/LICENSE))
|
||||
- [github.com/subosito/gotenv](https://pkg.go.dev/github.com/subosito/gotenv) ([MIT](https://github.com/subosito/gotenv/blob/v1.6.0/LICENSE))
|
||||
- [github.com/theupdateframework/go-tuf](https://pkg.go.dev/github.com/theupdateframework/go-tuf) ([BSD-3-Clause](https://github.com/theupdateframework/go-tuf/blob/v0.7.0/LICENSE))
|
||||
- [github.com/theupdateframework/go-tuf/v2/metadata](https://pkg.go.dev/github.com/theupdateframework/go-tuf/v2/metadata) ([Apache-2.0](https://github.com/theupdateframework/go-tuf/blob/v2.3.0/LICENSE))
|
||||
- [github.com/thlib/go-timezone-local/tzlocal](https://pkg.go.dev/github.com/thlib/go-timezone-local/tzlocal) ([Unlicense](https://github.com/thlib/go-timezone-local/blob/v0.0.6/LICENSE))
|
||||
- [github.com/titanous/rocacheck](https://pkg.go.dev/github.com/titanous/rocacheck) ([MIT](https://github.com/titanous/rocacheck/blob/afe73141d399/LICENSE))
|
||||
- [github.com/transparency-dev/formats](https://pkg.go.dev/github.com/transparency-dev/formats) ([Apache-2.0](https://github.com/transparency-dev/formats/blob/bb8ad4d07c26/LICENSE))
|
||||
- [github.com/transparency-dev/formats/log](https://pkg.go.dev/github.com/transparency-dev/formats/log) ([Apache-2.0](https://github.com/transparency-dev/formats/blob/404c0d5b696c/LICENSE))
|
||||
- [github.com/transparency-dev/merkle](https://pkg.go.dev/github.com/transparency-dev/merkle) ([Apache-2.0](https://github.com/transparency-dev/merkle/blob/v0.0.2/LICENSE))
|
||||
- [github.com/transparency-dev/tessera](https://pkg.go.dev/github.com/transparency-dev/tessera) ([Apache-2.0](https://github.com/transparency-dev/tessera/blob/v1.0.0-rc3/LICENSE))
|
||||
- [github.com/vbatts/tar-split/archive/tar](https://pkg.go.dev/github.com/vbatts/tar-split/archive/tar) ([BSD-3-Clause](https://github.com/vbatts/tar-split/blob/v0.12.2/LICENSE))
|
||||
- [github.com/vmihailenco/msgpack/v5](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5) ([BSD-2-Clause](https://github.com/vmihailenco/msgpack/blob/v5.4.1/LICENSE))
|
||||
- [github.com/vmihailenco/tagparser/v2](https://pkg.go.dev/github.com/vmihailenco/tagparser/v2) ([BSD-2-Clause](https://github.com/vmihailenco/tagparser/blob/v2.0.0/LICENSE))
|
||||
- [github.com/xo/terminfo](https://pkg.go.dev/github.com/xo/terminfo) ([MIT](https://github.com/xo/terminfo/blob/abceb7e1c41e/LICENSE))
|
||||
- [github.com/yuin/goldmark](https://pkg.go.dev/github.com/yuin/goldmark) ([MIT](https://github.com/yuin/goldmark/blob/v1.7.13/LICENSE))
|
||||
- [github.com/yuin/goldmark](https://pkg.go.dev/github.com/yuin/goldmark) ([MIT](https://github.com/yuin/goldmark/blob/v1.7.16/LICENSE))
|
||||
- [github.com/yuin/goldmark-emoji](https://pkg.go.dev/github.com/yuin/goldmark-emoji) ([MIT](https://github.com/yuin/goldmark-emoji/blob/v1.0.6/LICENSE))
|
||||
- [github.com/zalando/go-keyring](https://pkg.go.dev/github.com/zalando/go-keyring) ([MIT](https://github.com/zalando/go-keyring/blob/v0.2.6/LICENSE))
|
||||
- [go.mongodb.org/mongo-driver](https://pkg.go.dev/go.mongodb.org/mongo-driver) ([Apache-2.0](https://github.com/mongodb/mongo-go-driver/blob/v1.17.4/LICENSE))
|
||||
- [go.opencensus.io](https://pkg.go.dev/go.opencensus.io) ([Apache-2.0](https://github.com/census-instrumentation/opencensus-go/blob/v0.24.0/LICENSE))
|
||||
- [go.mongodb.org/mongo-driver](https://pkg.go.dev/go.mongodb.org/mongo-driver) ([Apache-2.0](https://github.com/mongodb/mongo-go-driver/blob/v1.17.6/LICENSE))
|
||||
- [go.opentelemetry.io/auto/sdk](https://pkg.go.dev/go.opentelemetry.io/auto/sdk) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-instrumentation/blob/sdk/v1.2.1/sdk/LICENSE))
|
||||
- [go.opentelemetry.io/contrib/detectors/gcp](https://pkg.go.dev/go.opentelemetry.io/contrib/detectors/gcp) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/detectors/gcp/v1.38.0/detectors/gcp/LICENSE))
|
||||
- [go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc](https://pkg.go.dev/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/instrumentation/google.golang.org/grpc/otelgrpc/v0.61.0/instrumentation/google.golang.org/grpc/otelgrpc/LICENSE))
|
||||
- [go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp](https://pkg.go.dev/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/instrumentation/net/http/otelhttp/v0.61.0/instrumentation/net/http/otelhttp/LICENSE))
|
||||
- [go.opentelemetry.io/otel](https://pkg.go.dev/go.opentelemetry.io/otel) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/v1.38.0/LICENSE))
|
||||
- [go.opentelemetry.io/otel](https://pkg.go.dev/go.opentelemetry.io/otel) ([BSD-3-Clause](https://github.com/open-telemetry/opentelemetry-go/blob/v1.38.0/LICENSE))
|
||||
- [go.opentelemetry.io/otel/metric](https://pkg.go.dev/go.opentelemetry.io/otel/metric) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/metric/v1.38.0/metric/LICENSE))
|
||||
- [go.opentelemetry.io/otel/sdk](https://pkg.go.dev/go.opentelemetry.io/otel/sdk) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/sdk/v1.38.0/sdk/LICENSE))
|
||||
- [go.opentelemetry.io/otel/sdk/metric](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/sdk/metric/v1.38.0/sdk/metric/LICENSE))
|
||||
- [go.opentelemetry.io/otel/metric](https://pkg.go.dev/go.opentelemetry.io/otel/metric) ([BSD-3-Clause](https://github.com/open-telemetry/opentelemetry-go/blob/metric/v1.38.0/metric/LICENSE))
|
||||
- [go.opentelemetry.io/otel/trace](https://pkg.go.dev/go.opentelemetry.io/otel/trace) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/trace/v1.38.0/trace/LICENSE))
|
||||
- [go.uber.org/multierr](https://pkg.go.dev/go.uber.org/multierr) ([MIT](https://github.com/uber-go/multierr/blob/v1.11.0/LICENSE.txt))
|
||||
- [go.uber.org/zap](https://pkg.go.dev/go.uber.org/zap) ([MIT](https://github.com/uber-go/zap/blob/v1.27.0/LICENSE))
|
||||
- [go.opentelemetry.io/otel/trace](https://pkg.go.dev/go.opentelemetry.io/otel/trace) ([BSD-3-Clause](https://github.com/open-telemetry/opentelemetry-go/blob/trace/v1.38.0/trace/LICENSE))
|
||||
- [go.yaml.in/yaml/v3](https://pkg.go.dev/go.yaml.in/yaml/v3) ([MIT](https://github.com/yaml/go-yaml/blob/v3.0.4/LICENSE))
|
||||
- [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.46.0:LICENSE))
|
||||
- [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/b7579e27:LICENSE))
|
||||
- [golang.org/x/mod](https://pkg.go.dev/golang.org/x/mod) ([BSD-3-Clause](https://cs.opensource.google/go/x/mod/+/v0.30.0:LICENSE))
|
||||
- [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.47.0:LICENSE))
|
||||
- [golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) ([BSD-3-Clause](https://cs.opensource.google/go/x/oauth2/+/v0.33.0:LICENSE))
|
||||
- [golang.org/x/sync](https://pkg.go.dev/golang.org/x/sync) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.19.0:LICENSE))
|
||||
- [golang.org/x/sync/errgroup](https://pkg.go.dev/golang.org/x/sync/errgroup) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.19.0:LICENSE))
|
||||
- [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.39.0:LICENSE))
|
||||
- [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.38.0:LICENSE))
|
||||
- [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.32.0:LICENSE))
|
||||
- [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.12.0:LICENSE))
|
||||
- [google.golang.org/api](https://pkg.go.dev/google.golang.org/api) ([BSD-3-Clause](https://github.com/googleapis/google-api-go-client/blob/v0.248.0/LICENSE))
|
||||
- [google.golang.org/api/internal/third_party/uritemplates](https://pkg.go.dev/google.golang.org/api/internal/third_party/uritemplates) ([BSD-3-Clause](https://github.com/googleapis/google-api-go-client/blob/v0.248.0/internal/third_party/uritemplates/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/api](https://pkg.go.dev/google.golang.org/genproto/googleapis/api) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/3a174f9686a8/googleapis/api/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/rpc](https://pkg.go.dev/google.golang.org/genproto/googleapis/rpc) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/3a174f9686a8/googleapis/rpc/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/type](https://pkg.go.dev/google.golang.org/genproto/googleapis/type) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/513f23925822/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/rpc/status](https://pkg.go.dev/google.golang.org/genproto/googleapis/rpc/status) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/f26f9409b101/googleapis/rpc/LICENSE))
|
||||
- [google.golang.org/grpc](https://pkg.go.dev/google.golang.org/grpc) ([Apache-2.0](https://github.com/grpc/grpc-go/blob/v1.77.0/LICENSE))
|
||||
- [google.golang.org/protobuf](https://pkg.go.dev/google.golang.org/protobuf) ([BSD-3-Clause](https://github.com/protocolbuffers/protobuf-go/blob/v1.36.10/LICENSE))
|
||||
- [gopkg.in/yaml.v3](https://pkg.go.dev/gopkg.in/yaml.v3) ([MIT](https://github.com/go-yaml/yaml/blob/v3.0.1/LICENSE))
|
||||
- [k8s.io/klog/v2](https://pkg.go.dev/k8s.io/klog/v2) ([Apache-2.0](https://github.com/kubernetes/klog/blob/v2.130.1/LICENSE))
|
||||
|
||||
[cli/cli]: https://github.com/cli/cli
|
||||
|
|
|
|||
|
|
@ -7,23 +7,9 @@ The following open source dependencies are used to build the [cli/cli][] GitHub
|
|||
Some packages may only be included on certain architectures or operating systems.
|
||||
|
||||
|
||||
- [cel.dev/expr](https://pkg.go.dev/cel.dev/expr) ([Apache-2.0](https://github.com/google/cel-spec/blob/v0.24.0/LICENSE))
|
||||
- [cloud.google.com/go](https://pkg.go.dev/cloud.google.com/go) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/v0.121.6/LICENSE))
|
||||
- [cloud.google.com/go/auth](https://pkg.go.dev/cloud.google.com/go/auth) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/auth/v0.16.5/auth/LICENSE))
|
||||
- [cloud.google.com/go/auth/oauth2adapt](https://pkg.go.dev/cloud.google.com/go/auth/oauth2adapt) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/auth/oauth2adapt/v0.2.8/auth/oauth2adapt/LICENSE))
|
||||
- [cloud.google.com/go/compute/metadata](https://pkg.go.dev/cloud.google.com/go/compute/metadata) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/compute/metadata/v0.9.0/compute/metadata/LICENSE))
|
||||
- [cloud.google.com/go/iam](https://pkg.go.dev/cloud.google.com/go/iam) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/iam/v1.5.2/iam/LICENSE))
|
||||
- [cloud.google.com/go/longrunning](https://pkg.go.dev/cloud.google.com/go/longrunning) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/longrunning/v0.6.7/longrunning/LICENSE))
|
||||
- [cloud.google.com/go/monitoring](https://pkg.go.dev/cloud.google.com/go/monitoring) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/monitoring/v1.24.2/monitoring/LICENSE))
|
||||
- [cloud.google.com/go/spanner](https://pkg.go.dev/cloud.google.com/go/spanner) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/spanner/v1.84.1/spanner/LICENSE))
|
||||
- [cloud.google.com/go/storage](https://pkg.go.dev/cloud.google.com/go/storage) ([Apache-2.0](https://github.com/googleapis/google-cloud-go/blob/storage/v1.56.1/storage/LICENSE))
|
||||
- [dario.cat/mergo](https://pkg.go.dev/dario.cat/mergo) ([BSD-3-Clause](https://github.com/imdario/mergo/blob/v1.0.2/LICENSE))
|
||||
- [github.com/AlecAivazis/survey/v2](https://pkg.go.dev/github.com/AlecAivazis/survey/v2) ([MIT](https://github.com/AlecAivazis/survey/blob/v2.3.7/LICENSE))
|
||||
- [github.com/AlecAivazis/survey/v2/terminal](https://pkg.go.dev/github.com/AlecAivazis/survey/v2/terminal) ([MIT](https://github.com/AlecAivazis/survey/blob/v2.3.7/terminal/LICENSE.txt))
|
||||
- [github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp](https://pkg.go.dev/github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp) ([Apache-2.0](https://github.com/GoogleCloudPlatform/grpc-gcp-go/blob/grpcgcp/v1.5.3/grpcgcp/LICENSE))
|
||||
- [github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp](https://pkg.go.dev/github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp) ([Apache-2.0](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/detectors/gcp/v1.30.0/detectors/gcp/LICENSE))
|
||||
- [github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric](https://pkg.go.dev/github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric) ([Apache-2.0](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/exporter/metric/v0.53.0/exporter/metric/LICENSE))
|
||||
- [github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping](https://pkg.go.dev/github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping) ([Apache-2.0](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/internal/resourcemapping/v0.53.0/internal/resourcemapping/LICENSE))
|
||||
- [github.com/MakeNowJust/heredoc](https://pkg.go.dev/github.com/MakeNowJust/heredoc) ([MIT](https://github.com/MakeNowJust/heredoc/blob/v1.0.0/LICENSE))
|
||||
- [github.com/Masterminds/goutils](https://pkg.go.dev/github.com/Masterminds/goutils) ([Apache-2.0](https://github.com/Masterminds/goutils/blob/v1.1.1/LICENSE.txt))
|
||||
- [github.com/Masterminds/semver/v3](https://pkg.go.dev/github.com/Masterminds/semver/v3) ([MIT](https://github.com/Masterminds/semver/blob/v3.4.0/LICENSE.txt))
|
||||
|
|
@ -38,14 +24,13 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/catppuccin/go](https://pkg.go.dev/github.com/catppuccin/go) ([MIT](https://github.com/catppuccin/go/blob/v0.3.0/LICENSE))
|
||||
- [github.com/cenkalti/backoff/v4](https://pkg.go.dev/github.com/cenkalti/backoff/v4) ([MIT](https://github.com/cenkalti/backoff/blob/v4.3.0/LICENSE))
|
||||
- [github.com/cenkalti/backoff/v5](https://pkg.go.dev/github.com/cenkalti/backoff/v5) ([MIT](https://github.com/cenkalti/backoff/blob/v5.0.3/LICENSE))
|
||||
- [github.com/cespare/xxhash/v2](https://pkg.go.dev/github.com/cespare/xxhash/v2) ([MIT](https://github.com/cespare/xxhash/blob/v2.3.0/LICENSE.txt))
|
||||
- [github.com/charmbracelet/bubbles](https://pkg.go.dev/github.com/charmbracelet/bubbles) ([MIT](https://github.com/charmbracelet/bubbles/blob/23b8fd6302d7/LICENSE))
|
||||
- [github.com/charmbracelet/bubbletea](https://pkg.go.dev/github.com/charmbracelet/bubbletea) ([MIT](https://github.com/charmbracelet/bubbletea/blob/v1.3.6/LICENSE))
|
||||
- [github.com/charmbracelet/bubbletea](https://pkg.go.dev/github.com/charmbracelet/bubbletea) ([MIT](https://github.com/charmbracelet/bubbletea/blob/v1.3.10/LICENSE))
|
||||
- [github.com/charmbracelet/colorprofile](https://pkg.go.dev/github.com/charmbracelet/colorprofile) ([MIT](https://github.com/charmbracelet/colorprofile/blob/v0.3.1/LICENSE))
|
||||
- [github.com/charmbracelet/glamour](https://pkg.go.dev/github.com/charmbracelet/glamour) ([MIT](https://github.com/charmbracelet/glamour/blob/v0.10.0/LICENSE))
|
||||
- [github.com/charmbracelet/huh](https://pkg.go.dev/github.com/charmbracelet/huh) ([MIT](https://github.com/charmbracelet/huh/blob/v0.8.0/LICENSE))
|
||||
- [github.com/charmbracelet/lipgloss](https://pkg.go.dev/github.com/charmbracelet/lipgloss) ([MIT](https://github.com/charmbracelet/lipgloss/blob/76690c660834/LICENSE))
|
||||
- [github.com/charmbracelet/x/ansi](https://pkg.go.dev/github.com/charmbracelet/x/ansi) ([MIT](https://github.com/charmbracelet/x/blob/ansi/v0.9.3/ansi/LICENSE))
|
||||
- [github.com/charmbracelet/x/ansi](https://pkg.go.dev/github.com/charmbracelet/x/ansi) ([MIT](https://github.com/charmbracelet/x/blob/ansi/v0.10.2/ansi/LICENSE))
|
||||
- [github.com/charmbracelet/x/cellbuf](https://pkg.go.dev/github.com/charmbracelet/x/cellbuf) ([MIT](https://github.com/charmbracelet/x/blob/cellbuf/v0.0.13/cellbuf/LICENSE))
|
||||
- [github.com/charmbracelet/x/exp/slice](https://pkg.go.dev/github.com/charmbracelet/x/exp/slice) ([MIT](https://github.com/charmbracelet/x/blob/821143405392/exp/slice/LICENSE))
|
||||
- [github.com/charmbracelet/x/exp/strings](https://pkg.go.dev/github.com/charmbracelet/x/exp/strings) ([MIT](https://github.com/charmbracelet/x/blob/821143405392/exp/strings/LICENSE))
|
||||
|
|
@ -55,10 +40,9 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/cli/oauth](https://pkg.go.dev/github.com/cli/oauth) ([MIT](https://github.com/cli/oauth/blob/v1.2.1/LICENSE))
|
||||
- [github.com/cli/safeexec](https://pkg.go.dev/github.com/cli/safeexec) ([BSD-2-Clause](https://github.com/cli/safeexec/blob/v1.0.1/LICENSE))
|
||||
- [github.com/cli/shurcooL-graphql](https://pkg.go.dev/github.com/cli/shurcooL-graphql) ([MIT](https://github.com/cli/shurcooL-graphql/blob/v0.0.4/LICENSE))
|
||||
- [github.com/cncf/xds/go](https://pkg.go.dev/github.com/cncf/xds/go) ([Apache-2.0](https://github.com/cncf/xds/blob/0feb69152e9f/go/LICENSE))
|
||||
- [github.com/containerd/stargz-snapshotter/estargz](https://pkg.go.dev/github.com/containerd/stargz-snapshotter/estargz) ([Apache-2.0](https://github.com/containerd/stargz-snapshotter/blob/estargz/v0.18.1/estargz/LICENSE))
|
||||
- [github.com/cpuguy83/go-md2man/v2/md2man](https://pkg.go.dev/github.com/cpuguy83/go-md2man/v2/md2man) ([MIT](https://github.com/cpuguy83/go-md2man/blob/v2.0.7/LICENSE.md))
|
||||
- [github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer](https://pkg.go.dev/github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer) ([Apache-2.0](https://github.com/cyberphone/json-canonicalization/blob/19d51d7fe467/LICENSE))
|
||||
- [github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer](https://pkg.go.dev/github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer) ([Unknown](Unknown))
|
||||
- [github.com/danieljoos/wincred](https://pkg.go.dev/github.com/danieljoos/wincred) ([MIT](https://github.com/danieljoos/wincred/blob/v1.2.2/LICENSE))
|
||||
- [github.com/davecgh/go-spew/spew](https://pkg.go.dev/github.com/davecgh/go-spew/spew) ([ISC](https://github.com/davecgh/go-spew/blob/d8f796af33cc/LICENSE))
|
||||
- [github.com/digitorus/pkcs7](https://pkg.go.dev/github.com/digitorus/pkcs7) ([MIT](https://github.com/digitorus/pkcs7/blob/3a137a874352/LICENSE))
|
||||
|
|
@ -69,87 +53,74 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/docker/distribution/registry/client/auth/challenge](https://pkg.go.dev/github.com/docker/distribution/registry/client/auth/challenge) ([Apache-2.0](https://github.com/docker/distribution/blob/v2.8.3/LICENSE))
|
||||
- [github.com/docker/docker-credential-helpers](https://pkg.go.dev/github.com/docker/docker-credential-helpers) ([MIT](https://github.com/docker/docker-credential-helpers/blob/v0.9.3/LICENSE))
|
||||
- [github.com/dustin/go-humanize](https://pkg.go.dev/github.com/dustin/go-humanize) ([MIT](https://github.com/dustin/go-humanize/blob/v1.0.1/LICENSE))
|
||||
- [github.com/envoyproxy/go-control-plane/envoy](https://pkg.go.dev/github.com/envoyproxy/go-control-plane/envoy) ([Apache-2.0](https://github.com/envoyproxy/go-control-plane/blob/envoy/v1.35.0/envoy/LICENSE))
|
||||
- [github.com/envoyproxy/protoc-gen-validate/validate](https://pkg.go.dev/github.com/envoyproxy/protoc-gen-validate/validate) ([Apache-2.0](https://github.com/envoyproxy/protoc-gen-validate/blob/v1.2.1/LICENSE))
|
||||
- [github.com/erikgeiser/coninput](https://pkg.go.dev/github.com/erikgeiser/coninput) ([MIT](https://github.com/erikgeiser/coninput/blob/1c3628e74d0f/LICENSE))
|
||||
- [github.com/fatih/color](https://pkg.go.dev/github.com/fatih/color) ([MIT](https://github.com/fatih/color/blob/v1.18.0/LICENSE.md))
|
||||
- [github.com/felixge/httpsnoop](https://pkg.go.dev/github.com/felixge/httpsnoop) ([MIT](https://github.com/felixge/httpsnoop/blob/v1.0.4/LICENSE.txt))
|
||||
- [github.com/fsnotify/fsnotify](https://pkg.go.dev/github.com/fsnotify/fsnotify) ([BSD-3-Clause](https://github.com/fsnotify/fsnotify/blob/v1.9.0/LICENSE))
|
||||
- [github.com/gabriel-vasile/mimetype](https://pkg.go.dev/github.com/gabriel-vasile/mimetype) ([MIT](https://github.com/gabriel-vasile/mimetype/blob/v1.4.11/LICENSE))
|
||||
- [github.com/gdamore/encoding](https://pkg.go.dev/github.com/gdamore/encoding) ([Apache-2.0](https://github.com/gdamore/encoding/blob/v1.0.1/LICENSE))
|
||||
- [github.com/gdamore/tcell/v2](https://pkg.go.dev/github.com/gdamore/tcell/v2) ([Apache-2.0](https://github.com/gdamore/tcell/blob/v2.13.4/LICENSE))
|
||||
- [github.com/go-chi/chi/v5](https://pkg.go.dev/github.com/go-chi/chi/v5) ([MIT](https://github.com/go-chi/chi/blob/v5.2.3/LICENSE))
|
||||
- [github.com/go-jose/go-jose/v4](https://pkg.go.dev/github.com/go-jose/go-jose/v4) ([Apache-2.0](https://github.com/go-jose/go-jose/blob/v4.1.3/LICENSE))
|
||||
- [github.com/go-jose/go-jose/v4/json](https://pkg.go.dev/github.com/go-jose/go-jose/v4/json) ([BSD-3-Clause](https://github.com/go-jose/go-jose/blob/v4.1.3/json/LICENSE))
|
||||
- [github.com/go-logr/logr](https://pkg.go.dev/github.com/go-logr/logr) ([Apache-2.0](https://github.com/go-logr/logr/blob/v1.4.3/LICENSE))
|
||||
- [github.com/go-logr/stdr](https://pkg.go.dev/github.com/go-logr/stdr) ([Apache-2.0](https://github.com/go-logr/stdr/blob/v1.2.2/LICENSE))
|
||||
- [github.com/go-openapi/analysis](https://pkg.go.dev/github.com/go-openapi/analysis) ([Apache-2.0](https://github.com/go-openapi/analysis/blob/v0.23.0/LICENSE))
|
||||
- [github.com/go-openapi/errors](https://pkg.go.dev/github.com/go-openapi/errors) ([Apache-2.0](https://github.com/go-openapi/errors/blob/v0.22.2/LICENSE))
|
||||
- [github.com/go-openapi/jsonpointer](https://pkg.go.dev/github.com/go-openapi/jsonpointer) ([Apache-2.0](https://github.com/go-openapi/jsonpointer/blob/v0.21.1/LICENSE))
|
||||
- [github.com/go-openapi/jsonreference](https://pkg.go.dev/github.com/go-openapi/jsonreference) ([Apache-2.0](https://github.com/go-openapi/jsonreference/blob/v0.21.0/LICENSE))
|
||||
- [github.com/go-openapi/loads](https://pkg.go.dev/github.com/go-openapi/loads) ([Apache-2.0](https://github.com/go-openapi/loads/blob/v0.22.0/LICENSE))
|
||||
- [github.com/go-openapi/runtime](https://pkg.go.dev/github.com/go-openapi/runtime) ([Apache-2.0](https://github.com/go-openapi/runtime/blob/v0.28.0/LICENSE))
|
||||
- [github.com/go-openapi/runtime/middleware/denco](https://pkg.go.dev/github.com/go-openapi/runtime/middleware/denco) ([MIT](https://github.com/go-openapi/runtime/blob/v0.28.0/middleware/denco/LICENSE))
|
||||
- [github.com/go-openapi/spec](https://pkg.go.dev/github.com/go-openapi/spec) ([Apache-2.0](https://github.com/go-openapi/spec/blob/v0.21.0/LICENSE))
|
||||
- [github.com/go-openapi/strfmt](https://pkg.go.dev/github.com/go-openapi/strfmt) ([Apache-2.0](https://github.com/go-openapi/strfmt/blob/v0.23.0/LICENSE))
|
||||
- [github.com/go-openapi/swag](https://pkg.go.dev/github.com/go-openapi/swag) ([Apache-2.0](https://github.com/go-openapi/swag/blob/v0.24.1/LICENSE))
|
||||
- [github.com/go-openapi/swag/cmdutils](https://pkg.go.dev/github.com/go-openapi/swag/cmdutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/cmdutils/v0.24.0/cmdutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/conv](https://pkg.go.dev/github.com/go-openapi/swag/conv) ([Apache-2.0](https://github.com/go-openapi/swag/blob/conv/v0.24.0/conv/LICENSE))
|
||||
- [github.com/go-openapi/swag/fileutils](https://pkg.go.dev/github.com/go-openapi/swag/fileutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/fileutils/v0.24.0/fileutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonname](https://pkg.go.dev/github.com/go-openapi/swag/jsonname) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonname/v0.24.0/jsonname/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonutils](https://pkg.go.dev/github.com/go-openapi/swag/jsonutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonutils/v0.24.0/jsonutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/loading](https://pkg.go.dev/github.com/go-openapi/swag/loading) ([Apache-2.0](https://github.com/go-openapi/swag/blob/loading/v0.24.0/loading/LICENSE))
|
||||
- [github.com/go-openapi/swag/mangling](https://pkg.go.dev/github.com/go-openapi/swag/mangling) ([Apache-2.0](https://github.com/go-openapi/swag/blob/mangling/v0.24.0/mangling/LICENSE))
|
||||
- [github.com/go-openapi/swag/netutils](https://pkg.go.dev/github.com/go-openapi/swag/netutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/netutils/v0.24.0/netutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/stringutils](https://pkg.go.dev/github.com/go-openapi/swag/stringutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/stringutils/v0.24.0/stringutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/typeutils](https://pkg.go.dev/github.com/go-openapi/swag/typeutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/typeutils/v0.24.0/typeutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/yamlutils](https://pkg.go.dev/github.com/go-openapi/swag/yamlutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/yamlutils/v0.24.0/yamlutils/LICENSE))
|
||||
- [github.com/go-openapi/validate](https://pkg.go.dev/github.com/go-openapi/validate) ([Apache-2.0](https://github.com/go-openapi/validate/blob/v0.24.0/LICENSE))
|
||||
- [github.com/go-openapi/analysis](https://pkg.go.dev/github.com/go-openapi/analysis) ([Apache-2.0](https://github.com/go-openapi/analysis/blob/v0.24.1/LICENSE))
|
||||
- [github.com/go-openapi/errors](https://pkg.go.dev/github.com/go-openapi/errors) ([Apache-2.0](https://github.com/go-openapi/errors/blob/v0.22.4/LICENSE))
|
||||
- [github.com/go-openapi/jsonpointer](https://pkg.go.dev/github.com/go-openapi/jsonpointer) ([Apache-2.0](https://github.com/go-openapi/jsonpointer/blob/v0.22.1/LICENSE))
|
||||
- [github.com/go-openapi/jsonreference](https://pkg.go.dev/github.com/go-openapi/jsonreference) ([Apache-2.0](https://github.com/go-openapi/jsonreference/blob/v0.21.3/LICENSE))
|
||||
- [github.com/go-openapi/loads](https://pkg.go.dev/github.com/go-openapi/loads) ([Apache-2.0](https://github.com/go-openapi/loads/blob/v0.23.2/LICENSE))
|
||||
- [github.com/go-openapi/runtime](https://pkg.go.dev/github.com/go-openapi/runtime) ([Apache-2.0](https://github.com/go-openapi/runtime/blob/v0.29.2/LICENSE))
|
||||
- [github.com/go-openapi/runtime/middleware/denco](https://pkg.go.dev/github.com/go-openapi/runtime/middleware/denco) ([MIT](https://github.com/go-openapi/runtime/blob/v0.29.2/middleware/denco/LICENSE))
|
||||
- [github.com/go-openapi/spec](https://pkg.go.dev/github.com/go-openapi/spec) ([Apache-2.0](https://github.com/go-openapi/spec/blob/v0.22.1/LICENSE))
|
||||
- [github.com/go-openapi/strfmt](https://pkg.go.dev/github.com/go-openapi/strfmt) ([Apache-2.0](https://github.com/go-openapi/strfmt/blob/v0.25.0/LICENSE))
|
||||
- [github.com/go-openapi/swag](https://pkg.go.dev/github.com/go-openapi/swag) ([Apache-2.0](https://github.com/go-openapi/swag/blob/v0.25.4/LICENSE))
|
||||
- [github.com/go-openapi/swag/cmdutils](https://pkg.go.dev/github.com/go-openapi/swag/cmdutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/cmdutils/v0.25.4/cmdutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/conv](https://pkg.go.dev/github.com/go-openapi/swag/conv) ([Apache-2.0](https://github.com/go-openapi/swag/blob/conv/v0.25.4/conv/LICENSE))
|
||||
- [github.com/go-openapi/swag/fileutils](https://pkg.go.dev/github.com/go-openapi/swag/fileutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/fileutils/v0.25.4/fileutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonname](https://pkg.go.dev/github.com/go-openapi/swag/jsonname) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonname/v0.25.4/jsonname/LICENSE))
|
||||
- [github.com/go-openapi/swag/jsonutils](https://pkg.go.dev/github.com/go-openapi/swag/jsonutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/jsonutils/v0.25.4/jsonutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/loading](https://pkg.go.dev/github.com/go-openapi/swag/loading) ([Apache-2.0](https://github.com/go-openapi/swag/blob/loading/v0.25.4/loading/LICENSE))
|
||||
- [github.com/go-openapi/swag/mangling](https://pkg.go.dev/github.com/go-openapi/swag/mangling) ([Apache-2.0](https://github.com/go-openapi/swag/blob/mangling/v0.25.4/mangling/LICENSE))
|
||||
- [github.com/go-openapi/swag/netutils](https://pkg.go.dev/github.com/go-openapi/swag/netutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/netutils/v0.25.4/netutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/stringutils](https://pkg.go.dev/github.com/go-openapi/swag/stringutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/stringutils/v0.25.4/stringutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/typeutils](https://pkg.go.dev/github.com/go-openapi/swag/typeutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/typeutils/v0.25.4/typeutils/LICENSE))
|
||||
- [github.com/go-openapi/swag/yamlutils](https://pkg.go.dev/github.com/go-openapi/swag/yamlutils) ([Apache-2.0](https://github.com/go-openapi/swag/blob/yamlutils/v0.25.4/yamlutils/LICENSE))
|
||||
- [github.com/go-openapi/validate](https://pkg.go.dev/github.com/go-openapi/validate) ([Apache-2.0](https://github.com/go-openapi/validate/blob/v0.25.1/LICENSE))
|
||||
- [github.com/go-viper/mapstructure/v2](https://pkg.go.dev/github.com/go-viper/mapstructure/v2) ([MIT](https://github.com/go-viper/mapstructure/blob/v2.4.0/LICENSE))
|
||||
- [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/2c02b8208cf8/LICENSE))
|
||||
- [github.com/golang/snappy](https://pkg.go.dev/github.com/golang/snappy) ([BSD-3-Clause](https://github.com/golang/snappy/blob/v1.0.0/LICENSE))
|
||||
- [github.com/google/certificate-transparency-go](https://pkg.go.dev/github.com/google/certificate-transparency-go) ([Apache-2.0](https://github.com/google/certificate-transparency-go/blob/v1.3.2/LICENSE))
|
||||
- [github.com/google/go-cmp/cmp](https://pkg.go.dev/github.com/google/go-cmp/cmp) ([BSD-3-Clause](https://github.com/google/go-cmp/blob/v0.7.0/LICENSE))
|
||||
- [github.com/google/go-containerregistry](https://pkg.go.dev/github.com/google/go-containerregistry) ([Apache-2.0](https://github.com/google/go-containerregistry/blob/v0.20.7/LICENSE))
|
||||
- [github.com/google/s2a-go](https://pkg.go.dev/github.com/google/s2a-go) ([Apache-2.0](https://github.com/google/s2a-go/blob/v0.1.9/LICENSE.md))
|
||||
- [github.com/google/shlex](https://pkg.go.dev/github.com/google/shlex) ([Apache-2.0](https://github.com/google/shlex/blob/e7afc7fbc510/COPYING))
|
||||
- [github.com/google/uuid](https://pkg.go.dev/github.com/google/uuid) ([BSD-3-Clause](https://github.com/google/uuid/blob/v1.6.0/LICENSE))
|
||||
- [github.com/googleapis/enterprise-certificate-proxy/client](https://pkg.go.dev/github.com/googleapis/enterprise-certificate-proxy/client) ([Apache-2.0](https://github.com/googleapis/enterprise-certificate-proxy/blob/v0.3.6/LICENSE))
|
||||
- [github.com/googleapis/gax-go/v2](https://pkg.go.dev/github.com/googleapis/gax-go/v2) ([BSD-3-Clause](https://github.com/googleapis/gax-go/blob/v2.15.0/v2/LICENSE))
|
||||
- [github.com/gorilla/css/scanner](https://pkg.go.dev/github.com/gorilla/css/scanner) ([BSD-3-Clause](https://github.com/gorilla/css/blob/v1.0.1/LICENSE))
|
||||
- [github.com/gorilla/websocket](https://pkg.go.dev/github.com/gorilla/websocket) ([BSD-2-Clause](https://github.com/gorilla/websocket/blob/v1.5.3/LICENSE))
|
||||
- [github.com/grpc-ecosystem/grpc-gateway/v2](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/v2) ([BSD-3-Clause](https://github.com/grpc-ecosystem/grpc-gateway/blob/v2.27.2/LICENSE))
|
||||
- [github.com/grpc-ecosystem/grpc-gateway/v2](https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/v2) ([BSD-3-Clause](https://github.com/grpc-ecosystem/grpc-gateway/blob/v2.27.3/LICENSE))
|
||||
- [github.com/hashicorp/go-version](https://pkg.go.dev/github.com/hashicorp/go-version) ([MPL-2.0](https://github.com/hashicorp/go-version/blob/v1.8.0/LICENSE))
|
||||
- [github.com/hashicorp/golang-lru/v2](https://pkg.go.dev/github.com/hashicorp/golang-lru/v2) ([MPL-2.0](https://github.com/hashicorp/golang-lru/blob/v2.0.7/LICENSE))
|
||||
- [github.com/hashicorp/golang-lru/v2/simplelru](https://pkg.go.dev/github.com/hashicorp/golang-lru/v2/simplelru) ([BSD-3-Clause](https://github.com/hashicorp/golang-lru/blob/v2.0.7/simplelru/LICENSE_list))
|
||||
- [github.com/henvic/httpretty](https://pkg.go.dev/github.com/henvic/httpretty) ([MIT](https://github.com/henvic/httpretty/blob/v0.1.4/LICENSE.md))
|
||||
- [github.com/huandu/xstrings](https://pkg.go.dev/github.com/huandu/xstrings) ([MIT](https://github.com/huandu/xstrings/blob/v1.5.0/LICENSE))
|
||||
- [github.com/in-toto/attestation/go/v1](https://pkg.go.dev/github.com/in-toto/attestation/go/v1) ([Apache-2.0](https://github.com/in-toto/attestation/blob/v1.1.2/LICENSE))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto) ([Apache-2.0](https://github.com/in-toto/in-toto-golang/blob/v0.9.0/LICENSE))
|
||||
- [github.com/in-toto/attestation/go/v1](https://pkg.go.dev/github.com/in-toto/attestation/go/v1) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2) ([Unknown](Unknown))
|
||||
- [github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1](https://pkg.go.dev/github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v1) ([Unknown](Unknown))
|
||||
- [github.com/inconshreveable/mousetrap](https://pkg.go.dev/github.com/inconshreveable/mousetrap) ([Apache-2.0](https://github.com/inconshreveable/mousetrap/blob/v1.1.0/LICENSE))
|
||||
- [github.com/itchyny/gojq](https://pkg.go.dev/github.com/itchyny/gojq) ([MIT](https://github.com/itchyny/gojq/blob/v0.12.17/LICENSE))
|
||||
- [github.com/itchyny/timefmt-go](https://pkg.go.dev/github.com/itchyny/timefmt-go) ([MIT](https://github.com/itchyny/timefmt-go/blob/v0.1.6/LICENSE))
|
||||
- [github.com/jedisct1/go-minisign](https://pkg.go.dev/github.com/jedisct1/go-minisign) ([MIT](https://github.com/jedisct1/go-minisign/blob/d2f9f49435c7/LICENSE))
|
||||
- [github.com/joho/godotenv](https://pkg.go.dev/github.com/joho/godotenv) ([MIT](https://github.com/joho/godotenv/blob/v1.5.1/LICENCE))
|
||||
- [github.com/josharian/intern](https://pkg.go.dev/github.com/josharian/intern) ([MIT](https://github.com/josharian/intern/blob/v1.0.0/license.md))
|
||||
- [github.com/kballard/go-shellquote](https://pkg.go.dev/github.com/kballard/go-shellquote) ([MIT](https://github.com/kballard/go-shellquote/blob/95032a82bc51/LICENSE))
|
||||
- [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([MIT](https://github.com/klauspost/compress/blob/v1.18.1/LICENSE))
|
||||
- [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.18.1/LICENSE))
|
||||
- [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.18.1/LICENSE))
|
||||
- [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.18.1/internal/snapref/LICENSE))
|
||||
- [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.18.1/zstd/internal/xxhash/LICENSE.txt))
|
||||
- [github.com/letsencrypt/boulder](https://pkg.go.dev/github.com/letsencrypt/boulder) ([MPL-2.0](https://github.com/letsencrypt/boulder/blob/v0.20250630.0/LICENSE.txt))
|
||||
- [github.com/lucasb-eyer/go-colorful](https://pkg.go.dev/github.com/lucasb-eyer/go-colorful) ([MIT](https://github.com/lucasb-eyer/go-colorful/blob/v1.3.0/LICENSE))
|
||||
- [github.com/mailru/easyjson](https://pkg.go.dev/github.com/mailru/easyjson) ([MIT](https://github.com/mailru/easyjson/blob/v0.9.0/LICENSE))
|
||||
- [github.com/mattn/go-colorable](https://pkg.go.dev/github.com/mattn/go-colorable) ([MIT](https://github.com/mattn/go-colorable/blob/v0.1.14/LICENSE))
|
||||
- [github.com/mattn/go-isatty](https://pkg.go.dev/github.com/mattn/go-isatty) ([MIT](https://github.com/mattn/go-isatty/blob/v0.0.20/LICENSE))
|
||||
- [github.com/mattn/go-localereader](https://pkg.go.dev/github.com/mattn/go-localereader) ([Unknown](Unknown))
|
||||
- [github.com/mattn/go-runewidth](https://pkg.go.dev/github.com/mattn/go-runewidth) ([MIT](https://github.com/mattn/go-runewidth/blob/v0.0.16/LICENSE))
|
||||
- [github.com/mattn/go-runewidth](https://pkg.go.dev/github.com/mattn/go-runewidth) ([MIT](https://github.com/mattn/go-runewidth/blob/v0.0.17/LICENSE))
|
||||
- [github.com/mgutz/ansi](https://pkg.go.dev/github.com/mgutz/ansi) ([MIT](https://github.com/mgutz/ansi/blob/d51e80ef957d/LICENSE))
|
||||
- [github.com/microcosm-cc/bluemonday](https://pkg.go.dev/github.com/microcosm-cc/bluemonday) ([BSD-3-Clause](https://github.com/microcosm-cc/bluemonday/blob/v1.0.27/LICENSE.md))
|
||||
- [github.com/microsoft/dev-tunnels/go/tunnels](https://pkg.go.dev/github.com/microsoft/dev-tunnels/go/tunnels) ([MIT](https://github.com/microsoft/dev-tunnels/blob/v0.1.19/LICENSE))
|
||||
- [github.com/mitchellh/copystructure](https://pkg.go.dev/github.com/mitchellh/copystructure) ([MIT](https://github.com/mitchellh/copystructure/blob/v1.2.0/LICENSE))
|
||||
- [github.com/mitchellh/go-homedir](https://pkg.go.dev/github.com/mitchellh/go-homedir) ([MIT](https://github.com/mitchellh/go-homedir/blob/v1.1.0/LICENSE))
|
||||
- [github.com/mitchellh/hashstructure/v2](https://pkg.go.dev/github.com/mitchellh/hashstructure/v2) ([MIT](https://github.com/mitchellh/hashstructure/blob/v2.0.2/LICENSE))
|
||||
- [github.com/mitchellh/mapstructure](https://pkg.go.dev/github.com/mitchellh/mapstructure) ([MIT](https://github.com/mitchellh/mapstructure/blob/v1.5.0/LICENSE))
|
||||
- [github.com/mitchellh/reflectwalk](https://pkg.go.dev/github.com/mitchellh/reflectwalk) ([MIT](https://github.com/mitchellh/reflectwalk/blob/v1.0.2/LICENSE))
|
||||
- [github.com/muesli/ansi](https://pkg.go.dev/github.com/muesli/ansi) ([MIT](https://github.com/muesli/ansi/blob/276c6243b2f6/LICENSE))
|
||||
- [github.com/muesli/cancelreader](https://pkg.go.dev/github.com/muesli/cancelreader) ([MIT](https://github.com/muesli/cancelreader/blob/v0.2.2/LICENSE))
|
||||
|
|
@ -160,83 +131,60 @@ Some packages may only be included on certain architectures or operating systems
|
|||
- [github.com/opencontainers/go-digest](https://pkg.go.dev/github.com/opencontainers/go-digest) ([Apache-2.0](https://github.com/opencontainers/go-digest/blob/v1.0.0/LICENSE))
|
||||
- [github.com/opencontainers/image-spec/specs-go](https://pkg.go.dev/github.com/opencontainers/image-spec/specs-go) ([Apache-2.0](https://github.com/opencontainers/image-spec/blob/v1.1.1/LICENSE))
|
||||
- [github.com/opentracing/opentracing-go](https://pkg.go.dev/github.com/opentracing/opentracing-go) ([Apache-2.0](https://github.com/opentracing/opentracing-go/blob/v1.2.0/LICENSE))
|
||||
- [github.com/pelletier/go-toml/v2](https://pkg.go.dev/github.com/pelletier/go-toml/v2) ([MIT](https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE))
|
||||
- [github.com/pkg/errors](https://pkg.go.dev/github.com/pkg/errors) ([BSD-2-Clause](https://github.com/pkg/errors/blob/v0.9.1/LICENSE))
|
||||
- [github.com/pmezard/go-difflib/difflib](https://pkg.go.dev/github.com/pmezard/go-difflib/difflib) ([BSD-3-Clause](https://github.com/pmezard/go-difflib/blob/5d4384ee4fb2/LICENSE))
|
||||
- [github.com/rivo/tview](https://pkg.go.dev/github.com/rivo/tview) ([MIT](https://github.com/rivo/tview/blob/v0.42.0/LICENSE.txt))
|
||||
- [github.com/rivo/uniseg](https://pkg.go.dev/github.com/rivo/uniseg) ([MIT](https://github.com/rivo/uniseg/blob/v0.4.7/LICENSE.txt))
|
||||
- [github.com/rodaine/table](https://pkg.go.dev/github.com/rodaine/table) ([MIT](https://github.com/rodaine/table/blob/v1.3.0/license))
|
||||
- [github.com/russross/blackfriday/v2](https://pkg.go.dev/github.com/russross/blackfriday/v2) ([BSD-2-Clause](https://github.com/russross/blackfriday/blob/v2.1.0/LICENSE.txt))
|
||||
- [github.com/sagikazarmark/locafero](https://pkg.go.dev/github.com/sagikazarmark/locafero) ([MIT](https://github.com/sagikazarmark/locafero/blob/v0.9.0/LICENSE))
|
||||
- [github.com/sassoftware/relic/lib](https://pkg.go.dev/github.com/sassoftware/relic/lib) ([Apache-2.0](https://github.com/sassoftware/relic/blob/v7.2.1/LICENSE))
|
||||
- [github.com/secure-systems-lab/go-securesystemslib](https://pkg.go.dev/github.com/secure-systems-lab/go-securesystemslib) ([MIT](https://github.com/secure-systems-lab/go-securesystemslib/blob/v0.9.1/LICENSE))
|
||||
- [github.com/shibumi/go-pathspec](https://pkg.go.dev/github.com/shibumi/go-pathspec) ([Apache-2.0](https://github.com/shibumi/go-pathspec/blob/v1.3.0/LICENSE))
|
||||
- [github.com/shopspring/decimal](https://pkg.go.dev/github.com/shopspring/decimal) ([MIT](https://github.com/shopspring/decimal/blob/v1.4.0/LICENSE))
|
||||
- [github.com/shurcooL/githubv4](https://pkg.go.dev/github.com/shurcooL/githubv4) ([MIT](https://github.com/shurcooL/githubv4/blob/48295856cce7/LICENSE))
|
||||
- [github.com/shurcooL/graphql](https://pkg.go.dev/github.com/shurcooL/graphql) ([MIT](https://github.com/shurcooL/graphql/blob/ed46e5a46466/LICENSE))
|
||||
- [github.com/sigstore/protobuf-specs/gen/pb-go](https://pkg.go.dev/github.com/sigstore/protobuf-specs/gen/pb-go) ([Apache-2.0](https://github.com/sigstore/protobuf-specs/blob/v0.5.0/LICENSE))
|
||||
- [github.com/sigstore/rekor-tiles](https://pkg.go.dev/github.com/sigstore/rekor-tiles) ([Apache-2.0](https://github.com/sigstore/rekor-tiles/blob/v0.1.11/LICENSE))
|
||||
- [github.com/sigstore/rekor/pkg](https://pkg.go.dev/github.com/sigstore/rekor/pkg) ([Apache-2.0](https://github.com/sigstore/rekor/blob/v1.4.2/LICENSE))
|
||||
- [github.com/sigstore/sigstore-go/pkg](https://pkg.go.dev/github.com/sigstore/sigstore-go/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore-go/blob/v1.1.3/LICENSE))
|
||||
- [github.com/sigstore/sigstore/pkg](https://pkg.go.dev/github.com/sigstore/sigstore/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore/blob/181c5d3339b3/LICENSE))
|
||||
- [github.com/sigstore/timestamp-authority/pkg/verification](https://pkg.go.dev/github.com/sigstore/timestamp-authority/pkg/verification) ([Apache-2.0](https://github.com/sigstore/timestamp-authority/blob/v1.2.9/LICENSE))
|
||||
- [github.com/sigstore/rekor-tiles/v2](https://pkg.go.dev/github.com/sigstore/rekor-tiles/v2) ([Apache-2.0](https://github.com/sigstore/rekor-tiles/blob/v2.0.1/LICENSE))
|
||||
- [github.com/sigstore/rekor/pkg](https://pkg.go.dev/github.com/sigstore/rekor/pkg) ([Apache-2.0](https://github.com/sigstore/rekor/blob/v1.4.3/LICENSE))
|
||||
- [github.com/sigstore/sigstore-go/pkg](https://pkg.go.dev/github.com/sigstore/sigstore-go/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore-go/blob/v1.1.4/LICENSE))
|
||||
- [github.com/sigstore/sigstore/pkg](https://pkg.go.dev/github.com/sigstore/sigstore/pkg) ([Apache-2.0](https://github.com/sigstore/sigstore/blob/v1.10.0/LICENSE))
|
||||
- [github.com/sigstore/timestamp-authority/v2/pkg/verification](https://pkg.go.dev/github.com/sigstore/timestamp-authority/v2/pkg/verification) ([Apache-2.0](https://github.com/sigstore/timestamp-authority/blob/v2.0.3/LICENSE))
|
||||
- [github.com/sirupsen/logrus](https://pkg.go.dev/github.com/sirupsen/logrus) ([MIT](https://github.com/sirupsen/logrus/blob/v1.9.3/LICENSE))
|
||||
- [github.com/sourcegraph/conc](https://pkg.go.dev/github.com/sourcegraph/conc) ([MIT](https://github.com/sourcegraph/conc/blob/v0.3.0/LICENSE))
|
||||
- [github.com/spf13/afero](https://pkg.go.dev/github.com/spf13/afero) ([Apache-2.0](https://github.com/spf13/afero/blob/v1.14.0/LICENSE.txt))
|
||||
- [github.com/spf13/cast](https://pkg.go.dev/github.com/spf13/cast) ([MIT](https://github.com/spf13/cast/blob/v1.9.2/LICENSE))
|
||||
- [github.com/spf13/cast](https://pkg.go.dev/github.com/spf13/cast) ([MIT](https://github.com/spf13/cast/blob/v1.10.0/LICENSE))
|
||||
- [github.com/spf13/cobra](https://pkg.go.dev/github.com/spf13/cobra) ([Apache-2.0](https://github.com/spf13/cobra/blob/v1.10.2/LICENSE.txt))
|
||||
- [github.com/spf13/pflag](https://pkg.go.dev/github.com/spf13/pflag) ([BSD-3-Clause](https://github.com/spf13/pflag/blob/v1.0.10/LICENSE))
|
||||
- [github.com/spf13/viper](https://pkg.go.dev/github.com/spf13/viper) ([MIT](https://github.com/spf13/viper/blob/v1.20.1/LICENSE))
|
||||
- [github.com/spiffe/go-spiffe/v2](https://pkg.go.dev/github.com/spiffe/go-spiffe/v2) ([Apache-2.0](https://github.com/spiffe/go-spiffe/blob/v2.6.0/LICENSE))
|
||||
- [github.com/stretchr/objx](https://pkg.go.dev/github.com/stretchr/objx) ([MIT](https://github.com/stretchr/objx/blob/v0.5.2/LICENSE))
|
||||
- [github.com/stretchr/testify](https://pkg.go.dev/github.com/stretchr/testify) ([MIT](https://github.com/stretchr/testify/blob/v1.11.1/LICENSE))
|
||||
- [github.com/subosito/gotenv](https://pkg.go.dev/github.com/subosito/gotenv) ([MIT](https://github.com/subosito/gotenv/blob/v1.6.0/LICENSE))
|
||||
- [github.com/theupdateframework/go-tuf](https://pkg.go.dev/github.com/theupdateframework/go-tuf) ([BSD-3-Clause](https://github.com/theupdateframework/go-tuf/blob/v0.7.0/LICENSE))
|
||||
- [github.com/theupdateframework/go-tuf/v2/metadata](https://pkg.go.dev/github.com/theupdateframework/go-tuf/v2/metadata) ([Apache-2.0](https://github.com/theupdateframework/go-tuf/blob/v2.3.0/LICENSE))
|
||||
- [github.com/thlib/go-timezone-local/tzlocal](https://pkg.go.dev/github.com/thlib/go-timezone-local/tzlocal) ([Unlicense](https://github.com/thlib/go-timezone-local/blob/v0.0.6/LICENSE))
|
||||
- [github.com/titanous/rocacheck](https://pkg.go.dev/github.com/titanous/rocacheck) ([MIT](https://github.com/titanous/rocacheck/blob/afe73141d399/LICENSE))
|
||||
- [github.com/transparency-dev/formats](https://pkg.go.dev/github.com/transparency-dev/formats) ([Apache-2.0](https://github.com/transparency-dev/formats/blob/bb8ad4d07c26/LICENSE))
|
||||
- [github.com/transparency-dev/formats/log](https://pkg.go.dev/github.com/transparency-dev/formats/log) ([Apache-2.0](https://github.com/transparency-dev/formats/blob/404c0d5b696c/LICENSE))
|
||||
- [github.com/transparency-dev/merkle](https://pkg.go.dev/github.com/transparency-dev/merkle) ([Apache-2.0](https://github.com/transparency-dev/merkle/blob/v0.0.2/LICENSE))
|
||||
- [github.com/transparency-dev/tessera](https://pkg.go.dev/github.com/transparency-dev/tessera) ([Apache-2.0](https://github.com/transparency-dev/tessera/blob/v1.0.0-rc3/LICENSE))
|
||||
- [github.com/vbatts/tar-split/archive/tar](https://pkg.go.dev/github.com/vbatts/tar-split/archive/tar) ([BSD-3-Clause](https://github.com/vbatts/tar-split/blob/v0.12.2/LICENSE))
|
||||
- [github.com/vmihailenco/msgpack/v5](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5) ([BSD-2-Clause](https://github.com/vmihailenco/msgpack/blob/v5.4.1/LICENSE))
|
||||
- [github.com/vmihailenco/tagparser/v2](https://pkg.go.dev/github.com/vmihailenco/tagparser/v2) ([BSD-2-Clause](https://github.com/vmihailenco/tagparser/blob/v2.0.0/LICENSE))
|
||||
- [github.com/xo/terminfo](https://pkg.go.dev/github.com/xo/terminfo) ([MIT](https://github.com/xo/terminfo/blob/abceb7e1c41e/LICENSE))
|
||||
- [github.com/yuin/goldmark](https://pkg.go.dev/github.com/yuin/goldmark) ([MIT](https://github.com/yuin/goldmark/blob/v1.7.13/LICENSE))
|
||||
- [github.com/yuin/goldmark](https://pkg.go.dev/github.com/yuin/goldmark) ([MIT](https://github.com/yuin/goldmark/blob/v1.7.16/LICENSE))
|
||||
- [github.com/yuin/goldmark-emoji](https://pkg.go.dev/github.com/yuin/goldmark-emoji) ([MIT](https://github.com/yuin/goldmark-emoji/blob/v1.0.6/LICENSE))
|
||||
- [github.com/zalando/go-keyring](https://pkg.go.dev/github.com/zalando/go-keyring) ([MIT](https://github.com/zalando/go-keyring/blob/v0.2.6/LICENSE))
|
||||
- [go.mongodb.org/mongo-driver](https://pkg.go.dev/go.mongodb.org/mongo-driver) ([Apache-2.0](https://github.com/mongodb/mongo-go-driver/blob/v1.17.4/LICENSE))
|
||||
- [go.opencensus.io](https://pkg.go.dev/go.opencensus.io) ([Apache-2.0](https://github.com/census-instrumentation/opencensus-go/blob/v0.24.0/LICENSE))
|
||||
- [go.mongodb.org/mongo-driver](https://pkg.go.dev/go.mongodb.org/mongo-driver) ([Apache-2.0](https://github.com/mongodb/mongo-go-driver/blob/v1.17.6/LICENSE))
|
||||
- [go.opentelemetry.io/auto/sdk](https://pkg.go.dev/go.opentelemetry.io/auto/sdk) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-instrumentation/blob/sdk/v1.2.1/sdk/LICENSE))
|
||||
- [go.opentelemetry.io/contrib/detectors/gcp](https://pkg.go.dev/go.opentelemetry.io/contrib/detectors/gcp) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/detectors/gcp/v1.38.0/detectors/gcp/LICENSE))
|
||||
- [go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc](https://pkg.go.dev/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/instrumentation/google.golang.org/grpc/otelgrpc/v0.61.0/instrumentation/google.golang.org/grpc/otelgrpc/LICENSE))
|
||||
- [go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp](https://pkg.go.dev/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/instrumentation/net/http/otelhttp/v0.61.0/instrumentation/net/http/otelhttp/LICENSE))
|
||||
- [go.opentelemetry.io/otel](https://pkg.go.dev/go.opentelemetry.io/otel) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/v1.38.0/LICENSE))
|
||||
- [go.opentelemetry.io/otel](https://pkg.go.dev/go.opentelemetry.io/otel) ([BSD-3-Clause](https://github.com/open-telemetry/opentelemetry-go/blob/v1.38.0/LICENSE))
|
||||
- [go.opentelemetry.io/otel/metric](https://pkg.go.dev/go.opentelemetry.io/otel/metric) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/metric/v1.38.0/metric/LICENSE))
|
||||
- [go.opentelemetry.io/otel/sdk](https://pkg.go.dev/go.opentelemetry.io/otel/sdk) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/sdk/v1.38.0/sdk/LICENSE))
|
||||
- [go.opentelemetry.io/otel/sdk/metric](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/sdk/metric/v1.38.0/sdk/metric/LICENSE))
|
||||
- [go.opentelemetry.io/otel/metric](https://pkg.go.dev/go.opentelemetry.io/otel/metric) ([BSD-3-Clause](https://github.com/open-telemetry/opentelemetry-go/blob/metric/v1.38.0/metric/LICENSE))
|
||||
- [go.opentelemetry.io/otel/trace](https://pkg.go.dev/go.opentelemetry.io/otel/trace) ([Apache-2.0](https://github.com/open-telemetry/opentelemetry-go/blob/trace/v1.38.0/trace/LICENSE))
|
||||
- [go.uber.org/multierr](https://pkg.go.dev/go.uber.org/multierr) ([MIT](https://github.com/uber-go/multierr/blob/v1.11.0/LICENSE.txt))
|
||||
- [go.uber.org/zap](https://pkg.go.dev/go.uber.org/zap) ([MIT](https://github.com/uber-go/zap/blob/v1.27.0/LICENSE))
|
||||
- [go.opentelemetry.io/otel/trace](https://pkg.go.dev/go.opentelemetry.io/otel/trace) ([BSD-3-Clause](https://github.com/open-telemetry/opentelemetry-go/blob/trace/v1.38.0/trace/LICENSE))
|
||||
- [go.yaml.in/yaml/v3](https://pkg.go.dev/go.yaml.in/yaml/v3) ([MIT](https://github.com/yaml/go-yaml/blob/v3.0.4/LICENSE))
|
||||
- [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.46.0:LICENSE))
|
||||
- [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/b7579e27:LICENSE))
|
||||
- [golang.org/x/mod](https://pkg.go.dev/golang.org/x/mod) ([BSD-3-Clause](https://cs.opensource.google/go/x/mod/+/v0.30.0:LICENSE))
|
||||
- [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.47.0:LICENSE))
|
||||
- [golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) ([BSD-3-Clause](https://cs.opensource.google/go/x/oauth2/+/v0.33.0:LICENSE))
|
||||
- [golang.org/x/sync](https://pkg.go.dev/golang.org/x/sync) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.19.0:LICENSE))
|
||||
- [golang.org/x/sync/errgroup](https://pkg.go.dev/golang.org/x/sync/errgroup) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.19.0:LICENSE))
|
||||
- [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.39.0:LICENSE))
|
||||
- [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.38.0:LICENSE))
|
||||
- [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.32.0:LICENSE))
|
||||
- [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.12.0:LICENSE))
|
||||
- [google.golang.org/api](https://pkg.go.dev/google.golang.org/api) ([BSD-3-Clause](https://github.com/googleapis/google-api-go-client/blob/v0.248.0/LICENSE))
|
||||
- [google.golang.org/api/internal/third_party/uritemplates](https://pkg.go.dev/google.golang.org/api/internal/third_party/uritemplates) ([BSD-3-Clause](https://github.com/googleapis/google-api-go-client/blob/v0.248.0/internal/third_party/uritemplates/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/api](https://pkg.go.dev/google.golang.org/genproto/googleapis/api) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/3a174f9686a8/googleapis/api/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/rpc](https://pkg.go.dev/google.golang.org/genproto/googleapis/rpc) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/3a174f9686a8/googleapis/rpc/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/type](https://pkg.go.dev/google.golang.org/genproto/googleapis/type) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/513f23925822/LICENSE))
|
||||
- [google.golang.org/genproto/googleapis/rpc/status](https://pkg.go.dev/google.golang.org/genproto/googleapis/rpc/status) ([Apache-2.0](https://github.com/googleapis/go-genproto/blob/f26f9409b101/googleapis/rpc/LICENSE))
|
||||
- [google.golang.org/grpc](https://pkg.go.dev/google.golang.org/grpc) ([Apache-2.0](https://github.com/grpc/grpc-go/blob/v1.77.0/LICENSE))
|
||||
- [google.golang.org/protobuf](https://pkg.go.dev/google.golang.org/protobuf) ([BSD-3-Clause](https://github.com/protocolbuffers/protobuf-go/blob/v1.36.10/LICENSE))
|
||||
- [gopkg.in/yaml.v3](https://pkg.go.dev/gopkg.in/yaml.v3) ([MIT](https://github.com/go-yaml/yaml/blob/v3.0.1/LICENSE))
|
||||
- [k8s.io/klog/v2](https://pkg.go.dev/k8s.io/klog/v2) ([Apache-2.0](https://github.com/kubernetes/klog/blob/v2.130.1/LICENSE))
|
||||
|
||||
[cli/cli]: https://github.com/cli/cli
|
||||
|
|
|
|||
202
third-party/cloud.google.com/go/auth/LICENSE
vendored
202
third-party/cloud.google.com/go/auth/LICENSE
vendored
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
202
third-party/cloud.google.com/go/iam/LICENSE
vendored
202
third-party/cloud.google.com/go/iam/LICENSE
vendored
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
202
third-party/cloud.google.com/go/longrunning/LICENSE
vendored
202
third-party/cloud.google.com/go/longrunning/LICENSE
vendored
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
202
third-party/cloud.google.com/go/monitoring/LICENSE
vendored
202
third-party/cloud.google.com/go/monitoring/LICENSE
vendored
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
202
third-party/cloud.google.com/go/spanner/LICENSE
vendored
202
third-party/cloud.google.com/go/spanner/LICENSE
vendored
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
202
third-party/cloud.google.com/go/storage/LICENSE
vendored
202
third-party/cloud.google.com/go/storage/LICENSE
vendored
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
Copyright (c) 2016 Caleb Spare
|
||||
|
||||
MIT License
|
||||
|
||||
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.
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020-2023 Charmbracelet, Inc
|
||||
Copyright (c) 2020-2025 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
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
Copyright 2018 Anders Rundgren
|
||||
|
||||
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
|
||||
|
||||
https://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.
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
Copyright (c) 2016 Felix Geisendörfer (felix@debuggable.com)
|
||||
|
||||
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.
|
||||
25
third-party/github.com/fsnotify/fsnotify/LICENSE
vendored
25
third-party/github.com/fsnotify/fsnotify/LICENSE
vendored
|
|
@ -1,25 +0,0 @@
|
|||
Copyright © 2012 The Go Authors. All rights reserved.
|
||||
Copyright © fsnotify 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 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.
|
||||
20
third-party/github.com/go-chi/chi/v5/LICENSE
vendored
20
third-party/github.com/go-chi/chi/v5/LICENSE
vendored
|
|
@ -1,20 +0,0 @@
|
|||
Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc.
|
||||
|
||||
MIT License
|
||||
|
||||
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.
|
||||
202
third-party/github.com/go-jose/go-jose/v4/LICENSE
vendored
202
third-party/github.com/go-jose/go-jose/v4/LICENSE
vendored
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
Copyright (c) 2012 The Go 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 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.
|
||||
36
third-party/github.com/go-openapi/jsonreference/NOTICE
vendored
Normal file
36
third-party/github.com/go-openapi/jsonreference/NOTICE
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
Copyright 2015-2025 go-swagger maintainers
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
This software library, github.com/go-openapi/jsonpointer, includes software developed
|
||||
by the go-swagger and go-openapi maintainers ("go-swagger maintainers").
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this software except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
This software is copied from, derived from, and inspired by other original software products.
|
||||
It ships with copies of other software which license terms are recalled below.
|
||||
|
||||
The original sofware was authored on 25-02-2013 by sigu-399 (https://github.com/sigu-399, sigu.399@gmail.com).
|
||||
|
||||
github.com/sigh-399/jsonpointer
|
||||
===========================
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
|
||||
|
||||
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.
|
||||
191
third-party/github.com/golang/groupcache/lru/LICENSE
vendored
191
third-party/github.com/golang/groupcache/lru/LICENSE
vendored
|
|
@ -1,191 +0,0 @@
|
|||
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:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of
|
||||
this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
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
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any
|
||||
Derivative Works that You distribute must include a readable copy of the
|
||||
attribution notices contained within such NOTICE file, excluding those notices
|
||||
that do not pertain to any part of the Derivative Works, in at least one of the
|
||||
following places: within a NOTICE text file distributed as part of the
|
||||
Derivative Works; within the Source form or documentation, if provided along
|
||||
with the Derivative Works; or, within a display generated by the Derivative
|
||||
Works, if and wherever such third-party notices normally appear. The contents of
|
||||
the NOTICE file are for informational purposes only and do not modify the
|
||||
License. You may add Your own attribution notices within Derivative Works that
|
||||
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||
provided that such additional attribution notices cannot be construed as
|
||||
modifying the License.
|
||||
You may add Your own copyright statement to Your modifications and may provide
|
||||
additional or different license terms and conditions for use, reproduction, or
|
||||
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||
with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions.
|
||||
|
||||
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
||||
for inclusion in the Work by You to the Licensor shall be under the terms and
|
||||
conditions of this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
||||
any separate license agreement you may have executed with Licensor regarding
|
||||
such Contributions.
|
||||
|
||||
6. Trademarks.
|
||||
|
||||
This License does not grant permission to use the trade names, trademarks,
|
||||
service marks, or product names of the Licensor, except as required for
|
||||
reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, Licensor provides the
|
||||
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
including, without limitation, any warranties or conditions of TITLE,
|
||||
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||
solely responsible for determining the appropriateness of using or
|
||||
redistributing the Work and assume any risks associated with Your exercise of
|
||||
permissions under this License.
|
||||
|
||||
8. Limitation of Liability.
|
||||
|
||||
In no event and under no legal theory, whether in tort (including negligence),
|
||||
contract, or otherwise, unless required by applicable law (such as deliberate
|
||||
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special, incidental,
|
||||
or consequential damages of any character arising as a result of this License or
|
||||
out of the use or inability to use the Work (including but not limited to
|
||||
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||
any and all other commercial damages or losses), even if such Contributor has
|
||||
been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability.
|
||||
|
||||
While redistributing the Work or Derivative Works thereof, You may choose to
|
||||
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
||||
other liability obligations and/or rights consistent with this License. However,
|
||||
in accepting such obligations, You may act only on Your own behalf and on Your
|
||||
sole responsibility, not on behalf of any other Contributor, and only if You
|
||||
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason of your
|
||||
accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate
|
||||
notice, with the fields enclosed by brackets "[]" replaced with your own
|
||||
identifying information. (Don't include the brackets!) The text should be
|
||||
enclosed in the appropriate comment syntax for the file format. We also
|
||||
recommend that a file or class name and description of purpose be included on
|
||||
the same "printed page" as the copyright notice for easier identification within
|
||||
third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
27
third-party/github.com/google/go-cmp/cmp/LICENSE
vendored
27
third-party/github.com/google/go-cmp/cmp/LICENSE
vendored
|
|
@ -1,27 +0,0 @@
|
|||
Copyright (c) 2017 The Go 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 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.
|
||||
202
third-party/github.com/google/s2a-go/LICENSE.md
vendored
202
third-party/github.com/google/s2a-go/LICENSE.md
vendored
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
Copyright 2016, Google Inc.
|
||||
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.
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
tags:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: set up go 1.19
|
||||
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0
|
||||
with:
|
||||
go-version: 1.19
|
||||
id: go
|
||||
|
||||
- name: checkout
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
|
||||
|
||||
- name: build and test
|
||||
run: |
|
||||
go test -timeout=60s -race ./...
|
||||
go build -race ./...
|
||||
|
||||
- name: build and test ARC
|
||||
working-directory: ./arc
|
||||
run: |
|
||||
go test -timeout=60s -race
|
||||
go build -race
|
||||
|
||||
- name: install golangci-lint
|
||||
run: curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $GITHUB_WORKSPACE v1.53.3
|
||||
|
||||
- name: run golangci-lint
|
||||
run: $GITHUB_WORKSPACE/golangci-lint run --out-format=github-actions ./... ./simplelru/... ./expirable/...
|
||||
|
||||
- name: run golangci-lint on ARC
|
||||
working-directory: ./arc
|
||||
run: $GITHUB_WORKSPACE/golangci-lint run --out-format=github-actions ./...
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
linters:
|
||||
fast: false
|
||||
disable-all: true
|
||||
enable:
|
||||
- revive
|
||||
- megacheck
|
||||
- govet
|
||||
- unconvert
|
||||
- gas
|
||||
- gocyclo
|
||||
- dupl
|
||||
- misspell
|
||||
- unparam
|
||||
- unused
|
||||
- typecheck
|
||||
- ineffassign
|
||||
# - stylecheck
|
||||
- exportloopref
|
||||
- gocritic
|
||||
- nakedret
|
||||
- gosimple
|
||||
- prealloc
|
||||
|
||||
# golangci-lint configuration file
|
||||
linters-settings:
|
||||
revive:
|
||||
ignore-generated-header: true
|
||||
severity: warning
|
||||
rules:
|
||||
- name: package-comments
|
||||
severity: warning
|
||||
disabled: true
|
||||
- name: exported
|
||||
severity: warning
|
||||
disabled: false
|
||||
arguments: ["checkPrivateReceivers", "disableStutteringCheck"]
|
||||
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
exclude-rules:
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- dupl
|
||||
267
third-party/github.com/hashicorp/golang-lru/v2/2q.go
vendored
267
third-party/github.com/hashicorp/golang-lru/v2/2q.go
vendored
|
|
@ -1,267 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package lru
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/golang-lru/v2/simplelru"
|
||||
)
|
||||
|
||||
const (
|
||||
// Default2QRecentRatio is the ratio of the 2Q cache dedicated
|
||||
// to recently added entries that have only been accessed once.
|
||||
Default2QRecentRatio = 0.25
|
||||
|
||||
// Default2QGhostEntries is the default ratio of ghost
|
||||
// entries kept to track entries recently evicted
|
||||
Default2QGhostEntries = 0.50
|
||||
)
|
||||
|
||||
// TwoQueueCache is a thread-safe fixed size 2Q cache.
|
||||
// 2Q is an enhancement over the standard LRU cache
|
||||
// in that it tracks both frequently and recently used
|
||||
// entries separately. This avoids a burst in access to new
|
||||
// entries from evicting frequently used entries. It adds some
|
||||
// additional tracking overhead to the standard LRU cache, and is
|
||||
// computationally about 2x the cost, and adds some metadata over
|
||||
// head. The ARCCache is similar, but does not require setting any
|
||||
// parameters.
|
||||
type TwoQueueCache[K comparable, V any] struct {
|
||||
size int
|
||||
recentSize int
|
||||
recentRatio float64
|
||||
ghostRatio float64
|
||||
|
||||
recent simplelru.LRUCache[K, V]
|
||||
frequent simplelru.LRUCache[K, V]
|
||||
recentEvict simplelru.LRUCache[K, struct{}]
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
// New2Q creates a new TwoQueueCache using the default
|
||||
// values for the parameters.
|
||||
func New2Q[K comparable, V any](size int) (*TwoQueueCache[K, V], error) {
|
||||
return New2QParams[K, V](size, Default2QRecentRatio, Default2QGhostEntries)
|
||||
}
|
||||
|
||||
// New2QParams creates a new TwoQueueCache using the provided
|
||||
// parameter values.
|
||||
func New2QParams[K comparable, V any](size int, recentRatio, ghostRatio float64) (*TwoQueueCache[K, V], error) {
|
||||
if size <= 0 {
|
||||
return nil, errors.New("invalid size")
|
||||
}
|
||||
if recentRatio < 0.0 || recentRatio > 1.0 {
|
||||
return nil, errors.New("invalid recent ratio")
|
||||
}
|
||||
if ghostRatio < 0.0 || ghostRatio > 1.0 {
|
||||
return nil, errors.New("invalid ghost ratio")
|
||||
}
|
||||
|
||||
// Determine the sub-sizes
|
||||
recentSize := int(float64(size) * recentRatio)
|
||||
evictSize := int(float64(size) * ghostRatio)
|
||||
|
||||
// Allocate the LRUs
|
||||
recent, err := simplelru.NewLRU[K, V](size, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
frequent, err := simplelru.NewLRU[K, V](size, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
recentEvict, err := simplelru.NewLRU[K, struct{}](evictSize, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Initialize the cache
|
||||
c := &TwoQueueCache[K, V]{
|
||||
size: size,
|
||||
recentSize: recentSize,
|
||||
recentRatio: recentRatio,
|
||||
ghostRatio: ghostRatio,
|
||||
recent: recent,
|
||||
frequent: frequent,
|
||||
recentEvict: recentEvict,
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Get looks up a key's value from the cache.
|
||||
func (c *TwoQueueCache[K, V]) Get(key K) (value V, ok bool) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
// Check if this is a frequent value
|
||||
if val, ok := c.frequent.Get(key); ok {
|
||||
return val, ok
|
||||
}
|
||||
|
||||
// If the value is contained in recent, then we
|
||||
// promote it to frequent
|
||||
if val, ok := c.recent.Peek(key); ok {
|
||||
c.recent.Remove(key)
|
||||
c.frequent.Add(key, val)
|
||||
return val, ok
|
||||
}
|
||||
|
||||
// No hit
|
||||
return
|
||||
}
|
||||
|
||||
// Add adds a value to the cache.
|
||||
func (c *TwoQueueCache[K, V]) Add(key K, value V) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
// Check if the value is frequently used already,
|
||||
// and just update the value
|
||||
if c.frequent.Contains(key) {
|
||||
c.frequent.Add(key, value)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the value is recently used, and promote
|
||||
// the value into the frequent list
|
||||
if c.recent.Contains(key) {
|
||||
c.recent.Remove(key)
|
||||
c.frequent.Add(key, value)
|
||||
return
|
||||
}
|
||||
|
||||
// If the value was recently evicted, add it to the
|
||||
// frequently used list
|
||||
if c.recentEvict.Contains(key) {
|
||||
c.ensureSpace(true)
|
||||
c.recentEvict.Remove(key)
|
||||
c.frequent.Add(key, value)
|
||||
return
|
||||
}
|
||||
|
||||
// Add to the recently seen list
|
||||
c.ensureSpace(false)
|
||||
c.recent.Add(key, value)
|
||||
}
|
||||
|
||||
// ensureSpace is used to ensure we have space in the cache
|
||||
func (c *TwoQueueCache[K, V]) ensureSpace(recentEvict bool) {
|
||||
// If we have space, nothing to do
|
||||
recentLen := c.recent.Len()
|
||||
freqLen := c.frequent.Len()
|
||||
if recentLen+freqLen < c.size {
|
||||
return
|
||||
}
|
||||
|
||||
// If the recent buffer is larger than
|
||||
// the target, evict from there
|
||||
if recentLen > 0 && (recentLen > c.recentSize || (recentLen == c.recentSize && !recentEvict)) {
|
||||
k, _, _ := c.recent.RemoveOldest()
|
||||
c.recentEvict.Add(k, struct{}{})
|
||||
return
|
||||
}
|
||||
|
||||
// Remove from the frequent list otherwise
|
||||
c.frequent.RemoveOldest()
|
||||
}
|
||||
|
||||
// Len returns the number of items in the cache.
|
||||
func (c *TwoQueueCache[K, V]) Len() int {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.recent.Len() + c.frequent.Len()
|
||||
}
|
||||
|
||||
// Resize changes the cache size.
|
||||
func (c *TwoQueueCache[K, V]) Resize(size int) (evicted int) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
// Recalculate the sub-sizes
|
||||
recentSize := int(float64(size) * c.recentRatio)
|
||||
evictSize := int(float64(size) * c.ghostRatio)
|
||||
c.size = size
|
||||
c.recentSize = recentSize
|
||||
|
||||
// ensureSpace
|
||||
diff := c.recent.Len() + c.frequent.Len() - size
|
||||
if diff < 0 {
|
||||
diff = 0
|
||||
}
|
||||
for i := 0; i < diff; i++ {
|
||||
c.ensureSpace(true)
|
||||
}
|
||||
|
||||
// Reallocate the LRUs
|
||||
c.recent.Resize(size)
|
||||
c.frequent.Resize(size)
|
||||
c.recentEvict.Resize(evictSize)
|
||||
|
||||
return diff
|
||||
}
|
||||
|
||||
// Keys returns a slice of the keys in the cache.
|
||||
// The frequently used keys are first in the returned slice.
|
||||
func (c *TwoQueueCache[K, V]) Keys() []K {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
k1 := c.frequent.Keys()
|
||||
k2 := c.recent.Keys()
|
||||
return append(k1, k2...)
|
||||
}
|
||||
|
||||
// Values returns a slice of the values in the cache.
|
||||
// The frequently used values are first in the returned slice.
|
||||
func (c *TwoQueueCache[K, V]) Values() []V {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
v1 := c.frequent.Values()
|
||||
v2 := c.recent.Values()
|
||||
return append(v1, v2...)
|
||||
}
|
||||
|
||||
// Remove removes the provided key from the cache.
|
||||
func (c *TwoQueueCache[K, V]) Remove(key K) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
if c.frequent.Remove(key) {
|
||||
return
|
||||
}
|
||||
if c.recent.Remove(key) {
|
||||
return
|
||||
}
|
||||
if c.recentEvict.Remove(key) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Purge is used to completely clear the cache.
|
||||
func (c *TwoQueueCache[K, V]) Purge() {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
c.recent.Purge()
|
||||
c.frequent.Purge()
|
||||
c.recentEvict.Purge()
|
||||
}
|
||||
|
||||
// Contains is used to check if the cache contains a key
|
||||
// without updating recency or frequency.
|
||||
func (c *TwoQueueCache[K, V]) Contains(key K) bool {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.frequent.Contains(key) || c.recent.Contains(key)
|
||||
}
|
||||
|
||||
// Peek is used to inspect the cache value of a key
|
||||
// without updating recency or frequency.
|
||||
func (c *TwoQueueCache[K, V]) Peek(key K) (value V, ok bool) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
if val, ok := c.frequent.Peek(key); ok {
|
||||
return val, ok
|
||||
}
|
||||
return c.recent.Peek(key)
|
||||
}
|
||||
|
|
@ -1,375 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package lru
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Benchmark2Q_Rand(b *testing.B) {
|
||||
l, err := New2Q[int64, int64](8192)
|
||||
if err != nil {
|
||||
b.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
trace[i] = getRand(b) % 32768
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
var hit, miss int
|
||||
for i := 0; i < 2*b.N; i++ {
|
||||
if i%2 == 0 {
|
||||
l.Add(trace[i], trace[i])
|
||||
} else {
|
||||
if _, ok := l.Get(trace[i]); ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(hit+miss))
|
||||
}
|
||||
|
||||
func Benchmark2Q_Freq(b *testing.B) {
|
||||
l, err := New2Q[int64, int64](8192)
|
||||
if err != nil {
|
||||
b.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
if i%2 == 0 {
|
||||
trace[i] = getRand(b) % 16384
|
||||
} else {
|
||||
trace[i] = getRand(b) % 32768
|
||||
}
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
l.Add(trace[i], trace[i])
|
||||
}
|
||||
var hit, miss int
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, ok := l.Get(trace[i]); ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(hit+miss))
|
||||
}
|
||||
|
||||
func Test2Q_RandomOps(t *testing.T) {
|
||||
size := 128
|
||||
l, err := New2Q[int64, int64](128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
n := 200000
|
||||
for i := 0; i < n; i++ {
|
||||
key := getRand(t) % 512
|
||||
r := getRand(t)
|
||||
switch r % 3 {
|
||||
case 0:
|
||||
l.Add(key, key)
|
||||
case 1:
|
||||
l.Get(key)
|
||||
case 2:
|
||||
l.Remove(key)
|
||||
}
|
||||
|
||||
if l.recent.Len()+l.frequent.Len() > size {
|
||||
t.Fatalf("bad: recent: %d freq: %d",
|
||||
l.recent.Len(), l.frequent.Len())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test2Q_Get_RecentToFrequent(t *testing.T) {
|
||||
l, err := New2Q[int, int](128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Touch all the entries, should be in t1
|
||||
for i := 0; i < 128; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
if n := l.recent.Len(); n != 128 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Get should upgrade to t2
|
||||
for i := 0; i < 128; i++ {
|
||||
if _, ok := l.Get(i); !ok {
|
||||
t.Fatalf("missing: %d", i)
|
||||
}
|
||||
}
|
||||
if n := l.recent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 128 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Get be from t2
|
||||
for i := 0; i < 128; i++ {
|
||||
if _, ok := l.Get(i); !ok {
|
||||
t.Fatalf("missing: %d", i)
|
||||
}
|
||||
}
|
||||
if n := l.recent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 128 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func Test2Q_Add_RecentToFrequent(t *testing.T) {
|
||||
l, err := New2Q[int, int](128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Add initially to recent
|
||||
l.Add(1, 1)
|
||||
if n := l.recent.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Add should upgrade to frequent
|
||||
l.Add(1, 1)
|
||||
if n := l.recent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Add should remain in frequent
|
||||
l.Add(1, 1)
|
||||
if n := l.recent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func Test2Q_Add_RecentEvict(t *testing.T) {
|
||||
l, err := New2Q[int, int](4)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Add 1,2,3,4,5 -> Evict 1
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
l.Add(3, 3)
|
||||
l.Add(4, 4)
|
||||
l.Add(5, 5)
|
||||
if n := l.recent.Len(); n != 4 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.recentEvict.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Pull in the recently evicted
|
||||
l.Add(1, 1)
|
||||
if n := l.recent.Len(); n != 3 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.recentEvict.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Add 6, should cause another recent evict
|
||||
l.Add(6, 6)
|
||||
if n := l.recent.Len(); n != 3 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.recentEvict.Len(); n != 2 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func Test2Q_Resize(t *testing.T) {
|
||||
l, err := New2Q[int, int](100)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Touch all the entries, should be in t1
|
||||
for i := 0; i < 100; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
|
||||
evicted := l.Resize(50)
|
||||
if evicted != 50 {
|
||||
t.Fatalf("bad: %d", evicted)
|
||||
}
|
||||
|
||||
if n := l.recent.Len(); n != 50 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
l, err = New2Q[int, int](100)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
for i := 0; i < 100; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
|
||||
evicted = l.Resize(50)
|
||||
if evicted != 50 {
|
||||
t.Fatalf("bad: %d", evicted)
|
||||
}
|
||||
|
||||
if n := l.recent.Len(); n != 12 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 38 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
l, err = New2Q[int, int](100)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
for i := 0; i < 100; i++ {
|
||||
l.Add(i, i)
|
||||
l.Add(i, i)
|
||||
}
|
||||
|
||||
evicted = l.Resize(50)
|
||||
if evicted != 50 {
|
||||
t.Fatalf("bad: %d", evicted)
|
||||
}
|
||||
|
||||
if n := l.recent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 50 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func Test2Q(t *testing.T) {
|
||||
l, err := New2Q[int, int](128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
if l.Len() != 128 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
|
||||
for i, k := range l.Keys() {
|
||||
if v, ok := l.Get(k); !ok || v != k || v != i+128 {
|
||||
t.Fatalf("bad key: %v", k)
|
||||
}
|
||||
}
|
||||
for i, v := range l.Values() {
|
||||
if v != i+128 {
|
||||
t.Fatalf("bad key: %v", v)
|
||||
}
|
||||
}
|
||||
for i := 0; i < 128; i++ {
|
||||
if _, ok := l.Get(i); ok {
|
||||
t.Fatalf("should be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 256; i++ {
|
||||
if _, ok := l.Get(i); !ok {
|
||||
t.Fatalf("should not be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 192; i++ {
|
||||
l.Remove(i)
|
||||
if _, ok := l.Get(i); ok {
|
||||
t.Fatalf("should be deleted")
|
||||
}
|
||||
}
|
||||
|
||||
l.Purge()
|
||||
if l.Len() != 0 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
if _, ok := l.Get(200); ok {
|
||||
t.Fatalf("should contain nothing")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Contains doesn't update recent-ness
|
||||
func Test2Q_Contains(t *testing.T) {
|
||||
l, err := New2Q[int, int](2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if !l.Contains(1) {
|
||||
t.Errorf("1 should be contained")
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("Contains should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Peek doesn't update recent-ness
|
||||
func Test2Q_Peek(t *testing.T) {
|
||||
l, err := New2Q[int, int](2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if v, ok := l.Peek(1); !ok || v != 1 {
|
||||
t.Errorf("1 should be set to 1: %v, %v", v, ok)
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,364 +0,0 @@
|
|||
Copyright (c) 2014 HashiCorp, Inc.
|
||||
|
||||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. "Contributor"
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the terms of
|
||||
a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
|
||||
means a work that combines Covered Software with other material, in a
|
||||
separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether
|
||||
at the time of the initial grant or subsequently, any and all of the
|
||||
rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the License,
|
||||
by the making, using, selling, offering for sale, having made, import,
|
||||
or transfer of either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, "control" means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights to
|
||||
grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter the
|
||||
recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty, or
|
||||
limitations of liability) contained within the Source Code Form of the
|
||||
Covered Software, except that You may alter any license notices to the
|
||||
extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute,
|
||||
judicial order, or regulation then You must: (a) comply with the terms of
|
||||
this License to the maximum extent possible; and (b) describe the
|
||||
limitations and the code they affect. Such description must be placed in a
|
||||
text file included with all distributions of the Covered Software under
|
||||
this License. Except to the extent prohibited by statute or regulation,
|
||||
such description must be sufficiently detailed for a recipient of ordinary
|
||||
skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing
|
||||
basis, if such Contributor fails to notify You of the non-compliance by
|
||||
some reasonable means prior to 60 days after You have come back into
|
||||
compliance. Moreover, Your grants from a particular Contributor are
|
||||
reinstated on an ongoing basis if such Contributor notifies You of the
|
||||
non-compliance by some reasonable means, this is the first time You have
|
||||
received notice of non-compliance with this License from such
|
||||
Contributor, and You become compliant prior to 30 days after Your receipt
|
||||
of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an "as is" basis,
|
||||
without warranty of any kind, either expressed, implied, or statutory,
|
||||
including, without limitation, warranties that the Covered Software is free
|
||||
of defects, merchantable, fit for a particular purpose or non-infringing.
|
||||
The entire risk as to the quality and performance of the Covered Software
|
||||
is with You. Should any Covered Software prove defective in any respect,
|
||||
You (not any Contributor) assume the cost of any necessary servicing,
|
||||
repair, or correction. This disclaimer of warranty constitutes an essential
|
||||
part of this License. No use of any Covered Software is authorized under
|
||||
this License except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from
|
||||
such party's negligence to the extent applicable law prohibits such
|
||||
limitation. Some jurisdictions do not allow the exclusion or limitation of
|
||||
incidental or consequential damages, so this exclusion and limitation may
|
||||
not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts
|
||||
of a jurisdiction where the defendant maintains its principal place of
|
||||
business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions. Nothing
|
||||
in this Section shall prevent a party's ability to bring cross-claims or
|
||||
counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides that
|
||||
the language of a contract shall be construed against the drafter shall not
|
||||
be used to construe this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses If You choose to distribute Source Code Form that is
|
||||
Incompatible With Secondary Licenses under the terms of this version of
|
||||
the License, the notice described in Exhibit B of this License must be
|
||||
attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file,
|
||||
then You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a
|
||||
notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
|
||||
This Source Code Form is "Incompatible
|
||||
With Secondary Licenses", as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
golang-lru
|
||||
==========
|
||||
|
||||
This provides the `lru` package which implements a fixed-size
|
||||
thread safe LRU cache. It is based on the cache in Groupcache.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
Full docs are available on [Go Packages](https://pkg.go.dev/github.com/hashicorp/golang-lru/v2)
|
||||
|
||||
LRU cache example
|
||||
=================
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/golang-lru/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
l, _ := lru.New[int, any](128)
|
||||
for i := 0; i < 256; i++ {
|
||||
l.Add(i, nil)
|
||||
}
|
||||
if l.Len() != 128 {
|
||||
panic(fmt.Sprintf("bad len: %v", l.Len()))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Expirable LRU cache example
|
||||
===========================
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/golang-lru/v2/expirable"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// make cache with 10ms TTL and 5 max keys
|
||||
cache := expirable.NewLRU[string, string](5, nil, time.Millisecond*10)
|
||||
|
||||
|
||||
// set value under key1.
|
||||
cache.Add("key1", "val1")
|
||||
|
||||
// get value under key1
|
||||
r, ok := cache.Get("key1")
|
||||
|
||||
// check for OK value
|
||||
if ok {
|
||||
fmt.Printf("value before expiration is found: %v, value: %q\n", ok, r)
|
||||
}
|
||||
|
||||
// wait for cache to expire
|
||||
time.Sleep(time.Millisecond * 12)
|
||||
|
||||
// get value under key1 after key expiration
|
||||
r, ok = cache.Get("key1")
|
||||
fmt.Printf("value after expiration is found: %v, value: %q\n", ok, r)
|
||||
|
||||
// set value under key2, would evict old entry because it is already expired.
|
||||
cache.Add("key2", "val2")
|
||||
|
||||
fmt.Printf("Cache len: %d\n", cache.Len())
|
||||
// Output:
|
||||
// value before expiration is found: true, value: "val1"
|
||||
// value after expiration is found: false, value: ""
|
||||
// Cache len: 1
|
||||
}
|
||||
```
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
// Package lru provides three different LRU caches of varying sophistication.
|
||||
//
|
||||
// Cache is a simple LRU cache. It is based on the LRU implementation in
|
||||
// groupcache: https://github.com/golang/groupcache/tree/master/lru
|
||||
//
|
||||
// TwoQueueCache tracks frequently used and recently used entries separately.
|
||||
// This avoids a burst of accesses from taking out frequently used entries, at
|
||||
// the cost of about 2x computational overhead and some extra bookkeeping.
|
||||
//
|
||||
// ARCCache is an adaptive replacement cache. It tracks recent evictions as well
|
||||
// as recent usage in both the frequent and recent caches. Its computational
|
||||
// overhead is comparable to TwoQueueCache, but the memory overhead is linear
|
||||
// with the size of the cache.
|
||||
//
|
||||
// ARC has been patented by IBM, so do not use it if that is problematic for
|
||||
// your program. For this reason, it is in a separate go module contained within
|
||||
// this repository.
|
||||
//
|
||||
// All caches in this package take locks while operating, and are therefore
|
||||
// thread-safe for consumers.
|
||||
package lru
|
||||
|
|
@ -1,338 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package expirable
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/golang-lru/v2/internal"
|
||||
)
|
||||
|
||||
// EvictCallback is used to get a callback when a cache entry is evicted
|
||||
type EvictCallback[K comparable, V any] func(key K, value V)
|
||||
|
||||
// LRU implements a thread-safe LRU with expirable entries.
|
||||
type LRU[K comparable, V any] struct {
|
||||
size int
|
||||
evictList *internal.LruList[K, V]
|
||||
items map[K]*internal.Entry[K, V]
|
||||
onEvict EvictCallback[K, V]
|
||||
|
||||
// expirable options
|
||||
mu sync.Mutex
|
||||
ttl time.Duration
|
||||
done chan struct{}
|
||||
|
||||
// buckets for expiration
|
||||
buckets []bucket[K, V]
|
||||
// uint8 because it's number between 0 and numBuckets
|
||||
nextCleanupBucket uint8
|
||||
}
|
||||
|
||||
// bucket is a container for holding entries to be expired
|
||||
type bucket[K comparable, V any] struct {
|
||||
entries map[K]*internal.Entry[K, V]
|
||||
newestEntry time.Time
|
||||
}
|
||||
|
||||
// noEvictionTTL - very long ttl to prevent eviction
|
||||
const noEvictionTTL = time.Hour * 24 * 365 * 10
|
||||
|
||||
// because of uint8 usage for nextCleanupBucket, should not exceed 256.
|
||||
// casting it as uint8 explicitly requires type conversions in multiple places
|
||||
const numBuckets = 100
|
||||
|
||||
// NewLRU returns a new thread-safe cache with expirable entries.
|
||||
//
|
||||
// Size parameter set to 0 makes cache of unlimited size, e.g. turns LRU mechanism off.
|
||||
//
|
||||
// Providing 0 TTL turns expiring off.
|
||||
//
|
||||
// Delete expired entries every 1/100th of ttl value. Goroutine which deletes expired entries runs indefinitely.
|
||||
func NewLRU[K comparable, V any](size int, onEvict EvictCallback[K, V], ttl time.Duration) *LRU[K, V] {
|
||||
if size < 0 {
|
||||
size = 0
|
||||
}
|
||||
if ttl <= 0 {
|
||||
ttl = noEvictionTTL
|
||||
}
|
||||
|
||||
res := LRU[K, V]{
|
||||
ttl: ttl,
|
||||
size: size,
|
||||
evictList: internal.NewList[K, V](),
|
||||
items: make(map[K]*internal.Entry[K, V]),
|
||||
onEvict: onEvict,
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
|
||||
// initialize the buckets
|
||||
res.buckets = make([]bucket[K, V], numBuckets)
|
||||
for i := 0; i < numBuckets; i++ {
|
||||
res.buckets[i] = bucket[K, V]{entries: make(map[K]*internal.Entry[K, V])}
|
||||
}
|
||||
|
||||
// enable deleteExpired() running in separate goroutine for cache with non-zero TTL
|
||||
//
|
||||
// Important: done channel is never closed, so deleteExpired() goroutine will never exit,
|
||||
// it's decided to add functionality to close it in the version later than v2.
|
||||
if res.ttl != noEvictionTTL {
|
||||
go func(done <-chan struct{}) {
|
||||
ticker := time.NewTicker(res.ttl / numBuckets)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
case <-ticker.C:
|
||||
res.deleteExpired()
|
||||
}
|
||||
}
|
||||
}(res.done)
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
// Purge clears the cache completely.
|
||||
// onEvict is called for each evicted key.
|
||||
func (c *LRU[K, V]) Purge() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
for k, v := range c.items {
|
||||
if c.onEvict != nil {
|
||||
c.onEvict(k, v.Value)
|
||||
}
|
||||
delete(c.items, k)
|
||||
}
|
||||
for _, b := range c.buckets {
|
||||
for _, ent := range b.entries {
|
||||
delete(b.entries, ent.Key)
|
||||
}
|
||||
}
|
||||
c.evictList.Init()
|
||||
}
|
||||
|
||||
// Add adds a value to the cache. Returns true if an eviction occurred.
|
||||
// Returns false if there was no eviction: the item was already in the cache,
|
||||
// or the size was not exceeded.
|
||||
func (c *LRU[K, V]) Add(key K, value V) (evicted bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
now := time.Now()
|
||||
|
||||
// Check for existing item
|
||||
if ent, ok := c.items[key]; ok {
|
||||
c.evictList.MoveToFront(ent)
|
||||
c.removeFromBucket(ent) // remove the entry from its current bucket as expiresAt is renewed
|
||||
ent.Value = value
|
||||
ent.ExpiresAt = now.Add(c.ttl)
|
||||
c.addToBucket(ent)
|
||||
return false
|
||||
}
|
||||
|
||||
// Add new item
|
||||
ent := c.evictList.PushFrontExpirable(key, value, now.Add(c.ttl))
|
||||
c.items[key] = ent
|
||||
c.addToBucket(ent) // adds the entry to the appropriate bucket and sets entry.expireBucket
|
||||
|
||||
evict := c.size > 0 && c.evictList.Length() > c.size
|
||||
// Verify size not exceeded
|
||||
if evict {
|
||||
c.removeOldest()
|
||||
}
|
||||
return evict
|
||||
}
|
||||
|
||||
// Get looks up a key's value from the cache.
|
||||
func (c *LRU[K, V]) Get(key K) (value V, ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
var ent *internal.Entry[K, V]
|
||||
if ent, ok = c.items[key]; ok {
|
||||
// Expired item check
|
||||
if time.Now().After(ent.ExpiresAt) {
|
||||
return value, false
|
||||
}
|
||||
c.evictList.MoveToFront(ent)
|
||||
return ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Contains checks if a key is in the cache, without updating the recent-ness
|
||||
// or deleting it for being stale.
|
||||
func (c *LRU[K, V]) Contains(key K) (ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
_, ok = c.items[key]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Peek returns the key value (or undefined if not found) without updating
|
||||
// the "recently used"-ness of the key.
|
||||
func (c *LRU[K, V]) Peek(key K) (value V, ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
var ent *internal.Entry[K, V]
|
||||
if ent, ok = c.items[key]; ok {
|
||||
// Expired item check
|
||||
if time.Now().After(ent.ExpiresAt) {
|
||||
return value, false
|
||||
}
|
||||
return ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Remove removes the provided key from the cache, returning if the
|
||||
// key was contained.
|
||||
func (c *LRU[K, V]) Remove(key K) bool {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if ent, ok := c.items[key]; ok {
|
||||
c.removeElement(ent)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// RemoveOldest removes the oldest item from the cache.
|
||||
func (c *LRU[K, V]) RemoveOldest() (key K, value V, ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if ent := c.evictList.Back(); ent != nil {
|
||||
c.removeElement(ent)
|
||||
return ent.Key, ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetOldest returns the oldest entry
|
||||
func (c *LRU[K, V]) GetOldest() (key K, value V, ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if ent := c.evictList.Back(); ent != nil {
|
||||
return ent.Key, ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Keys returns a slice of the keys in the cache, from oldest to newest.
|
||||
func (c *LRU[K, V]) Keys() []K {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
keys := make([]K, 0, len(c.items))
|
||||
for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() {
|
||||
keys = append(keys, ent.Key)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// Values returns a slice of the values in the cache, from oldest to newest.
|
||||
// Expired entries are filtered out.
|
||||
func (c *LRU[K, V]) Values() []V {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
values := make([]V, len(c.items))
|
||||
i := 0
|
||||
now := time.Now()
|
||||
for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() {
|
||||
if now.After(ent.ExpiresAt) {
|
||||
continue
|
||||
}
|
||||
values[i] = ent.Value
|
||||
i++
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// Len returns the number of items in the cache.
|
||||
func (c *LRU[K, V]) Len() int {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.evictList.Length()
|
||||
}
|
||||
|
||||
// Resize changes the cache size. Size of 0 means unlimited.
|
||||
func (c *LRU[K, V]) Resize(size int) (evicted int) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if size <= 0 {
|
||||
c.size = 0
|
||||
return 0
|
||||
}
|
||||
diff := c.evictList.Length() - size
|
||||
if diff < 0 {
|
||||
diff = 0
|
||||
}
|
||||
for i := 0; i < diff; i++ {
|
||||
c.removeOldest()
|
||||
}
|
||||
c.size = size
|
||||
return diff
|
||||
}
|
||||
|
||||
// Close destroys cleanup goroutine. To clean up the cache, run Purge() before Close().
|
||||
// func (c *LRU[K, V]) Close() {
|
||||
// c.mu.Lock()
|
||||
// defer c.mu.Unlock()
|
||||
// select {
|
||||
// case <-c.done:
|
||||
// return
|
||||
// default:
|
||||
// }
|
||||
// close(c.done)
|
||||
// }
|
||||
|
||||
// removeOldest removes the oldest item from the cache. Has to be called with lock!
|
||||
func (c *LRU[K, V]) removeOldest() {
|
||||
if ent := c.evictList.Back(); ent != nil {
|
||||
c.removeElement(ent)
|
||||
}
|
||||
}
|
||||
|
||||
// removeElement is used to remove a given list element from the cache. Has to be called with lock!
|
||||
func (c *LRU[K, V]) removeElement(e *internal.Entry[K, V]) {
|
||||
c.evictList.Remove(e)
|
||||
delete(c.items, e.Key)
|
||||
c.removeFromBucket(e)
|
||||
if c.onEvict != nil {
|
||||
c.onEvict(e.Key, e.Value)
|
||||
}
|
||||
}
|
||||
|
||||
// deleteExpired deletes expired records from the oldest bucket, waiting for the newest entry
|
||||
// in it to expire first.
|
||||
func (c *LRU[K, V]) deleteExpired() {
|
||||
c.mu.Lock()
|
||||
bucketIdx := c.nextCleanupBucket
|
||||
timeToExpire := time.Until(c.buckets[bucketIdx].newestEntry)
|
||||
// wait for newest entry to expire before cleanup without holding lock
|
||||
if timeToExpire > 0 {
|
||||
c.mu.Unlock()
|
||||
time.Sleep(timeToExpire)
|
||||
c.mu.Lock()
|
||||
}
|
||||
for _, ent := range c.buckets[bucketIdx].entries {
|
||||
c.removeElement(ent)
|
||||
}
|
||||
c.nextCleanupBucket = (c.nextCleanupBucket + 1) % numBuckets
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
// addToBucket adds entry to expire bucket so that it will be cleaned up when the time comes. Has to be called with lock!
|
||||
func (c *LRU[K, V]) addToBucket(e *internal.Entry[K, V]) {
|
||||
bucketID := (numBuckets + c.nextCleanupBucket - 1) % numBuckets
|
||||
e.ExpireBucket = bucketID
|
||||
c.buckets[bucketID].entries[e.Key] = e
|
||||
if c.buckets[bucketID].newestEntry.Before(e.ExpiresAt) {
|
||||
c.buckets[bucketID].newestEntry = e.ExpiresAt
|
||||
}
|
||||
}
|
||||
|
||||
// removeFromBucket removes the entry from its corresponding bucket. Has to be called with lock!
|
||||
func (c *LRU[K, V]) removeFromBucket(e *internal.Entry[K, V]) {
|
||||
delete(c.buckets[e.ExpireBucket].entries, e.Key)
|
||||
}
|
||||
|
|
@ -1,573 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package expirable
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/golang-lru/v2/simplelru"
|
||||
)
|
||||
|
||||
func BenchmarkLRU_Rand_NoExpire(b *testing.B) {
|
||||
l := NewLRU[int64, int64](8192, nil, 0)
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
trace[i] = getRand(b) % 32768
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
var hit, miss int
|
||||
for i := 0; i < 2*b.N; i++ {
|
||||
if i%2 == 0 {
|
||||
l.Add(trace[i], trace[i])
|
||||
} else {
|
||||
if _, ok := l.Get(trace[i]); ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(hit+miss))
|
||||
}
|
||||
|
||||
func BenchmarkLRU_Freq_NoExpire(b *testing.B) {
|
||||
l := NewLRU[int64, int64](8192, nil, 0)
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
if i%2 == 0 {
|
||||
trace[i] = getRand(b) % 16384
|
||||
} else {
|
||||
trace[i] = getRand(b) % 32768
|
||||
}
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
l.Add(trace[i], trace[i])
|
||||
}
|
||||
var hit, miss int
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, ok := l.Get(trace[i]); ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(hit+miss))
|
||||
}
|
||||
|
||||
func BenchmarkLRU_Rand_WithExpire(b *testing.B) {
|
||||
l := NewLRU[int64, int64](8192, nil, time.Millisecond*10)
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
trace[i] = getRand(b) % 32768
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
var hit, miss int
|
||||
for i := 0; i < 2*b.N; i++ {
|
||||
if i%2 == 0 {
|
||||
l.Add(trace[i], trace[i])
|
||||
} else {
|
||||
if _, ok := l.Get(trace[i]); ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(hit+miss))
|
||||
}
|
||||
|
||||
func BenchmarkLRU_Freq_WithExpire(b *testing.B) {
|
||||
l := NewLRU[int64, int64](8192, nil, time.Millisecond*10)
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
if i%2 == 0 {
|
||||
trace[i] = getRand(b) % 16384
|
||||
} else {
|
||||
trace[i] = getRand(b) % 32768
|
||||
}
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
l.Add(trace[i], trace[i])
|
||||
}
|
||||
var hit, miss int
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, ok := l.Get(trace[i]); ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(hit+miss))
|
||||
}
|
||||
|
||||
func TestLRUInterface(_ *testing.T) {
|
||||
var _ simplelru.LRUCache[int, int] = &LRU[int, int]{}
|
||||
}
|
||||
|
||||
func TestLRUNoPurge(t *testing.T) {
|
||||
lc := NewLRU[string, string](10, nil, 0)
|
||||
|
||||
lc.Add("key1", "val1")
|
||||
if lc.Len() != 1 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
|
||||
v, ok := lc.Peek("key1")
|
||||
if v != "val1" {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if !ok {
|
||||
t.Fatalf("should be true")
|
||||
}
|
||||
|
||||
if !lc.Contains("key1") {
|
||||
t.Fatalf("should contain key1")
|
||||
}
|
||||
if lc.Contains("key2") {
|
||||
t.Fatalf("should not contain key2")
|
||||
}
|
||||
|
||||
v, ok = lc.Peek("key2")
|
||||
if v != "" {
|
||||
t.Fatalf("should be empty")
|
||||
}
|
||||
if ok {
|
||||
t.Fatalf("should be false")
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(lc.Keys(), []string{"key1"}) {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
|
||||
if lc.Resize(0) != 0 {
|
||||
t.Fatalf("evicted count differs from expected")
|
||||
}
|
||||
if lc.Resize(2) != 0 {
|
||||
t.Fatalf("evicted count differs from expected")
|
||||
}
|
||||
lc.Add("key2", "val2")
|
||||
if lc.Resize(1) != 1 {
|
||||
t.Fatalf("evicted count differs from expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLRUEdgeCases(t *testing.T) {
|
||||
lc := NewLRU[string, *string](2, nil, 0)
|
||||
|
||||
// Adding a nil value
|
||||
lc.Add("key1", nil)
|
||||
|
||||
value, exists := lc.Get("key1")
|
||||
if value != nil || !exists {
|
||||
t.Fatalf("unexpected value or existence flag for key1: value=%v, exists=%v", value, exists)
|
||||
}
|
||||
|
||||
// Adding an entry with the same key but different value
|
||||
newVal := "val1"
|
||||
lc.Add("key1", &newVal)
|
||||
|
||||
value, exists = lc.Get("key1")
|
||||
if value != &newVal || !exists {
|
||||
t.Fatalf("unexpected value or existence flag for key1: value=%v, exists=%v", value, exists)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLRU_Values(t *testing.T) {
|
||||
lc := NewLRU[string, string](3, nil, 0)
|
||||
|
||||
lc.Add("key1", "val1")
|
||||
lc.Add("key2", "val2")
|
||||
lc.Add("key3", "val3")
|
||||
|
||||
values := lc.Values()
|
||||
if !reflect.DeepEqual(values, []string{"val1", "val2", "val3"}) {
|
||||
t.Fatalf("values differs from expected")
|
||||
}
|
||||
}
|
||||
|
||||
// func TestExpirableMultipleClose(_ *testing.T) {
|
||||
// lc := NewLRU[string, string](10, nil, 0)
|
||||
// lc.Close()
|
||||
// // should not panic
|
||||
// lc.Close()
|
||||
// }
|
||||
|
||||
func TestLRUWithPurge(t *testing.T) {
|
||||
var evicted []string
|
||||
lc := NewLRU(10, func(key string, value string) { evicted = append(evicted, key, value) }, 150*time.Millisecond)
|
||||
|
||||
k, v, ok := lc.GetOldest()
|
||||
if k != "" {
|
||||
t.Fatalf("should be empty")
|
||||
}
|
||||
if v != "" {
|
||||
t.Fatalf("should be empty")
|
||||
}
|
||||
if ok {
|
||||
t.Fatalf("should be false")
|
||||
}
|
||||
|
||||
lc.Add("key1", "val1")
|
||||
|
||||
time.Sleep(100 * time.Millisecond) // not enough to expire
|
||||
if lc.Len() != 1 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
|
||||
v, ok = lc.Get("key1")
|
||||
if v != "val1" {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if !ok {
|
||||
t.Fatalf("should be true")
|
||||
}
|
||||
|
||||
time.Sleep(200 * time.Millisecond) // expire
|
||||
v, ok = lc.Get("key1")
|
||||
if ok {
|
||||
t.Fatalf("should be false")
|
||||
}
|
||||
if v != "" {
|
||||
t.Fatalf("should be nil")
|
||||
}
|
||||
|
||||
if lc.Len() != 0 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
if !reflect.DeepEqual(evicted, []string{"key1", "val1"}) {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
|
||||
// add new entry
|
||||
lc.Add("key2", "val2")
|
||||
if lc.Len() != 1 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
|
||||
k, v, ok = lc.GetOldest()
|
||||
if k != "key2" {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if v != "val2" {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if !ok {
|
||||
t.Fatalf("should be true")
|
||||
}
|
||||
|
||||
// DeleteExpired, nothing deleted
|
||||
lc.deleteExpired()
|
||||
if lc.Len() != 1 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
if !reflect.DeepEqual(evicted, []string{"key1", "val1"}) {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
|
||||
// Purge, cache should be clean
|
||||
lc.Purge()
|
||||
if lc.Len() != 0 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
if !reflect.DeepEqual(evicted, []string{"key1", "val1", "key2", "val2"}) {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLRUWithPurgeEnforcedBySize(t *testing.T) {
|
||||
lc := NewLRU[string, string](10, nil, time.Hour)
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
i := i
|
||||
lc.Add(fmt.Sprintf("key%d", i), fmt.Sprintf("val%d", i))
|
||||
v, ok := lc.Get(fmt.Sprintf("key%d", i))
|
||||
if v != fmt.Sprintf("val%d", i) {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if !ok {
|
||||
t.Fatalf("should be true")
|
||||
}
|
||||
if lc.Len() > 20 {
|
||||
t.Fatalf("length should be less than 20")
|
||||
}
|
||||
}
|
||||
|
||||
if lc.Len() != 10 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLRUConcurrency(t *testing.T) {
|
||||
lc := NewLRU[string, string](0, nil, 0)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1000)
|
||||
for i := 0; i < 1000; i++ {
|
||||
go func(i int) {
|
||||
lc.Add(fmt.Sprintf("key-%d", i/10), fmt.Sprintf("val-%d", i/10))
|
||||
wg.Done()
|
||||
}(i)
|
||||
}
|
||||
wg.Wait()
|
||||
if lc.Len() != 100 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLRUInvalidateAndEvict(t *testing.T) {
|
||||
var evicted int
|
||||
lc := NewLRU(-1, func(_, _ string) { evicted++ }, 0)
|
||||
|
||||
lc.Add("key1", "val1")
|
||||
lc.Add("key2", "val2")
|
||||
|
||||
val, ok := lc.Get("key1")
|
||||
if !ok {
|
||||
t.Fatalf("should be true")
|
||||
}
|
||||
if val != "val1" {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if evicted != 0 {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
|
||||
lc.Remove("key1")
|
||||
if evicted != 1 {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
val, ok = lc.Get("key1")
|
||||
if val != "" {
|
||||
t.Fatalf("should be empty")
|
||||
}
|
||||
if ok {
|
||||
t.Fatalf("should be false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadingExpired(t *testing.T) {
|
||||
lc := NewLRU[string, string](0, nil, time.Millisecond*5)
|
||||
|
||||
lc.Add("key1", "val1")
|
||||
if lc.Len() != 1 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
|
||||
v, ok := lc.Peek("key1")
|
||||
if v != "val1" {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if !ok {
|
||||
t.Fatalf("should be true")
|
||||
}
|
||||
|
||||
v, ok = lc.Get("key1")
|
||||
if v != "val1" {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if !ok {
|
||||
t.Fatalf("should be true")
|
||||
}
|
||||
|
||||
for {
|
||||
result, ok := lc.Get("key1")
|
||||
if ok && result == "" {
|
||||
t.Fatalf("ok should return a result")
|
||||
}
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(time.Millisecond * 100) // wait for expiration reaper
|
||||
if lc.Len() != 0 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
|
||||
v, ok = lc.Peek("key1")
|
||||
if v != "" {
|
||||
t.Fatalf("should be empty")
|
||||
}
|
||||
if ok {
|
||||
t.Fatalf("should be false")
|
||||
}
|
||||
|
||||
v, ok = lc.Get("key1")
|
||||
if v != "" {
|
||||
t.Fatalf("should be empty")
|
||||
}
|
||||
if ok {
|
||||
t.Fatalf("should be false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLRURemoveOldest(t *testing.T) {
|
||||
lc := NewLRU[string, string](2, nil, 0)
|
||||
|
||||
k, v, ok := lc.RemoveOldest()
|
||||
if k != "" {
|
||||
t.Fatalf("should be empty")
|
||||
}
|
||||
if v != "" {
|
||||
t.Fatalf("should be empty")
|
||||
}
|
||||
if ok {
|
||||
t.Fatalf("should be false")
|
||||
}
|
||||
|
||||
ok = lc.Remove("non_existent")
|
||||
if ok {
|
||||
t.Fatalf("should be false")
|
||||
}
|
||||
|
||||
lc.Add("key1", "val1")
|
||||
if lc.Len() != 1 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
|
||||
v, ok = lc.Get("key1")
|
||||
if !ok {
|
||||
t.Fatalf("should be true")
|
||||
}
|
||||
if v != "val1" {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(lc.Keys(), []string{"key1"}) {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if lc.Len() != 1 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
|
||||
lc.Add("key2", "val2")
|
||||
if !reflect.DeepEqual(lc.Keys(), []string{"key1", "key2"}) {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if lc.Len() != 2 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
|
||||
k, v, ok = lc.RemoveOldest()
|
||||
if k != "key1" {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if v != "val1" {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if !ok {
|
||||
t.Fatalf("should be true")
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(lc.Keys(), []string{"key2"}) {
|
||||
t.Fatalf("value differs from expected")
|
||||
}
|
||||
if lc.Len() != 1 {
|
||||
t.Fatalf("length differs from expected")
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleLRU() {
|
||||
// make cache with 10ms TTL and 5 max keys
|
||||
cache := NewLRU[string, string](5, nil, time.Millisecond*10)
|
||||
|
||||
// set value under key1.
|
||||
cache.Add("key1", "val1")
|
||||
|
||||
// get value under key1
|
||||
r, ok := cache.Get("key1")
|
||||
|
||||
// check for OK value
|
||||
if ok {
|
||||
fmt.Printf("value before expiration is found: %v, value: %q\n", ok, r)
|
||||
}
|
||||
|
||||
// wait for cache to expire
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
// get value under key1 after key expiration
|
||||
r, ok = cache.Get("key1")
|
||||
fmt.Printf("value after expiration is found: %v, value: %q\n", ok, r)
|
||||
|
||||
// set value under key2, would evict old entry because it is already expired.
|
||||
cache.Add("key2", "val2")
|
||||
|
||||
fmt.Printf("Cache len: %d\n", cache.Len())
|
||||
// Output:
|
||||
// value before expiration is found: true, value: "val1"
|
||||
// value after expiration is found: false, value: ""
|
||||
// Cache len: 1
|
||||
}
|
||||
|
||||
func getRand(tb testing.TB) int64 {
|
||||
out, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
}
|
||||
return out.Int64()
|
||||
}
|
||||
|
||||
func (c *LRU[K, V]) wantKeys(t *testing.T, want []K) {
|
||||
t.Helper()
|
||||
got := c.Keys()
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("wrong keys got: %v, want: %v ", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache_EvictionSameKey(t *testing.T) {
|
||||
var evictedKeys []int
|
||||
|
||||
cache := NewLRU[int, struct{}](
|
||||
2,
|
||||
func(key int, _ struct{}) {
|
||||
evictedKeys = append(evictedKeys, key)
|
||||
},
|
||||
0)
|
||||
|
||||
if evicted := cache.Add(1, struct{}{}); evicted {
|
||||
t.Error("First 1: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1})
|
||||
|
||||
if evicted := cache.Add(2, struct{}{}); evicted {
|
||||
t.Error("2: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1, 2})
|
||||
|
||||
if evicted := cache.Add(1, struct{}{}); evicted {
|
||||
t.Error("Second 1: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{2, 1})
|
||||
|
||||
if evicted := cache.Add(3, struct{}{}); !evicted {
|
||||
t.Error("3: did not get expected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1, 3})
|
||||
|
||||
want := []int{2}
|
||||
if !reflect.DeepEqual(evictedKeys, want) {
|
||||
t.Errorf("evictedKeys got: %v want: %v", evictedKeys, want)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
module github.com/hashicorp/golang-lru/v2
|
||||
|
||||
go 1.18
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
// 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_list file.
|
||||
|
||||
package internal
|
||||
|
||||
import "time"
|
||||
|
||||
// Entry is an LRU Entry
|
||||
type Entry[K comparable, V any] struct {
|
||||
// Next and previous pointers in the doubly-linked list of elements.
|
||||
// To simplify the implementation, internally a list l is implemented
|
||||
// as a ring, such that &l.root is both the next element of the last
|
||||
// list element (l.Back()) and the previous element of the first list
|
||||
// element (l.Front()).
|
||||
next, prev *Entry[K, V]
|
||||
|
||||
// The list to which this element belongs.
|
||||
list *LruList[K, V]
|
||||
|
||||
// The LRU Key of this element.
|
||||
Key K
|
||||
|
||||
// The Value stored with this element.
|
||||
Value V
|
||||
|
||||
// The time this element would be cleaned up, optional
|
||||
ExpiresAt time.Time
|
||||
|
||||
// The expiry bucket item was put in, optional
|
||||
ExpireBucket uint8
|
||||
}
|
||||
|
||||
// PrevEntry returns the previous list element or nil.
|
||||
func (e *Entry[K, V]) PrevEntry() *Entry[K, V] {
|
||||
if p := e.prev; e.list != nil && p != &e.list.root {
|
||||
return p
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LruList represents a doubly linked list.
|
||||
// The zero Value for LruList is an empty list ready to use.
|
||||
type LruList[K comparable, V any] struct {
|
||||
root Entry[K, V] // sentinel list element, only &root, root.prev, and root.next are used
|
||||
len int // current list Length excluding (this) sentinel element
|
||||
}
|
||||
|
||||
// Init initializes or clears list l.
|
||||
func (l *LruList[K, V]) Init() *LruList[K, V] {
|
||||
l.root.next = &l.root
|
||||
l.root.prev = &l.root
|
||||
l.len = 0
|
||||
return l
|
||||
}
|
||||
|
||||
// NewList returns an initialized list.
|
||||
func NewList[K comparable, V any]() *LruList[K, V] { return new(LruList[K, V]).Init() }
|
||||
|
||||
// Length returns the number of elements of list l.
|
||||
// The complexity is O(1).
|
||||
func (l *LruList[K, V]) Length() int { return l.len }
|
||||
|
||||
// Back returns the last element of list l or nil if the list is empty.
|
||||
func (l *LruList[K, V]) Back() *Entry[K, V] {
|
||||
if l.len == 0 {
|
||||
return nil
|
||||
}
|
||||
return l.root.prev
|
||||
}
|
||||
|
||||
// lazyInit lazily initializes a zero List Value.
|
||||
func (l *LruList[K, V]) lazyInit() {
|
||||
if l.root.next == nil {
|
||||
l.Init()
|
||||
}
|
||||
}
|
||||
|
||||
// insert inserts e after at, increments l.len, and returns e.
|
||||
func (l *LruList[K, V]) insert(e, at *Entry[K, V]) *Entry[K, V] {
|
||||
e.prev = at
|
||||
e.next = at.next
|
||||
e.prev.next = e
|
||||
e.next.prev = e
|
||||
e.list = l
|
||||
l.len++
|
||||
return e
|
||||
}
|
||||
|
||||
// insertValue is a convenience wrapper for insert(&Entry{Value: v, ExpiresAt: ExpiresAt}, at).
|
||||
func (l *LruList[K, V]) insertValue(k K, v V, expiresAt time.Time, at *Entry[K, V]) *Entry[K, V] {
|
||||
return l.insert(&Entry[K, V]{Value: v, Key: k, ExpiresAt: expiresAt}, at)
|
||||
}
|
||||
|
||||
// Remove removes e from its list, decrements l.len
|
||||
func (l *LruList[K, V]) Remove(e *Entry[K, V]) V {
|
||||
e.prev.next = e.next
|
||||
e.next.prev = e.prev
|
||||
e.next = nil // avoid memory leaks
|
||||
e.prev = nil // avoid memory leaks
|
||||
e.list = nil
|
||||
l.len--
|
||||
|
||||
return e.Value
|
||||
}
|
||||
|
||||
// move moves e to next to at.
|
||||
func (l *LruList[K, V]) move(e, at *Entry[K, V]) {
|
||||
if e == at {
|
||||
return
|
||||
}
|
||||
e.prev.next = e.next
|
||||
e.next.prev = e.prev
|
||||
|
||||
e.prev = at
|
||||
e.next = at.next
|
||||
e.prev.next = e
|
||||
e.next.prev = e
|
||||
}
|
||||
|
||||
// PushFront inserts a new element e with value v at the front of list l and returns e.
|
||||
func (l *LruList[K, V]) PushFront(k K, v V) *Entry[K, V] {
|
||||
l.lazyInit()
|
||||
return l.insertValue(k, v, time.Time{}, &l.root)
|
||||
}
|
||||
|
||||
// PushFrontExpirable inserts a new expirable element e with Value v at the front of list l and returns e.
|
||||
func (l *LruList[K, V]) PushFrontExpirable(k K, v V, expiresAt time.Time) *Entry[K, V] {
|
||||
l.lazyInit()
|
||||
return l.insertValue(k, v, expiresAt, &l.root)
|
||||
}
|
||||
|
||||
// MoveToFront moves element e to the front of list l.
|
||||
// If e is not an element of l, the list is not modified.
|
||||
// The element must not be nil.
|
||||
func (l *LruList[K, V]) MoveToFront(e *Entry[K, V]) {
|
||||
if e.list != l || l.root.next == e {
|
||||
return
|
||||
}
|
||||
// see comment in List.Remove about initialization of l
|
||||
l.move(e, &l.root)
|
||||
}
|
||||
|
|
@ -1,250 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package lru
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/golang-lru/v2/simplelru"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultEvictedBufferSize defines the default buffer size to store evicted key/val
|
||||
DefaultEvictedBufferSize = 16
|
||||
)
|
||||
|
||||
// Cache is a thread-safe fixed size LRU cache.
|
||||
type Cache[K comparable, V any] struct {
|
||||
lru *simplelru.LRU[K, V]
|
||||
evictedKeys []K
|
||||
evictedVals []V
|
||||
onEvictedCB func(k K, v V)
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
// New creates an LRU of the given size.
|
||||
func New[K comparable, V any](size int) (*Cache[K, V], error) {
|
||||
return NewWithEvict[K, V](size, nil)
|
||||
}
|
||||
|
||||
// NewWithEvict constructs a fixed size cache with the given eviction
|
||||
// callback.
|
||||
func NewWithEvict[K comparable, V any](size int, onEvicted func(key K, value V)) (c *Cache[K, V], err error) {
|
||||
// create a cache with default settings
|
||||
c = &Cache[K, V]{
|
||||
onEvictedCB: onEvicted,
|
||||
}
|
||||
if onEvicted != nil {
|
||||
c.initEvictBuffers()
|
||||
onEvicted = c.onEvicted
|
||||
}
|
||||
c.lru, err = simplelru.NewLRU(size, onEvicted)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Cache[K, V]) initEvictBuffers() {
|
||||
c.evictedKeys = make([]K, 0, DefaultEvictedBufferSize)
|
||||
c.evictedVals = make([]V, 0, DefaultEvictedBufferSize)
|
||||
}
|
||||
|
||||
// onEvicted save evicted key/val and sent in externally registered callback
|
||||
// outside of critical section
|
||||
func (c *Cache[K, V]) onEvicted(k K, v V) {
|
||||
c.evictedKeys = append(c.evictedKeys, k)
|
||||
c.evictedVals = append(c.evictedVals, v)
|
||||
}
|
||||
|
||||
// Purge is used to completely clear the cache.
|
||||
func (c *Cache[K, V]) Purge() {
|
||||
var ks []K
|
||||
var vs []V
|
||||
c.lock.Lock()
|
||||
c.lru.Purge()
|
||||
if c.onEvictedCB != nil && len(c.evictedKeys) > 0 {
|
||||
ks, vs = c.evictedKeys, c.evictedVals
|
||||
c.initEvictBuffers()
|
||||
}
|
||||
c.lock.Unlock()
|
||||
// invoke callback outside of critical section
|
||||
if c.onEvictedCB != nil {
|
||||
for i := 0; i < len(ks); i++ {
|
||||
c.onEvictedCB(ks[i], vs[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add adds a value to the cache. Returns true if an eviction occurred.
|
||||
func (c *Cache[K, V]) Add(key K, value V) (evicted bool) {
|
||||
var k K
|
||||
var v V
|
||||
c.lock.Lock()
|
||||
evicted = c.lru.Add(key, value)
|
||||
if c.onEvictedCB != nil && evicted {
|
||||
k, v = c.evictedKeys[0], c.evictedVals[0]
|
||||
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
|
||||
}
|
||||
c.lock.Unlock()
|
||||
if c.onEvictedCB != nil && evicted {
|
||||
c.onEvictedCB(k, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Get looks up a key's value from the cache.
|
||||
func (c *Cache[K, V]) Get(key K) (value V, ok bool) {
|
||||
c.lock.Lock()
|
||||
value, ok = c.lru.Get(key)
|
||||
c.lock.Unlock()
|
||||
return value, ok
|
||||
}
|
||||
|
||||
// Contains checks if a key is in the cache, without updating the
|
||||
// recent-ness or deleting it for being stale.
|
||||
func (c *Cache[K, V]) Contains(key K) bool {
|
||||
c.lock.RLock()
|
||||
containKey := c.lru.Contains(key)
|
||||
c.lock.RUnlock()
|
||||
return containKey
|
||||
}
|
||||
|
||||
// Peek returns the key value (or undefined if not found) without updating
|
||||
// the "recently used"-ness of the key.
|
||||
func (c *Cache[K, V]) Peek(key K) (value V, ok bool) {
|
||||
c.lock.RLock()
|
||||
value, ok = c.lru.Peek(key)
|
||||
c.lock.RUnlock()
|
||||
return value, ok
|
||||
}
|
||||
|
||||
// ContainsOrAdd checks if a key is in the cache without updating the
|
||||
// recent-ness or deleting it for being stale, and if not, adds the value.
|
||||
// Returns whether found and whether an eviction occurred.
|
||||
func (c *Cache[K, V]) ContainsOrAdd(key K, value V) (ok, evicted bool) {
|
||||
var k K
|
||||
var v V
|
||||
c.lock.Lock()
|
||||
if c.lru.Contains(key) {
|
||||
c.lock.Unlock()
|
||||
return true, false
|
||||
}
|
||||
evicted = c.lru.Add(key, value)
|
||||
if c.onEvictedCB != nil && evicted {
|
||||
k, v = c.evictedKeys[0], c.evictedVals[0]
|
||||
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
|
||||
}
|
||||
c.lock.Unlock()
|
||||
if c.onEvictedCB != nil && evicted {
|
||||
c.onEvictedCB(k, v)
|
||||
}
|
||||
return false, evicted
|
||||
}
|
||||
|
||||
// PeekOrAdd checks if a key is in the cache without updating the
|
||||
// recent-ness or deleting it for being stale, and if not, adds the value.
|
||||
// Returns whether found and whether an eviction occurred.
|
||||
func (c *Cache[K, V]) PeekOrAdd(key K, value V) (previous V, ok, evicted bool) {
|
||||
var k K
|
||||
var v V
|
||||
c.lock.Lock()
|
||||
previous, ok = c.lru.Peek(key)
|
||||
if ok {
|
||||
c.lock.Unlock()
|
||||
return previous, true, false
|
||||
}
|
||||
evicted = c.lru.Add(key, value)
|
||||
if c.onEvictedCB != nil && evicted {
|
||||
k, v = c.evictedKeys[0], c.evictedVals[0]
|
||||
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
|
||||
}
|
||||
c.lock.Unlock()
|
||||
if c.onEvictedCB != nil && evicted {
|
||||
c.onEvictedCB(k, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Remove removes the provided key from the cache.
|
||||
func (c *Cache[K, V]) Remove(key K) (present bool) {
|
||||
var k K
|
||||
var v V
|
||||
c.lock.Lock()
|
||||
present = c.lru.Remove(key)
|
||||
if c.onEvictedCB != nil && present {
|
||||
k, v = c.evictedKeys[0], c.evictedVals[0]
|
||||
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
|
||||
}
|
||||
c.lock.Unlock()
|
||||
if c.onEvictedCB != nil && present {
|
||||
c.onEvictedCB(k, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Resize changes the cache size.
|
||||
func (c *Cache[K, V]) Resize(size int) (evicted int) {
|
||||
var ks []K
|
||||
var vs []V
|
||||
c.lock.Lock()
|
||||
evicted = c.lru.Resize(size)
|
||||
if c.onEvictedCB != nil && evicted > 0 {
|
||||
ks, vs = c.evictedKeys, c.evictedVals
|
||||
c.initEvictBuffers()
|
||||
}
|
||||
c.lock.Unlock()
|
||||
if c.onEvictedCB != nil && evicted > 0 {
|
||||
for i := 0; i < len(ks); i++ {
|
||||
c.onEvictedCB(ks[i], vs[i])
|
||||
}
|
||||
}
|
||||
return evicted
|
||||
}
|
||||
|
||||
// RemoveOldest removes the oldest item from the cache.
|
||||
func (c *Cache[K, V]) RemoveOldest() (key K, value V, ok bool) {
|
||||
var k K
|
||||
var v V
|
||||
c.lock.Lock()
|
||||
key, value, ok = c.lru.RemoveOldest()
|
||||
if c.onEvictedCB != nil && ok {
|
||||
k, v = c.evictedKeys[0], c.evictedVals[0]
|
||||
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
|
||||
}
|
||||
c.lock.Unlock()
|
||||
if c.onEvictedCB != nil && ok {
|
||||
c.onEvictedCB(k, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetOldest returns the oldest entry
|
||||
func (c *Cache[K, V]) GetOldest() (key K, value V, ok bool) {
|
||||
c.lock.RLock()
|
||||
key, value, ok = c.lru.GetOldest()
|
||||
c.lock.RUnlock()
|
||||
return
|
||||
}
|
||||
|
||||
// Keys returns a slice of the keys in the cache, from oldest to newest.
|
||||
func (c *Cache[K, V]) Keys() []K {
|
||||
c.lock.RLock()
|
||||
keys := c.lru.Keys()
|
||||
c.lock.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
// Values returns a slice of the values in the cache, from oldest to newest.
|
||||
func (c *Cache[K, V]) Values() []V {
|
||||
c.lock.RLock()
|
||||
values := c.lru.Values()
|
||||
c.lock.RUnlock()
|
||||
return values
|
||||
}
|
||||
|
||||
// Len returns the number of items in the cache.
|
||||
func (c *Cache[K, V]) Len() int {
|
||||
c.lock.RLock()
|
||||
length := c.lru.Len()
|
||||
c.lock.RUnlock()
|
||||
return length
|
||||
}
|
||||
|
|
@ -1,443 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package lru
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkLRU_Rand(b *testing.B) {
|
||||
l, err := New[int64, int64](8192)
|
||||
if err != nil {
|
||||
b.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
trace[i] = getRand(b) % 32768
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
var hit, miss int
|
||||
for i := 0; i < 2*b.N; i++ {
|
||||
if i%2 == 0 {
|
||||
l.Add(trace[i], trace[i])
|
||||
} else {
|
||||
if _, ok := l.Get(trace[i]); ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(hit+miss))
|
||||
}
|
||||
|
||||
func BenchmarkLRU_Freq(b *testing.B) {
|
||||
l, err := New[int64, int64](8192)
|
||||
if err != nil {
|
||||
b.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
if i%2 == 0 {
|
||||
trace[i] = getRand(b) % 16384
|
||||
} else {
|
||||
trace[i] = getRand(b) % 32768
|
||||
}
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
l.Add(trace[i], trace[i])
|
||||
}
|
||||
var hit, miss int
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, ok := l.Get(trace[i]); ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(hit+miss))
|
||||
}
|
||||
|
||||
func TestLRU(t *testing.T) {
|
||||
evictCounter := 0
|
||||
onEvicted := func(k int, v int) {
|
||||
if k != v {
|
||||
t.Fatalf("Evict values not equal (%v!=%v)", k, v)
|
||||
}
|
||||
evictCounter++
|
||||
}
|
||||
l, err := NewWithEvict(128, onEvicted)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
if l.Len() != 128 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
|
||||
if evictCounter != 128 {
|
||||
t.Fatalf("bad evict count: %v", evictCounter)
|
||||
}
|
||||
|
||||
for i, k := range l.Keys() {
|
||||
if v, ok := l.Get(k); !ok || v != k || v != i+128 {
|
||||
t.Fatalf("bad key: %v", k)
|
||||
}
|
||||
}
|
||||
for i, v := range l.Values() {
|
||||
if v != i+128 {
|
||||
t.Fatalf("bad value: %v", v)
|
||||
}
|
||||
}
|
||||
for i := 0; i < 128; i++ {
|
||||
if _, ok := l.Get(i); ok {
|
||||
t.Fatalf("should be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 256; i++ {
|
||||
if _, ok := l.Get(i); !ok {
|
||||
t.Fatalf("should not be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 192; i++ {
|
||||
l.Remove(i)
|
||||
if _, ok := l.Get(i); ok {
|
||||
t.Fatalf("should be deleted")
|
||||
}
|
||||
}
|
||||
|
||||
l.Get(192) // expect 192 to be last key in l.Keys()
|
||||
|
||||
for i, k := range l.Keys() {
|
||||
if (i < 63 && k != i+193) || (i == 63 && k != 192) {
|
||||
t.Fatalf("out of order key: %v", k)
|
||||
}
|
||||
}
|
||||
|
||||
l.Purge()
|
||||
if l.Len() != 0 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
if _, ok := l.Get(200); ok {
|
||||
t.Fatalf("should contain nothing")
|
||||
}
|
||||
}
|
||||
|
||||
// test that Add returns true/false if an eviction occurred
|
||||
func TestLRUAdd(t *testing.T) {
|
||||
evictCounter := 0
|
||||
onEvicted := func(k int, v int) {
|
||||
evictCounter++
|
||||
}
|
||||
|
||||
l, err := NewWithEvict(1, onEvicted)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if l.Add(1, 1) == true || evictCounter != 0 {
|
||||
t.Errorf("should not have an eviction")
|
||||
}
|
||||
if l.Add(2, 2) == false || evictCounter != 1 {
|
||||
t.Errorf("should have an eviction")
|
||||
}
|
||||
}
|
||||
|
||||
// test that Contains doesn't update recent-ness
|
||||
func TestLRUContains(t *testing.T) {
|
||||
l, err := New[int, int](2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if !l.Contains(1) {
|
||||
t.Errorf("1 should be contained")
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("Contains should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
|
||||
// test that ContainsOrAdd doesn't update recent-ness
|
||||
func TestLRUContainsOrAdd(t *testing.T) {
|
||||
l, err := New[int, int](2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
contains, evict := l.ContainsOrAdd(1, 1)
|
||||
if !contains {
|
||||
t.Errorf("1 should be contained")
|
||||
}
|
||||
if evict {
|
||||
t.Errorf("nothing should be evicted here")
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
contains, evict = l.ContainsOrAdd(1, 1)
|
||||
if contains {
|
||||
t.Errorf("1 should not have been contained")
|
||||
}
|
||||
if !evict {
|
||||
t.Errorf("an eviction should have occurred")
|
||||
}
|
||||
if !l.Contains(1) {
|
||||
t.Errorf("now 1 should be contained")
|
||||
}
|
||||
}
|
||||
|
||||
// test that PeekOrAdd doesn't update recent-ness
|
||||
func TestLRUPeekOrAdd(t *testing.T) {
|
||||
l, err := New[int, int](2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
previous, contains, evict := l.PeekOrAdd(1, 1)
|
||||
if !contains {
|
||||
t.Errorf("1 should be contained")
|
||||
}
|
||||
if evict {
|
||||
t.Errorf("nothing should be evicted here")
|
||||
}
|
||||
if previous != 1 {
|
||||
t.Errorf("previous is not equal to 1")
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
contains, evict = l.ContainsOrAdd(1, 1)
|
||||
if contains {
|
||||
t.Errorf("1 should not have been contained")
|
||||
}
|
||||
if !evict {
|
||||
t.Errorf("an eviction should have occurred")
|
||||
}
|
||||
if !l.Contains(1) {
|
||||
t.Errorf("now 1 should be contained")
|
||||
}
|
||||
}
|
||||
|
||||
// test that Peek doesn't update recent-ness
|
||||
func TestLRUPeek(t *testing.T) {
|
||||
l, err := New[int, int](2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if v, ok := l.Peek(1); !ok || v != 1 {
|
||||
t.Errorf("1 should be set to 1: %v, %v", v, ok)
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
|
||||
// test that Resize can upsize and downsize
|
||||
func TestLRUResize(t *testing.T) {
|
||||
onEvictCounter := 0
|
||||
onEvicted := func(k int, v int) {
|
||||
onEvictCounter++
|
||||
}
|
||||
l, err := NewWithEvict(2, onEvicted)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Downsize
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
evicted := l.Resize(1)
|
||||
if evicted != 1 {
|
||||
t.Errorf("1 element should have been evicted: %v", evicted)
|
||||
}
|
||||
if onEvictCounter != 1 {
|
||||
t.Errorf("onEvicted should have been called 1 time: %v", onEvictCounter)
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("Element 1 should have been evicted")
|
||||
}
|
||||
|
||||
// Upsize
|
||||
evicted = l.Resize(2)
|
||||
if evicted != 0 {
|
||||
t.Errorf("0 elements should have been evicted: %v", evicted)
|
||||
}
|
||||
|
||||
l.Add(4, 4)
|
||||
if !l.Contains(3) || !l.Contains(4) {
|
||||
t.Errorf("Cache should have contained 2 elements")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache[K, V]) wantKeys(t *testing.T, want []K) {
|
||||
t.Helper()
|
||||
got := c.Keys()
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("wrong keys got: %v, want: %v ", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache_EvictionSameKey(t *testing.T) {
|
||||
t.Run("Add", func(t *testing.T) {
|
||||
var evictedKeys []int
|
||||
|
||||
cache, _ := NewWithEvict(
|
||||
2,
|
||||
func(key int, _ struct{}) {
|
||||
evictedKeys = append(evictedKeys, key)
|
||||
})
|
||||
|
||||
if evicted := cache.Add(1, struct{}{}); evicted {
|
||||
t.Error("First 1: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1})
|
||||
|
||||
if evicted := cache.Add(2, struct{}{}); evicted {
|
||||
t.Error("2: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1, 2})
|
||||
|
||||
if evicted := cache.Add(1, struct{}{}); evicted {
|
||||
t.Error("Second 1: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{2, 1})
|
||||
|
||||
if evicted := cache.Add(3, struct{}{}); !evicted {
|
||||
t.Error("3: did not get expected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1, 3})
|
||||
|
||||
want := []int{2}
|
||||
if !reflect.DeepEqual(evictedKeys, want) {
|
||||
t.Errorf("evictedKeys got: %v want: %v", evictedKeys, want)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ContainsOrAdd", func(t *testing.T) {
|
||||
var evictedKeys []int
|
||||
|
||||
cache, _ := NewWithEvict(
|
||||
2,
|
||||
func(key int, _ struct{}) {
|
||||
evictedKeys = append(evictedKeys, key)
|
||||
})
|
||||
|
||||
contained, evicted := cache.ContainsOrAdd(1, struct{}{})
|
||||
if contained {
|
||||
t.Error("First 1: got unexpected contained")
|
||||
}
|
||||
if evicted {
|
||||
t.Error("First 1: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1})
|
||||
|
||||
contained, evicted = cache.ContainsOrAdd(2, struct{}{})
|
||||
if contained {
|
||||
t.Error("2: got unexpected contained")
|
||||
}
|
||||
if evicted {
|
||||
t.Error("2: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1, 2})
|
||||
|
||||
contained, evicted = cache.ContainsOrAdd(1, struct{}{})
|
||||
if !contained {
|
||||
t.Error("Second 1: did not get expected contained")
|
||||
}
|
||||
if evicted {
|
||||
t.Error("Second 1: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1, 2})
|
||||
|
||||
contained, evicted = cache.ContainsOrAdd(3, struct{}{})
|
||||
if contained {
|
||||
t.Error("3: got unexpected contained")
|
||||
}
|
||||
if !evicted {
|
||||
t.Error("3: did not get expected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{2, 3})
|
||||
|
||||
want := []int{1}
|
||||
if !reflect.DeepEqual(evictedKeys, want) {
|
||||
t.Errorf("evictedKeys got: %v want: %v", evictedKeys, want)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("PeekOrAdd", func(t *testing.T) {
|
||||
var evictedKeys []int
|
||||
|
||||
cache, _ := NewWithEvict(
|
||||
2,
|
||||
func(key int, _ struct{}) {
|
||||
evictedKeys = append(evictedKeys, key)
|
||||
})
|
||||
|
||||
_, contained, evicted := cache.PeekOrAdd(1, struct{}{})
|
||||
if contained {
|
||||
t.Error("First 1: got unexpected contained")
|
||||
}
|
||||
if evicted {
|
||||
t.Error("First 1: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1})
|
||||
|
||||
_, contained, evicted = cache.PeekOrAdd(2, struct{}{})
|
||||
if contained {
|
||||
t.Error("2: got unexpected contained")
|
||||
}
|
||||
if evicted {
|
||||
t.Error("2: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1, 2})
|
||||
|
||||
_, contained, evicted = cache.PeekOrAdd(1, struct{}{})
|
||||
if !contained {
|
||||
t.Error("Second 1: did not get expected contained")
|
||||
}
|
||||
if evicted {
|
||||
t.Error("Second 1: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1, 2})
|
||||
|
||||
_, contained, evicted = cache.PeekOrAdd(3, struct{}{})
|
||||
if contained {
|
||||
t.Error("3: got unexpected contained")
|
||||
}
|
||||
if !evicted {
|
||||
t.Error("3: did not get expected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{2, 3})
|
||||
|
||||
want := []int{1}
|
||||
if !reflect.DeepEqual(evictedKeys, want) {
|
||||
t.Errorf("evictedKeys got: %v want: %v", evictedKeys, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
This license applies to simplelru/list.go
|
||||
|
||||
Copyright (c) 2009 The Go 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 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.
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package simplelru
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/hashicorp/golang-lru/v2/internal"
|
||||
)
|
||||
|
||||
// EvictCallback is used to get a callback when a cache entry is evicted
|
||||
type EvictCallback[K comparable, V any] func(key K, value V)
|
||||
|
||||
// LRU implements a non-thread safe fixed size LRU cache
|
||||
type LRU[K comparable, V any] struct {
|
||||
size int
|
||||
evictList *internal.LruList[K, V]
|
||||
items map[K]*internal.Entry[K, V]
|
||||
onEvict EvictCallback[K, V]
|
||||
}
|
||||
|
||||
// NewLRU constructs an LRU of the given size
|
||||
func NewLRU[K comparable, V any](size int, onEvict EvictCallback[K, V]) (*LRU[K, V], error) {
|
||||
if size <= 0 {
|
||||
return nil, errors.New("must provide a positive size")
|
||||
}
|
||||
|
||||
c := &LRU[K, V]{
|
||||
size: size,
|
||||
evictList: internal.NewList[K, V](),
|
||||
items: make(map[K]*internal.Entry[K, V]),
|
||||
onEvict: onEvict,
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Purge is used to completely clear the cache.
|
||||
func (c *LRU[K, V]) Purge() {
|
||||
for k, v := range c.items {
|
||||
if c.onEvict != nil {
|
||||
c.onEvict(k, v.Value)
|
||||
}
|
||||
delete(c.items, k)
|
||||
}
|
||||
c.evictList.Init()
|
||||
}
|
||||
|
||||
// Add adds a value to the cache. Returns true if an eviction occurred.
|
||||
func (c *LRU[K, V]) Add(key K, value V) (evicted bool) {
|
||||
// Check for existing item
|
||||
if ent, ok := c.items[key]; ok {
|
||||
c.evictList.MoveToFront(ent)
|
||||
ent.Value = value
|
||||
return false
|
||||
}
|
||||
|
||||
// Add new item
|
||||
ent := c.evictList.PushFront(key, value)
|
||||
c.items[key] = ent
|
||||
|
||||
evict := c.evictList.Length() > c.size
|
||||
// Verify size not exceeded
|
||||
if evict {
|
||||
c.removeOldest()
|
||||
}
|
||||
return evict
|
||||
}
|
||||
|
||||
// Get looks up a key's value from the cache.
|
||||
func (c *LRU[K, V]) Get(key K) (value V, ok bool) {
|
||||
if ent, ok := c.items[key]; ok {
|
||||
c.evictList.MoveToFront(ent)
|
||||
return ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Contains checks if a key is in the cache, without updating the recent-ness
|
||||
// or deleting it for being stale.
|
||||
func (c *LRU[K, V]) Contains(key K) (ok bool) {
|
||||
_, ok = c.items[key]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Peek returns the key value (or undefined if not found) without updating
|
||||
// the "recently used"-ness of the key.
|
||||
func (c *LRU[K, V]) Peek(key K) (value V, ok bool) {
|
||||
var ent *internal.Entry[K, V]
|
||||
if ent, ok = c.items[key]; ok {
|
||||
return ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Remove removes the provided key from the cache, returning if the
|
||||
// key was contained.
|
||||
func (c *LRU[K, V]) Remove(key K) (present bool) {
|
||||
if ent, ok := c.items[key]; ok {
|
||||
c.removeElement(ent)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// RemoveOldest removes the oldest item from the cache.
|
||||
func (c *LRU[K, V]) RemoveOldest() (key K, value V, ok bool) {
|
||||
if ent := c.evictList.Back(); ent != nil {
|
||||
c.removeElement(ent)
|
||||
return ent.Key, ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetOldest returns the oldest entry
|
||||
func (c *LRU[K, V]) GetOldest() (key K, value V, ok bool) {
|
||||
if ent := c.evictList.Back(); ent != nil {
|
||||
return ent.Key, ent.Value, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Keys returns a slice of the keys in the cache, from oldest to newest.
|
||||
func (c *LRU[K, V]) Keys() []K {
|
||||
keys := make([]K, c.evictList.Length())
|
||||
i := 0
|
||||
for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() {
|
||||
keys[i] = ent.Key
|
||||
i++
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// Values returns a slice of the values in the cache, from oldest to newest.
|
||||
func (c *LRU[K, V]) Values() []V {
|
||||
values := make([]V, len(c.items))
|
||||
i := 0
|
||||
for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() {
|
||||
values[i] = ent.Value
|
||||
i++
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// Len returns the number of items in the cache.
|
||||
func (c *LRU[K, V]) Len() int {
|
||||
return c.evictList.Length()
|
||||
}
|
||||
|
||||
// Resize changes the cache size.
|
||||
func (c *LRU[K, V]) Resize(size int) (evicted int) {
|
||||
diff := c.Len() - size
|
||||
if diff < 0 {
|
||||
diff = 0
|
||||
}
|
||||
for i := 0; i < diff; i++ {
|
||||
c.removeOldest()
|
||||
}
|
||||
c.size = size
|
||||
return diff
|
||||
}
|
||||
|
||||
// removeOldest removes the oldest item from the cache.
|
||||
func (c *LRU[K, V]) removeOldest() {
|
||||
if ent := c.evictList.Back(); ent != nil {
|
||||
c.removeElement(ent)
|
||||
}
|
||||
}
|
||||
|
||||
// removeElement is used to remove a given list element from the cache
|
||||
func (c *LRU[K, V]) removeElement(e *internal.Entry[K, V]) {
|
||||
c.evictList.Remove(e)
|
||||
delete(c.items, e.Key)
|
||||
if c.onEvict != nil {
|
||||
c.onEvict(e.Key, e.Value)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
// Package simplelru provides simple LRU implementation based on build-in container/list.
|
||||
package simplelru
|
||||
|
||||
// LRUCache is the interface for simple LRU cache.
|
||||
type LRUCache[K comparable, V any] interface {
|
||||
// Adds a value to the cache, returns true if an eviction occurred and
|
||||
// updates the "recently used"-ness of the key.
|
||||
Add(key K, value V) bool
|
||||
|
||||
// Returns key's value from the cache and
|
||||
// updates the "recently used"-ness of the key. #value, isFound
|
||||
Get(key K) (value V, ok bool)
|
||||
|
||||
// Checks if a key exists in cache without updating the recent-ness.
|
||||
Contains(key K) (ok bool)
|
||||
|
||||
// Returns key's value without updating the "recently used"-ness of the key.
|
||||
Peek(key K) (value V, ok bool)
|
||||
|
||||
// Removes a key from the cache.
|
||||
Remove(key K) bool
|
||||
|
||||
// Removes the oldest entry from cache.
|
||||
RemoveOldest() (K, V, bool)
|
||||
|
||||
// Returns the oldest entry from the cache. #key, value, isFound
|
||||
GetOldest() (K, V, bool)
|
||||
|
||||
// Returns a slice of the keys in the cache, from oldest to newest.
|
||||
Keys() []K
|
||||
|
||||
// Values returns a slice of the values in the cache, from oldest to newest.
|
||||
Values() []V
|
||||
|
||||
// Returns the number of items in the cache.
|
||||
Len() int
|
||||
|
||||
// Clears all cache entries.
|
||||
Purge()
|
||||
|
||||
// Resizes cache, returning number evicted
|
||||
Resize(int) int
|
||||
}
|
||||
|
|
@ -1,255 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package simplelru
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLRU(t *testing.T) {
|
||||
evictCounter := 0
|
||||
onEvicted := func(k int, v int) {
|
||||
if k != v {
|
||||
t.Fatalf("Evict values not equal (%v!=%v)", k, v)
|
||||
}
|
||||
evictCounter++
|
||||
}
|
||||
l, err := NewLRU(128, onEvicted)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
if l.Len() != 128 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
|
||||
if evictCounter != 128 {
|
||||
t.Fatalf("bad evict count: %v", evictCounter)
|
||||
}
|
||||
|
||||
for i, k := range l.Keys() {
|
||||
if v, ok := l.Get(k); !ok || v != k || v != i+128 {
|
||||
t.Fatalf("bad key: %v", k)
|
||||
}
|
||||
}
|
||||
for i, v := range l.Values() {
|
||||
if v != i+128 {
|
||||
t.Fatalf("bad value: %v", v)
|
||||
}
|
||||
}
|
||||
for i := 0; i < 128; i++ {
|
||||
if _, ok := l.Get(i); ok {
|
||||
t.Fatalf("should be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 256; i++ {
|
||||
if _, ok := l.Get(i); !ok {
|
||||
t.Fatalf("should not be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 192; i++ {
|
||||
if ok := l.Remove(i); !ok {
|
||||
t.Fatalf("should be contained")
|
||||
}
|
||||
if ok := l.Remove(i); ok {
|
||||
t.Fatalf("should not be contained")
|
||||
}
|
||||
if _, ok := l.Get(i); ok {
|
||||
t.Fatalf("should be deleted")
|
||||
}
|
||||
}
|
||||
|
||||
l.Get(192) // expect 192 to be last key in l.Keys()
|
||||
|
||||
for i, k := range l.Keys() {
|
||||
if (i < 63 && k != i+193) || (i == 63 && k != 192) {
|
||||
t.Fatalf("out of order key: %v", k)
|
||||
}
|
||||
}
|
||||
|
||||
l.Purge()
|
||||
if l.Len() != 0 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
if _, ok := l.Get(200); ok {
|
||||
t.Fatalf("should contain nothing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLRU_GetOldest_RemoveOldest(t *testing.T) {
|
||||
l, err := NewLRU[int, int](128, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
for i := 0; i < 256; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
k, _, ok := l.GetOldest()
|
||||
if !ok {
|
||||
t.Fatalf("missing")
|
||||
}
|
||||
if k != 128 {
|
||||
t.Fatalf("bad: %v", k)
|
||||
}
|
||||
|
||||
k, _, ok = l.RemoveOldest()
|
||||
if !ok {
|
||||
t.Fatalf("missing")
|
||||
}
|
||||
if k != 128 {
|
||||
t.Fatalf("bad: %v", k)
|
||||
}
|
||||
|
||||
k, _, ok = l.RemoveOldest()
|
||||
if !ok {
|
||||
t.Fatalf("missing")
|
||||
}
|
||||
if k != 129 {
|
||||
t.Fatalf("bad: %v", k)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Add returns true/false if an eviction occurred
|
||||
func TestLRU_Add(t *testing.T) {
|
||||
evictCounter := 0
|
||||
onEvicted := func(k int, v int) {
|
||||
evictCounter++
|
||||
}
|
||||
|
||||
l, err := NewLRU(1, onEvicted)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if l.Add(1, 1) == true || evictCounter != 0 {
|
||||
t.Errorf("should not have an eviction")
|
||||
}
|
||||
if l.Add(2, 2) == false || evictCounter != 1 {
|
||||
t.Errorf("should have an eviction")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Contains doesn't update recent-ness
|
||||
func TestLRU_Contains(t *testing.T) {
|
||||
l, err := NewLRU[int, int](2, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if !l.Contains(1) {
|
||||
t.Errorf("1 should be contained")
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("Contains should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Peek doesn't update recent-ness
|
||||
func TestLRU_Peek(t *testing.T) {
|
||||
l, err := NewLRU[int, int](2, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if v, ok := l.Peek(1); !ok || v != 1 {
|
||||
t.Errorf("1 should be set to 1: %v, %v", v, ok)
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Resize can upsize and downsize
|
||||
func TestLRU_Resize(t *testing.T) {
|
||||
onEvictCounter := 0
|
||||
onEvicted := func(k int, v int) {
|
||||
onEvictCounter++
|
||||
}
|
||||
l, err := NewLRU(2, onEvicted)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Downsize
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
evicted := l.Resize(1)
|
||||
if evicted != 1 {
|
||||
t.Errorf("1 element should have been evicted: %v", evicted)
|
||||
}
|
||||
if onEvictCounter != 1 {
|
||||
t.Errorf("onEvicted should have been called 1 time: %v", onEvictCounter)
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("Element 1 should have been evicted")
|
||||
}
|
||||
|
||||
// Upsize
|
||||
evicted = l.Resize(2)
|
||||
if evicted != 0 {
|
||||
t.Errorf("0 elements should have been evicted: %v", evicted)
|
||||
}
|
||||
|
||||
l.Add(4, 4)
|
||||
if !l.Contains(3) || !l.Contains(4) {
|
||||
t.Errorf("Cache should have contained 2 elements")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *LRU[K, V]) wantKeys(t *testing.T, want []K) {
|
||||
t.Helper()
|
||||
got := c.Keys()
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("wrong keys got: %v, want: %v ", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache_EvictionSameKey(t *testing.T) {
|
||||
var evictedKeys []int
|
||||
|
||||
cache, _ := NewLRU(
|
||||
2,
|
||||
func(key int, _ struct{}) {
|
||||
evictedKeys = append(evictedKeys, key)
|
||||
})
|
||||
|
||||
if evicted := cache.Add(1, struct{}{}); evicted {
|
||||
t.Error("First 1: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1})
|
||||
|
||||
if evicted := cache.Add(2, struct{}{}); evicted {
|
||||
t.Error("2: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1, 2})
|
||||
|
||||
if evicted := cache.Add(1, struct{}{}); evicted {
|
||||
t.Error("Second 1: got unexpected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{2, 1})
|
||||
|
||||
if evicted := cache.Add(3, struct{}{}); !evicted {
|
||||
t.Error("3: did not get expected eviction")
|
||||
}
|
||||
cache.wantKeys(t, []int{1, 3})
|
||||
|
||||
want := []int{2}
|
||||
if !reflect.DeepEqual(evictedKeys, want) {
|
||||
t.Errorf("evictedKeys got: %v want: %v", evictedKeys, want)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package lru
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"math"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func getRand(tb testing.TB) int64 {
|
||||
out, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
}
|
||||
return out.Int64()
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
Copyright 2021 in-toto Developers
|
||||
|
||||
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.
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
Copyright 2018 New York University
|
||||
|
||||
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.
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018-2024 Frank Denis
|
||||
|
||||
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.
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 Josh Bleecher Snyder
|
||||
|
||||
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.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
bin
|
||||
tags
|
||||
|
|
@ -1 +0,0 @@
|
|||
custom: https://letsencrypt.org/donate/
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
version: 2
|
||||
|
||||
updates:
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/"
|
||||
groups:
|
||||
aws:
|
||||
patterns:
|
||||
- "github.com/aws/*"
|
||||
otel:
|
||||
patterns:
|
||||
- "go.opentelemetry.io/*"
|
||||
open-pull-requests-limit: 1
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "wednesday"
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: monthly
|
||||
open-pull-requests-limit: 1
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
---
|
||||
name: Default Template
|
||||
about: File a bug report or feature request
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Summary:**
|
||||
|
||||
|
||||
**Steps to reproduce:**
|
||||
|
||||
|
||||
**Expected result:**
|
||||
|
||||
|
||||
**Actual result:**
|
||||
|
||||
|
||||
**Additional details:**
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
# Boulder CI test suite workflow
|
||||
|
||||
name: Boulder CI
|
||||
|
||||
# Controls when the action will run.
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events but only for the main branch
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release-branch-*
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
# Main test jobs. This looks like a single job, but the matrix
|
||||
# items will multiply it. For example every entry in the
|
||||
# BOULDER_TOOLS_TAG list will run with every test. If there were two
|
||||
# tags and 5 tests there would be 10 jobs run.
|
||||
b:
|
||||
# The type of runner that the job will run on
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
strategy:
|
||||
# When set to true, GitHub cancels all in-progress jobs if any matrix job fails. Default: true
|
||||
fail-fast: false
|
||||
# Test matrix.
|
||||
matrix:
|
||||
# Add additional docker image tags here and all tests will be run with the additional image.
|
||||
BOULDER_TOOLS_TAG:
|
||||
- go1.24.4_2025-06-06
|
||||
# Tests command definitions. Use the entire "docker compose" command you want to run.
|
||||
tests:
|
||||
# Run ./test.sh --help for a description of each of the flags.
|
||||
- "./t.sh --lints --generate"
|
||||
- "./t.sh --integration"
|
||||
# Testing Config Changes:
|
||||
# Config changes that have landed in main but not yet been applied to
|
||||
# production can be made in `test/config-next/<component>.json`.
|
||||
#
|
||||
# Testing DB Schema Changes:
|
||||
# Database migrations in `sa/_db-next/migrations` are only performed
|
||||
# when `docker compose` is called using `-f docker-compose.yml -f
|
||||
# docker-compose.next.yml`.
|
||||
- "./tn.sh --integration"
|
||||
- "./t.sh --unit --enable-race-detection"
|
||||
- "./tn.sh --unit --enable-race-detection"
|
||||
- "./t.sh --start-py"
|
||||
|
||||
env:
|
||||
# This sets the docker image tag for the boulder-tools repository to
|
||||
# use in tests. It will be set appropriately for each tag in the list
|
||||
# defined in the matrix.
|
||||
BOULDER_TOOLS_TAG: ${{ matrix.BOULDER_TOOLS_TAG }}
|
||||
|
||||
# Sequence of tasks that will be executed as part of the job.
|
||||
steps:
|
||||
# Checks out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Docker Login
|
||||
# You may pin to the exact commit or the version.
|
||||
# uses: docker/login-action@f3364599c6aa293cdc2b8391b1b56d0c30e45c8a
|
||||
uses: docker/login-action@v3.4.0
|
||||
with:
|
||||
# Username used to log against the Docker registry
|
||||
username: ${{ secrets.DOCKER_USERNAME}}
|
||||
# Password or personal access token used to log against the Docker registry
|
||||
password: ${{ secrets.DOCKER_PASSWORD}}
|
||||
# Log out from the Docker registry at the end of a job
|
||||
logout: true
|
||||
continue-on-error: true
|
||||
|
||||
# Print the env variable being used to pull the docker image. For
|
||||
# informational use.
|
||||
- name: Print BOULDER_TOOLS_TAG
|
||||
run: echo "Using BOULDER_TOOLS_TAG ${BOULDER_TOOLS_TAG}"
|
||||
|
||||
# Pre-pull the docker containers before running the tests.
|
||||
- name: docker compose pull
|
||||
run: docker compose pull
|
||||
|
||||
# Run the test matrix. This will run
|
||||
- name: "Run Test: ${{ matrix.tests }}"
|
||||
run: ${{ matrix.tests }}
|
||||
|
||||
govulncheck:
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
# Checks out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
# When Go produces a security release, we want govulncheck to run
|
||||
# against the most recently released Go version.
|
||||
check-latest: true
|
||||
go-version: "stable"
|
||||
|
||||
- name: Run govulncheck
|
||||
run: go run golang.org/x/vuln/cmd/govulncheck@latest ./...
|
||||
|
||||
vendorcheck:
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
# When set to true, GitHub cancels all in-progress jobs if any matrix job fails. Default: true
|
||||
fail-fast: false
|
||||
matrix:
|
||||
go-version: [ '1.24.1' ]
|
||||
|
||||
steps:
|
||||
# Checks out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Go ${{ matrix.go-version }}
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
|
||||
- name: Verify vendor
|
||||
shell: bash
|
||||
run: |
|
||||
go mod tidy
|
||||
go mod vendor
|
||||
git diff --exit-code
|
||||
|
||||
|
||||
# This is a utility build job to detect if the status of any of the
|
||||
# above jobs have failed and fail if so. It is needed so there can be
|
||||
# one static job name that can be used to determine success of the job
|
||||
# in GitHub branch protection.
|
||||
# It does not block on the result of govulncheck so that a new vulnerability
|
||||
# disclosure does not prevent any other PRs from being merged.
|
||||
boulder_ci_test_matrix_status:
|
||||
permissions:
|
||||
contents: none
|
||||
if: ${{ always() }}
|
||||
runs-on: ubuntu-24.04
|
||||
name: Boulder CI Test Matrix
|
||||
needs:
|
||||
- b
|
||||
- vendorcheck
|
||||
steps:
|
||||
- name: Check boulder ci test matrix status
|
||||
if: ${{ needs.b.result != 'success' || needs.vendorcheck.result != 'success' }}
|
||||
run: exit 1
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
name: Check for IANA special-purpose address registry updates
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "20 16 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
check-iana-registries:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout iana/data from main branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
sparse-checkout: iana/data
|
||||
|
||||
# If the branch already exists, this will fail, which will remind us about
|
||||
# the outstanding PR.
|
||||
- name: Create an iana-registries-gha branch
|
||||
run: |
|
||||
git checkout --track origin/main -b iana-registries-gha
|
||||
|
||||
- name: Retrieve the IANA special-purpose address registries
|
||||
run: |
|
||||
IANA_IPV4="https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry-1.csv"
|
||||
IANA_IPV6="https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry-1.csv"
|
||||
|
||||
REPO_IPV4="iana/data/iana-ipv4-special-registry-1.csv"
|
||||
REPO_IPV6="iana/data/iana-ipv6-special-registry-1.csv"
|
||||
|
||||
curl --fail --location --show-error --silent --output "${REPO_IPV4}" "${IANA_IPV4}"
|
||||
curl --fail --location --show-error --silent --output "${REPO_IPV6}" "${IANA_IPV6}"
|
||||
|
||||
- name: Create a commit and pull request
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
shell:
|
||||
bash
|
||||
# `git diff --exit-code` returns an error code if there are any changes.
|
||||
run: |
|
||||
if ! git diff --exit-code; then
|
||||
git add iana/data/
|
||||
git config user.name "Irwin the IANA Bot"
|
||||
git commit \
|
||||
--message "Update IANA special-purpose address registries"
|
||||
git push origin HEAD
|
||||
gh pr create --fill
|
||||
fi
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
name: "Code Scanning - Action"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ release-branch-*, main]
|
||||
push:
|
||||
branches: [ release-branch-*, main]
|
||||
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
# required for all workflows
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
name: Check PR for changes that trigger CP/CPS review
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [ready_for_review, review_requested]
|
||||
paths:
|
||||
- 'features/features.go'
|
||||
|
||||
jobs:
|
||||
check-features:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "stable"
|
||||
|
||||
- name: Checkout Upstream
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.base.ref }}
|
||||
- name: Get Current Flags
|
||||
run: go run ./test/list-features/list-features.go | sort >| /tmp/currflags.txt
|
||||
|
||||
- name: Checkout PR
|
||||
uses: actions/checkout@v4
|
||||
- name: Get PR Flags
|
||||
run: go run ./test/list-features/list-features.go | sort >| /tmp/prflags.txt
|
||||
|
||||
- name: Identify New Flags
|
||||
id: newflags
|
||||
run: echo flagnames=$(comm -13 /tmp/currflags.txt /tmp/prflags.txt | paste -sd,) >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Comment PR
|
||||
if: ${{ steps.newflags.outputs.flagnames != '' }}
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const { owner, repo, number: issue_number } = context.issue;
|
||||
|
||||
// No need to comment if the PR description already has a CPS review.
|
||||
const reviewRegexp = /^CPS Compliance Review:/;
|
||||
if (reviewRegexp.test(context.payload.pull_request.body)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No need to comment if this task has previously commented on this PR.
|
||||
const commentMarker = '<!-- cps_review_check -->';
|
||||
const comments = await github.rest.issues.listComments({
|
||||
owner,
|
||||
repo,
|
||||
issue_number
|
||||
});
|
||||
if (comments.data.find(c => c.body.includes(commentMarker))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No existing review or comment found, post the comment.
|
||||
const prAuthor = context.payload.pull_request.user.login;
|
||||
const flagNames = '${{ steps.newflags.outputs.flagnames }}';
|
||||
const commentBody = `${commentMarker}\n@${prAuthor}, this PR adds one or more new feature flags: ${flagNames}. As such, this PR must be accompanied by a review of the Let's Encrypt CP/CPS to ensure that our behavior both before and after this flag is flipped is compliant with that document.\n\nPlease conduct such a review, then add your findings to the PR description in a paragraph beginning with "CPS Compliance Review:".`;
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number,
|
||||
body: commentBody
|
||||
});
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
name: Check PR for configuration and SQL changes
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [review_requested]
|
||||
paths:
|
||||
- 'test/config-next/*.json'
|
||||
- 'test/config-next/*.yaml'
|
||||
- 'test/config-next/*.yml'
|
||||
- 'sa/db-users/*.sql'
|
||||
- 'sa/db-next/**/*.sql'
|
||||
- 'sa/db/**/*.sql'
|
||||
|
||||
jobs:
|
||||
check-changes:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Comment PR
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const commentMarker = '<!-- deployment_ticket_check -->';
|
||||
const prAuthor = context.payload.pull_request.user.login;
|
||||
const commentBody = `${commentMarker}\n@${prAuthor}, this PR appears to contain configuration and/or SQL schema changes. Please ensure that a corresponding deployment ticket has been filed with the new values.\n`;
|
||||
const { owner, repo, number: issue_number } = context.issue;
|
||||
const issueRegexp = /IN-\d+/;
|
||||
|
||||
// Get PR body and all issue comments.
|
||||
const prBody = context.payload.pull_request.body;
|
||||
const comments = await github.rest.issues.listComments({
|
||||
owner,
|
||||
repo,
|
||||
issue_number
|
||||
});
|
||||
|
||||
if (issueRegexp.test(prBody) || comments.data.some(c => issueRegexp.test(c.body))) {
|
||||
// Issue number exists in PR body or comments.
|
||||
return;
|
||||
}
|
||||
|
||||
if (comments.data.find(c => c.body.includes(commentMarker))) {
|
||||
// Comment already exists.
|
||||
return;
|
||||
}
|
||||
|
||||
// No issue number or comment were found, post the comment.
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number,
|
||||
body: commentBody
|
||||
});
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# This GitHub Action runs only on pushes to main or a hotfix branch. It can
|
||||
# be used by tag protection rules to ensure that tags may only be pushed if
|
||||
# their corresponding commit was first pushed to one of those branches.
|
||||
name: Merged to main (or hotfix)
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release-branch-*
|
||||
jobs:
|
||||
merged-to-main:
|
||||
name: Merged to main (or hotfix)
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
# Build the Boulder Debian package on every PR, push to main, and tag push. On
|
||||
# tag pushes, additionally create a GitHub release and with the resulting Debian
|
||||
# package.
|
||||
# Keep in sync with try-release.yml, with the exception that try-release.yml
|
||||
# can have multiple entries in its matrix but this should only have one.
|
||||
name: Build release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- release-*
|
||||
|
||||
jobs:
|
||||
push-release:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
GO_VERSION:
|
||||
- "1.24.4"
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: '0' # Needed for verify-release-ancestry.sh to see origin/main
|
||||
|
||||
- name: Verify release ancestry
|
||||
run: ./tools/verify-release-ancestry.sh "$GITHUB_SHA"
|
||||
|
||||
- name: Build .deb
|
||||
id: build
|
||||
env:
|
||||
GO_VERSION: ${{ matrix.GO_VERSION }}
|
||||
run: docker run -v $PWD:/boulder -e GO_VERSION=$GO_VERSION -e COMMIT_ID="$(git rev-parse --short=8 HEAD)" ubuntu:24.04 bash -c 'apt update && apt -y install gnupg2 curl sudo git gcc && cd /boulder/ && ./tools/make-assets.sh'
|
||||
|
||||
- name: Compute checksums
|
||||
id: checksums
|
||||
# The files listed on this line must be identical to the files uploaded
|
||||
# in the last step.
|
||||
run: sha256sum boulder*.deb boulder*.tar.gz >| boulder-${{ matrix.GO_VERSION }}.$(date +%s)-$(git rev-parse --short=8 HEAD).checksums.txt
|
||||
|
||||
- name: Create release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# https://cli.github.com/manual/gh_release_create
|
||||
run: gh release create "${GITHUB_REF_NAME}"
|
||||
continue-on-error: true
|
||||
|
||||
- name: Upload release files
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# https://cli.github.com/manual/gh_release_upload
|
||||
run: gh release upload "${GITHUB_REF_NAME}" boulder*.deb boulder*.tar.gz boulder*.checksums.txt
|
||||
|
||||
- name: Build ct-test-srv Container
|
||||
run: docker buildx build . --build-arg "GO_VERSION=${{ matrix.GO_VERSION }}" -f test/ct-test-srv/Dockerfile -t "ghcr.io/letsencrypt/ct-test-srv:${{ github.ref_name }}-go${{ matrix.GO_VERSION }}"
|
||||
|
||||
- name: Login to ghcr.io
|
||||
run: printenv GITHUB_TOKEN | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Push ct-test-srv Container
|
||||
run: docker push "ghcr.io/letsencrypt/ct-test-srv:${{ github.ref_name }}-go${{ matrix.GO_VERSION }}"
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
# Try building the Boulder Debian package on every PR and push to main.
|
||||
# This is to make sure the actual release job will succeed when we tag a
|
||||
# release.
|
||||
# Keep in sync with release.yml
|
||||
name: Try release
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
try-release:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
GO_VERSION:
|
||||
- "1.24.4"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Build .deb
|
||||
id: build
|
||||
env:
|
||||
GO_VERSION: ${{ matrix.GO_VERSION }}
|
||||
run: docker run -v $PWD:/boulder -e GO_VERSION=$GO_VERSION -e COMMIT_ID="$(git rev-parse --short=8 HEAD)" ubuntu:24.04 bash -c 'apt update && apt -y install gnupg2 curl sudo git gcc && cd /boulder/ && ./tools/make-assets.sh'
|
||||
|
||||
- name: Compute checksums
|
||||
id: checksums
|
||||
# The files listed on this line must be identical to the files uploaded
|
||||
# in the last step of the real release action.
|
||||
run: sha256sum boulder*.deb boulder*.tar.gz >| boulder-${{ matrix.GO_VERSION }}.$(date +%s)-$(git rev-parse --short=8 HEAD).checksums.txt
|
||||
|
||||
- name: List files
|
||||
id: files
|
||||
run: ls boulder*.deb boulder*.tar.gz boulder*.checksums.txt
|
||||
|
||||
- name: Show checksums
|
||||
id: check
|
||||
run: cat boulder*.checksums.txt
|
||||
|
||||
- name: Build ct-test-srv Container
|
||||
run: docker buildx build . --build-arg "GO_VERSION=${{ matrix.GO_VERSION }}" -f test/ct-test-srv/Dockerfile -t "ghcr.io/letsencrypt/ct-test-srv:${{ github.sha }}-go${{ matrix.GO_VERSION }}"
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.pyc
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
bin
|
||||
.gocache
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
# Vim swap files
|
||||
*.sw?
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.sw?
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
*.coverprofile
|
||||
|
||||
tags
|
||||
|
||||
# IDE support files
|
||||
.idea
|
||||
|
||||
.vscode/*
|
||||
|
||||
# ProxySQL log files
|
||||
test/proxysql/*.log*
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
version: "2"
|
||||
linters:
|
||||
default: none
|
||||
enable:
|
||||
- asciicheck
|
||||
- bidichk
|
||||
- errcheck
|
||||
- gosec
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
- nolintlint
|
||||
- spancheck
|
||||
- sqlclosecheck
|
||||
- staticcheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- wastedassign
|
||||
settings:
|
||||
errcheck:
|
||||
exclude-functions:
|
||||
- (net/http.ResponseWriter).Write
|
||||
- (net.Conn).Write
|
||||
- encoding/binary.Write
|
||||
- io.Write
|
||||
- net/http.Write
|
||||
- os.Remove
|
||||
- github.com/miekg/dns.WriteMsg
|
||||
govet:
|
||||
disable:
|
||||
- fieldalignment
|
||||
- shadow
|
||||
enable-all: true
|
||||
settings:
|
||||
printf:
|
||||
funcs:
|
||||
- (github.com/letsencrypt/boulder/log.Logger).Errf
|
||||
- (github.com/letsencrypt/boulder/log.Logger).Warningf
|
||||
- (github.com/letsencrypt/boulder/log.Logger).Infof
|
||||
- (github.com/letsencrypt/boulder/log.Logger).Debugf
|
||||
- (github.com/letsencrypt/boulder/log.Logger).AuditInfof
|
||||
- (github.com/letsencrypt/boulder/log.Logger).AuditErrf
|
||||
- (github.com/letsencrypt/boulder/ocsp/responder).SampledError
|
||||
- (github.com/letsencrypt/boulder/web.RequestEvent).AddError
|
||||
gosec:
|
||||
excludes:
|
||||
# TODO: Identify, fix, and remove violations of most of these rules
|
||||
- G101 # Potential hardcoded credentials
|
||||
- G102 # Binds to all network interfaces
|
||||
- G104 # Errors unhandled
|
||||
- G107 # Potential HTTP request made with variable url
|
||||
- G201 # SQL string formatting
|
||||
- G202 # SQL string concatenation
|
||||
- G204 # Subprocess launched with variable
|
||||
- G302 # Expect file permissions to be 0600 or less
|
||||
- G306 # Expect WriteFile permissions to be 0600 or less
|
||||
- G304 # Potential file inclusion via variable
|
||||
- G401 # Use of weak cryptographic primitive
|
||||
- G402 # TLS InsecureSkipVerify set true.
|
||||
- G403 # RSA keys should be at least 2048 bits
|
||||
- G404 # Use of weak random number generator
|
||||
nolintlint:
|
||||
require-explanation: true
|
||||
require-specific: true
|
||||
allow-unused: false
|
||||
staticcheck:
|
||||
checks:
|
||||
- all
|
||||
# TODO: Identify, fix, and remove violations of most of these rules
|
||||
- -S1029 # Range over the string directly
|
||||
- -SA1019 # Using a deprecated function, variable, constant or field
|
||||
- -SA6003 # Converting a string to a slice of runes before ranging over it
|
||||
- -ST1000 # Incorrect or missing package comment
|
||||
- -ST1003 # Poorly chosen identifier
|
||||
- -ST1005 # Incorrectly formatted error string
|
||||
- -QF1001 # Could apply De Morgan's law
|
||||
- -QF1003 # Could use tagged switch
|
||||
- -QF1004 # Could use strings.Split instead
|
||||
- -QF1007 # Could merge conditional assignment into variable declaration
|
||||
- -QF1008 # Could remove embedded field from selector
|
||||
- -QF1009 # Probably want to use time.Time.Equal
|
||||
- -QF1012 # Use fmt.Fprintf(...) instead of Write(fmt.Sprintf(...))
|
||||
exclusions:
|
||||
presets:
|
||||
- std-error-handling
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
[files]
|
||||
extend-exclude = [
|
||||
".git/",
|
||||
"go.mod",
|
||||
"go.sum",
|
||||
"vendor/",
|
||||
]
|
||||
ignore-hidden = false
|
||||
|
||||
[default]
|
||||
extend-ignore-re = [
|
||||
# Anything base64 or base64url longer than 36 chars is probably encoded.
|
||||
'\b[0-9A-Za-z+/]{36,}\b',
|
||||
'\b[0-9A-Za-z_-]{36,}\b',
|
||||
"0002a4ba3cf408927759",
|
||||
"65CuDAA",
|
||||
'"sql_warnings", "TrUe"',
|
||||
'"tx_read_only", "FalSe"',
|
||||
"evenMOREcaps",
|
||||
'"iSsUe"',
|
||||
]
|
||||
|
||||
[default.extend-words]
|
||||
# Extended DNS Error
|
||||
"ede" = "ede"
|
||||
# Alternative spelling
|
||||
"unmarshaling" = "unmarshaling"
|
||||
|
||||
[default.extend-identifiers]
|
||||
"caaFailer" = "caaFailer"
|
||||
"challStrat" = "challStrat"
|
||||
"ExpectedStratType" = "ExpectedStratType"
|
||||
"otConf" = "otConf"
|
||||
"serInt" = "serInt"
|
||||
"StratName" = "StratName"
|
||||
"typ" = "typ"
|
||||
"UPDATEs" = "UPDATEs"
|
||||
"vai" = "vai"
|
||||
|
|
@ -1 +0,0 @@
|
|||
* @letsencrypt/boulder-developers
|
||||
|
|
@ -1,375 +0,0 @@
|
|||
Copyright 2016 ISRG. All rights reserved.
|
||||
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
OBJDIR ?= $(shell pwd)/bin
|
||||
DESTDIR ?= /usr/local/bin
|
||||
ARCHIVEDIR ?= /tmp
|
||||
|
||||
VERSION ?= 1.0.0
|
||||
EPOCH ?= 1
|
||||
MAINTAINER ?= "Community"
|
||||
|
||||
CMDS = admin boulder ceremony ct-test-srv pardot-test-srv chall-test-srv
|
||||
CMD_BINS = $(addprefix bin/, $(CMDS) )
|
||||
OBJECTS = $(CMD_BINS)
|
||||
|
||||
# Build environment variables (referencing core/util.go)
|
||||
COMMIT_ID = $(shell git rev-parse --short=8 HEAD)
|
||||
|
||||
BUILD_ID = $(shell git symbolic-ref --short=8 HEAD 2>/dev/null) +$(COMMIT_ID)
|
||||
BUILD_ID_VAR = github.com/letsencrypt/boulder/core.BuildID
|
||||
|
||||
BUILD_HOST = $(shell whoami)@$(shell hostname)
|
||||
BUILD_HOST_VAR = github.com/letsencrypt/boulder/core.BuildHost
|
||||
|
||||
BUILD_TIME = $(shell date -u)
|
||||
BUILD_TIME_VAR = github.com/letsencrypt/boulder/core.BuildTime
|
||||
|
||||
GO_BUILD_FLAGS = -ldflags "-X \"$(BUILD_ID_VAR)=$(BUILD_ID)\" -X \"$(BUILD_TIME_VAR)=$(BUILD_TIME)\" -X \"$(BUILD_HOST_VAR)=$(BUILD_HOST)\""
|
||||
|
||||
.PHONY: all build build_cmds deb tar
|
||||
all: build
|
||||
|
||||
build: $(OBJECTS)
|
||||
|
||||
$(OBJDIR):
|
||||
@mkdir -p $(OBJDIR)
|
||||
|
||||
$(CMD_BINS): build_cmds
|
||||
|
||||
build_cmds: | $(OBJDIR)
|
||||
echo $(OBJECTS)
|
||||
GOBIN=$(OBJDIR) GO111MODULE=on go install -mod=vendor $(GO_BUILD_FLAGS) ./...
|
||||
|
||||
# Building a .deb requires `fpm` from https://github.com/jordansissel/fpm
|
||||
# which you can install with `gem install fpm`.
|
||||
# It is recommended that maintainers use environment overrides to specify
|
||||
# Version and Epoch, such as:
|
||||
#
|
||||
# VERSION=0.1.9 EPOCH=52 MAINTAINER="$(whoami)" ARCHIVEDIR=/tmp make build deb
|
||||
deb: build
|
||||
fpm -f -s dir -t deb --name "boulder" \
|
||||
--license "Mozilla Public License v2.0" --vendor "ISRG" \
|
||||
--url "https://github.com/letsencrypt/boulder" --prefix=/opt/boulder \
|
||||
--version "$(VERSION)" --iteration "$(COMMIT_ID)" --epoch "$(EPOCH)" \
|
||||
--package "$(ARCHIVEDIR)/boulder-$(VERSION)-$(COMMIT_ID).x86_64.deb" \
|
||||
--description "Boulder is an ACME-compatible X.509 Certificate Authority" \
|
||||
--maintainer "$(MAINTAINER)" \
|
||||
test/config/ sa/db data/ $(OBJECTS)
|
||||
|
||||
tar: build
|
||||
fpm -f -s dir -t tar --name "boulder" --prefix=/opt/boulder \
|
||||
--package "$(ARCHIVEDIR)/boulder-$(VERSION)-$(COMMIT_ID).amd64.tar" \
|
||||
test/config/ sa/db data/ $(OBJECTS)
|
||||
gzip -f "$(ARCHIVEDIR)/boulder-$(VERSION)-$(COMMIT_ID).amd64.tar"
|
||||
286
third-party/github.com/letsencrypt/boulder/README.md
vendored
286
third-party/github.com/letsencrypt/boulder/README.md
vendored
|
|
@ -1,286 +0,0 @@
|
|||
# Boulder - An ACME CA
|
||||
|
||||
[](https://github.com/letsencrypt/boulder/actions/workflows/boulder-ci.yml?query=branch%3Amain)
|
||||
|
||||
This is an implementation of an ACME-based CA. The [ACME
|
||||
protocol](https://github.com/ietf-wg-acme/acme/) allows the CA to automatically
|
||||
verify that an applicant for a certificate actually controls an identifier, and
|
||||
allows subscribers to issue and revoke certificates for the identifiers they
|
||||
control. Boulder is the software that runs [Let's
|
||||
Encrypt](https://letsencrypt.org).
|
||||
|
||||
## Contents
|
||||
|
||||
* [Overview](#overview)
|
||||
* [Setting up Boulder](#setting-up-boulder)
|
||||
* [Development](#development)
|
||||
* [Working with Certbot](#working-with-certbot)
|
||||
* [Working with another ACME Client](#working-with-another-acme-client)
|
||||
* [Production](#production)
|
||||
* [Contributing](#contributing)
|
||||
* [License](#license)
|
||||
|
||||
## Overview
|
||||
|
||||
Boulder is divided into the following main components:
|
||||
|
||||
1. Web Front Ends (one per API version)
|
||||
2. Registration Authority
|
||||
3. Validation Authority
|
||||
4. Certificate Authority
|
||||
5. Storage Authority
|
||||
6. Publisher
|
||||
7. OCSP Responder
|
||||
8. CRL Updater
|
||||
|
||||
This component model lets us separate the function of the CA by security
|
||||
context. The Web Front End, Validation Authority, OCSP Responder and
|
||||
Publisher need access to the Internet, which puts them at greater risk of
|
||||
compromise. The Registration Authority can live without Internet
|
||||
connectivity, but still needs to talk to the Web Front End and Validation
|
||||
Authority. The Certificate Authority need only receive instructions from the
|
||||
Registration Authority. All components talk to the SA for storage, so most
|
||||
lines indicating SA RPCs are not shown here.
|
||||
|
||||
```text
|
||||
CA ---------> Publisher
|
||||
^
|
||||
|
|
||||
Subscriber -> WFE --> RA --> SA --> MariaDB
|
||||
| ^
|
||||
Subscriber server <- VA <----+ |
|
||||
|
|
||||
Browser -------------------> OCSP Responder
|
||||
```
|
||||
|
||||
Internally, the logic of the system is based around five types of objects:
|
||||
accounts, authorizations, challenges, orders and certificates, mapping directly
|
||||
to the resources of the same name in ACME. Requests from ACME clients result in
|
||||
new objects and changes to objects. The Storage Authority maintains persistent
|
||||
copies of the current set of objects.
|
||||
|
||||
Boulder uses gRPC for inter-component communication. For components that you
|
||||
want to be remote, it is necessary to instantiate a "client" and "server" for
|
||||
that component. The client implements the component's Go interface, while the
|
||||
server has the actual logic for the component. A high level overview for this
|
||||
communication model can be found in the [gRPC
|
||||
documentation](https://www.grpc.io/docs/).
|
||||
|
||||
The full details of how the various ACME operations happen in Boulder are
|
||||
laid out in
|
||||
[DESIGN.md](https://github.com/letsencrypt/boulder/blob/main/docs/DESIGN.md).
|
||||
|
||||
## Setting up Boulder
|
||||
|
||||
### Development
|
||||
|
||||
Boulder has a Dockerfile and uses Docker Compose to make it easy to install
|
||||
and set up all its dependencies. This is how the maintainers work on Boulder,
|
||||
and is our main recommended way to run it for development/experimentation. It
|
||||
is not suitable for use as a production environment.
|
||||
|
||||
While we aim to make Boulder easy to setup ACME client developers may find
|
||||
[Pebble](https://github.com/letsencrypt/pebble), a miniature version of
|
||||
Boulder, to be better suited for continuous integration and quick
|
||||
experimentation.
|
||||
|
||||
We recommend setting git's [fsckObjects
|
||||
setting](https://groups.google.com/forum/#!topic/binary-transparency/f-BI4o8HZW0/discussion)
|
||||
before getting a copy of Boulder to have better integrity guarantees for
|
||||
updates.
|
||||
|
||||
Clone the boulder repository:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/letsencrypt/boulder/
|
||||
cd boulder
|
||||
```
|
||||
|
||||
Additionally, make sure you have Docker Engine 1.13.0+ and Docker Compose
|
||||
1.10.0+ installed. If you do not, you can follow Docker's [installation
|
||||
instructions](https://docs.docker.com/compose/install/).
|
||||
|
||||
We recommend having **at least 2GB of RAM** available on your Docker host. In
|
||||
practice using less RAM may result in the MariaDB container failing in
|
||||
non-obvious ways.
|
||||
|
||||
To start Boulder in a Docker container, run:
|
||||
|
||||
```shell
|
||||
docker compose up
|
||||
```
|
||||
|
||||
To run our standard battery of tests (lints, unit, integration):
|
||||
|
||||
```shell
|
||||
docker compose run --use-aliases boulder ./test.sh
|
||||
```
|
||||
|
||||
To run all unit tests:
|
||||
|
||||
```shell
|
||||
docker compose run --use-aliases boulder ./test.sh --unit
|
||||
```
|
||||
|
||||
To run specific unit tests (example is of the ./va directory):
|
||||
|
||||
```shell
|
||||
docker compose run --use-aliases boulder ./test.sh --unit --filter=./va
|
||||
```
|
||||
|
||||
To run all integration tests:
|
||||
|
||||
```shell
|
||||
docker compose run --use-aliases boulder ./test.sh --integration
|
||||
```
|
||||
|
||||
To run specific integration tests (example runs TestAkamaiPurgerDrainQueueFails and TestWFECORS):
|
||||
|
||||
```shell
|
||||
docker compose run --use-aliases boulder ./test.sh --filter TestAkamaiPurgerDrainQueueFails/TestWFECORS
|
||||
```
|
||||
|
||||
To get a list of available integration tests:
|
||||
|
||||
```shell
|
||||
docker compose run --use-aliases boulder ./test.sh --list-integration-tests
|
||||
```
|
||||
|
||||
The configuration in docker-compose.yml mounts your boulder checkout at
|
||||
/boulder so you can edit code on your host and it will be immediately
|
||||
reflected inside the Docker containers run with `docker compose`.
|
||||
|
||||
If you have problems with Docker, you may want to try [removing all
|
||||
containers and
|
||||
volumes](https://www.digitalocean.com/community/tutorials/how-to-remove-docker-images-containers-and-volumes).
|
||||
|
||||
By default, Boulder uses a fake DNS resolver that resolves all hostnames to
|
||||
127.0.0.1. This is suitable for running integration tests inside the Docker
|
||||
container. If you want Boulder to be able to communicate with a client
|
||||
running on your host instead, you should find your host's Docker IP with:
|
||||
|
||||
```shell
|
||||
ifconfig docker0 | grep "inet addr:" | cut -d: -f2 | awk '{ print $1}'
|
||||
```
|
||||
|
||||
And edit docker-compose.yml to change the `FAKE_DNS` environment variable to
|
||||
match. This will cause Boulder's stubbed-out DNS resolver (`sd-test-srv`) to
|
||||
respond to all A queries with the address in `FAKE_DNS`.
|
||||
|
||||
If you use a host-based firewall (e.g. `ufw` or `iptables`) make sure you allow
|
||||
connections from the Docker instance to your host on the required validation
|
||||
ports to your ACME client.
|
||||
|
||||
Alternatively, you can override the docker-compose.yml default with an
|
||||
environmental variable using -e (replace 172.17.0.1 with the host IPv4
|
||||
address found in the command above)
|
||||
|
||||
```shell
|
||||
docker compose run --use-aliases -e FAKE_DNS=172.17.0.1 --service-ports boulder ./start.py
|
||||
```
|
||||
|
||||
Running tests without the `./test.sh` wrapper:
|
||||
|
||||
Run all unit tests
|
||||
|
||||
```shell
|
||||
docker compose run --use-aliases boulder go test -p 1 ./...
|
||||
```
|
||||
|
||||
Run unit tests for a specific directory:
|
||||
|
||||
```shell
|
||||
docker compose run --use-aliases boulder go test <DIRECTORY>
|
||||
```
|
||||
|
||||
Run integration tests (omit `--filter <REGEX>` to run all):
|
||||
|
||||
```shell
|
||||
docker compose run --use-aliases boulder python3 test/integration-test.py --chisel --gotest --filter <REGEX>
|
||||
```
|
||||
|
||||
### Working with Certbot
|
||||
|
||||
Check out the Certbot client from https://github.com/certbot/certbot and
|
||||
follow their setup instructions. Once you've got the client set up, you'll
|
||||
probably want to run it against your local Boulder. There are a number of
|
||||
command line flags that are necessary to run the client against a local
|
||||
Boulder, and without root access. The simplest way to run the client locally
|
||||
is to use a convenient alias for certbot (`certbot_test`) with a custom
|
||||
`SERVER` environment variable:
|
||||
|
||||
```shell
|
||||
SERVER=http://localhost:4001/directory certbot_test certonly --standalone -d test.example.com
|
||||
```
|
||||
|
||||
Your local Boulder instance uses a fake DNS resolver that returns 127.0.0.1
|
||||
for any query, so you can use any value for the -d flag. To return an answer
|
||||
other than `127.0.0.1` change the Boulder `FAKE_DNS` environment variable to
|
||||
another IP address.
|
||||
|
||||
### Working with another ACME Client
|
||||
|
||||
Once you have followed the Boulder development environment instructions and have
|
||||
started the containers you will find the ACME endpoints exposed to your host at
|
||||
the following URLs:
|
||||
|
||||
* ACME v2, HTTP: `http://localhost:4001/directory`
|
||||
* ACME v2, HTTPS: `https://localhost:4431/directory`
|
||||
|
||||
To access the HTTPS versions of the endpoints you will need to configure your
|
||||
ACME client software to use a CA truststore that contains the
|
||||
`test/certs/ipki/minica.pem` CA certificate. See
|
||||
[`test/certs/README.md`](https://github.com/letsencrypt/boulder/blob/main/test/certs/README.md)
|
||||
for more information.
|
||||
|
||||
Your local Boulder instance uses a fake DNS resolver that returns 127.0.0.1
|
||||
for any query, allowing you to issue certificates for any domain as if it
|
||||
resolved to your localhost. To return an answer other than `127.0.0.1` change
|
||||
the Boulder `FAKE_DNS` environment variable to another IP address.
|
||||
|
||||
Most often you will want to configure `FAKE_DNS` to point to your host
|
||||
machine where you run an ACME client.
|
||||
|
||||
### Production
|
||||
|
||||
Boulder is custom built for Let's Encrypt and is intended only to support the
|
||||
Web PKI and the CA/Browser forum's baseline requirements. In our experience
|
||||
often Boulder is not the right fit for organizations that are evaluating it for
|
||||
production usage. In most cases a centrally managed PKI that doesn't require
|
||||
domain-authorization with ACME is a better choice. For this environment we
|
||||
recommend evaluating a project other than Boulder.
|
||||
|
||||
We offer a brief [deployment and implementation
|
||||
guide](https://github.com/letsencrypt/boulder/wiki/Deployment-&-Implementation-Guide)
|
||||
that describes some of the required work and security considerations involved in
|
||||
using Boulder in a production environment. As-is the docker based Boulder
|
||||
development environment is **not suitable for
|
||||
production usage**. It uses private key material that is publicly available,
|
||||
exposes debug ports and is brittle to component failure.
|
||||
|
||||
While we are supportive of other organization's deploying Boulder in
|
||||
a production setting we prioritize support and development work that favors
|
||||
Let's Encrypt's mission. This means we may not be able to provide timely support
|
||||
or accept pull-requests that deviate significantly from our first line goals. If
|
||||
you've thoroughly evaluated the alternatives and Boulder is definitely the best
|
||||
fit we're happy to answer questions to the best of our ability.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please take a look at
|
||||
[CONTRIBUTING.md](https://github.com/letsencrypt/boulder/blob/main/docs/CONTRIBUTING.md)
|
||||
for our guidelines on submitting patches, code review process, code of conduct,
|
||||
and various other tips related to working on the codebase.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
The code of conduct for everyone participating in this community in any capacity
|
||||
is available for reference
|
||||
[on the community forum](https://community.letsencrypt.org/guidelines).
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the Mozilla Public License 2.0, the full text
|
||||
of which can be found in the
|
||||
[LICENSE.txt](https://github.com/letsencrypt/boulder/blob/main/LICENSE.txt)
|
||||
file.
|
||||
|
|
@ -1,402 +0,0 @@
|
|||
package akamai
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/md5" //nolint: gosec // MD5 is required by the Akamai API.
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jmhodges/clock"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/crypto/ocsp"
|
||||
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/metrics"
|
||||
)
|
||||
|
||||
const (
|
||||
timestampFormat = "20060102T15:04:05-0700"
|
||||
v3PurgePath = "/ccu/v3/delete/url/"
|
||||
v3PurgeTagPath = "/ccu/v3/delete/tag/"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrAllRetriesFailed indicates that all purge submission attempts have
|
||||
// failed.
|
||||
ErrAllRetriesFailed = errors.New("all attempts to submit purge request failed")
|
||||
|
||||
// errFatal is returned by the purge method of CachePurgeClient to indicate
|
||||
// that it failed for a reason that cannot be remediated by retrying the
|
||||
// request.
|
||||
errFatal = errors.New("fatal error")
|
||||
)
|
||||
|
||||
type v3PurgeRequest struct {
|
||||
Objects []string `json:"objects"`
|
||||
}
|
||||
|
||||
type purgeResponse struct {
|
||||
HTTPStatus int `json:"httpStatus"`
|
||||
Detail string `json:"detail"`
|
||||
EstimatedSeconds int `json:"estimatedSeconds"`
|
||||
PurgeID string `json:"purgeId"`
|
||||
}
|
||||
|
||||
// CachePurgeClient talks to the Akamai CCU REST API. It is safe to make
|
||||
// concurrent requests using this client.
|
||||
type CachePurgeClient struct {
|
||||
client *http.Client
|
||||
apiEndpoint string
|
||||
apiHost string
|
||||
apiScheme string
|
||||
clientToken string
|
||||
clientSecret string
|
||||
accessToken string
|
||||
v3Network string
|
||||
retries int
|
||||
retryBackoff time.Duration
|
||||
log blog.Logger
|
||||
purgeLatency prometheus.Histogram
|
||||
purges *prometheus.CounterVec
|
||||
clk clock.Clock
|
||||
}
|
||||
|
||||
// NewCachePurgeClient performs some basic validation of supplied configuration
|
||||
// and returns a newly constructed CachePurgeClient.
|
||||
func NewCachePurgeClient(
|
||||
baseURL,
|
||||
clientToken,
|
||||
secret,
|
||||
accessToken,
|
||||
network string,
|
||||
retries int,
|
||||
retryBackoff time.Duration,
|
||||
log blog.Logger, scope prometheus.Registerer,
|
||||
) (*CachePurgeClient, error) {
|
||||
if network != "production" && network != "staging" {
|
||||
return nil, fmt.Errorf("'V3Network' must be \"staging\" or \"production\", got %q", network)
|
||||
}
|
||||
|
||||
endpoint, err := url.Parse(strings.TrimSuffix(baseURL, "/"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse 'BaseURL' as a URL: %s", err)
|
||||
}
|
||||
|
||||
purgeLatency := prometheus.NewHistogram(prometheus.HistogramOpts{
|
||||
Name: "ccu_purge_latency",
|
||||
Help: "Histogram of latencies of CCU purges",
|
||||
Buckets: metrics.InternetFacingBuckets,
|
||||
})
|
||||
scope.MustRegister(purgeLatency)
|
||||
|
||||
purges := prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "ccu_purges",
|
||||
Help: "A counter of CCU purges labelled by the result",
|
||||
}, []string{"type"})
|
||||
scope.MustRegister(purges)
|
||||
|
||||
return &CachePurgeClient{
|
||||
client: new(http.Client),
|
||||
apiEndpoint: endpoint.String(),
|
||||
apiHost: endpoint.Host,
|
||||
apiScheme: strings.ToLower(endpoint.Scheme),
|
||||
clientToken: clientToken,
|
||||
clientSecret: secret,
|
||||
accessToken: accessToken,
|
||||
v3Network: network,
|
||||
retries: retries,
|
||||
retryBackoff: retryBackoff,
|
||||
log: log,
|
||||
clk: clock.New(),
|
||||
purgeLatency: purgeLatency,
|
||||
purges: purges,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// makeAuthHeader constructs a special Akamai authorization header. This header
|
||||
// is used to identify clients to Akamai's EdgeGrid APIs. For a more detailed
|
||||
// description of the generation process see their docs:
|
||||
// https://developer.akamai.com/introduction/Client_Auth.html
|
||||
func (cpc *CachePurgeClient) makeAuthHeader(body []byte, apiPath string, nonce string) string {
|
||||
// The akamai API is very time sensitive (recommending reliance on a stratum 2
|
||||
// or better time source). Additionally, timestamps MUST be in UTC.
|
||||
timestamp := cpc.clk.Now().UTC().Format(timestampFormat)
|
||||
header := fmt.Sprintf(
|
||||
"EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;",
|
||||
cpc.clientToken,
|
||||
cpc.accessToken,
|
||||
timestamp,
|
||||
nonce,
|
||||
)
|
||||
bodyHash := sha256.Sum256(body)
|
||||
tbs := fmt.Sprintf(
|
||||
"%s\t%s\t%s\t%s\t%s\t%s\t%s",
|
||||
"POST",
|
||||
cpc.apiScheme,
|
||||
cpc.apiHost,
|
||||
apiPath,
|
||||
// Signed headers are not required for this request type.
|
||||
"",
|
||||
base64.StdEncoding.EncodeToString(bodyHash[:]),
|
||||
header,
|
||||
)
|
||||
cpc.log.Debugf("To-be-signed Akamai EdgeGrid authentication %q", tbs)
|
||||
|
||||
h := hmac.New(sha256.New, signingKey(cpc.clientSecret, timestamp))
|
||||
h.Write([]byte(tbs))
|
||||
return fmt.Sprintf(
|
||||
"%ssignature=%s",
|
||||
header,
|
||||
base64.StdEncoding.EncodeToString(h.Sum(nil)),
|
||||
)
|
||||
}
|
||||
|
||||
// signingKey makes a signing key by HMAC'ing the timestamp
|
||||
// using a client secret as the key.
|
||||
func signingKey(clientSecret string, timestamp string) []byte {
|
||||
h := hmac.New(sha256.New, []byte(clientSecret))
|
||||
h.Write([]byte(timestamp))
|
||||
key := make([]byte, base64.StdEncoding.EncodedLen(32))
|
||||
base64.StdEncoding.Encode(key, h.Sum(nil))
|
||||
return key
|
||||
}
|
||||
|
||||
// PurgeTags constructs and dispatches a request to purge a batch of Tags.
|
||||
func (cpc *CachePurgeClient) PurgeTags(tags []string) error {
|
||||
purgeReq := v3PurgeRequest{
|
||||
Objects: tags,
|
||||
}
|
||||
endpoint := fmt.Sprintf("%s%s%s", cpc.apiEndpoint, v3PurgeTagPath, cpc.v3Network)
|
||||
return cpc.authedRequest(endpoint, purgeReq)
|
||||
}
|
||||
|
||||
// purgeURLs constructs and dispatches a request to purge a batch of URLs.
|
||||
func (cpc *CachePurgeClient) purgeURLs(urls []string) error {
|
||||
purgeReq := v3PurgeRequest{
|
||||
Objects: urls,
|
||||
}
|
||||
endpoint := fmt.Sprintf("%s%s%s", cpc.apiEndpoint, v3PurgePath, cpc.v3Network)
|
||||
return cpc.authedRequest(endpoint, purgeReq)
|
||||
}
|
||||
|
||||
// authedRequest POSTs the JSON marshaled purge request to the provided endpoint
|
||||
// along with an Akamai authorization header.
|
||||
func (cpc *CachePurgeClient) authedRequest(endpoint string, body v3PurgeRequest) error {
|
||||
reqBody, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", err, errFatal)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(reqBody))
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", err, errFatal)
|
||||
}
|
||||
|
||||
endpointURL, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while parsing %q as URL: %s: %w", endpoint, err, errFatal)
|
||||
}
|
||||
|
||||
authorization := cpc.makeAuthHeader(reqBody, endpointURL.Path, core.RandomString(16))
|
||||
req.Header.Set("Authorization", authorization)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
cpc.log.Debugf("POSTing to endpoint %q (header %q) (body %q)", endpoint, authorization, reqBody)
|
||||
|
||||
start := cpc.clk.Now()
|
||||
resp, err := cpc.client.Do(req)
|
||||
cpc.purgeLatency.Observe(cpc.clk.Since(start).Seconds())
|
||||
if err != nil {
|
||||
return fmt.Errorf("while POSTing to endpoint %q: %w", endpointURL, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.Body == nil {
|
||||
return fmt.Errorf("response body was empty from URL %q", resp.Request.URL)
|
||||
}
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Success for a request to purge a URL or Cache tag is 'HTTP 201'.
|
||||
// https://techdocs.akamai.com/purge-cache/reference/delete-url
|
||||
// https://techdocs.akamai.com/purge-cache/reference/delete-tag
|
||||
if resp.StatusCode != http.StatusCreated {
|
||||
switch resp.StatusCode {
|
||||
// https://techdocs.akamai.com/purge-cache/reference/403
|
||||
case http.StatusForbidden:
|
||||
return fmt.Errorf("client not authorized to make requests for URL %q: %w", resp.Request.URL, errFatal)
|
||||
|
||||
// https://techdocs.akamai.com/purge-cache/reference/504
|
||||
case http.StatusGatewayTimeout:
|
||||
return fmt.Errorf("server timed out, got HTTP %d (body %q) for URL %q", resp.StatusCode, respBody, resp.Request.URL)
|
||||
|
||||
// https://techdocs.akamai.com/purge-cache/reference/429
|
||||
case http.StatusTooManyRequests:
|
||||
return fmt.Errorf("exceeded request count rate limit, got HTTP %d (body %q) for URL %q", resp.StatusCode, respBody, resp.Request.URL)
|
||||
|
||||
// https://techdocs.akamai.com/purge-cache/reference/413
|
||||
case http.StatusRequestEntityTooLarge:
|
||||
return fmt.Errorf("exceeded request size rate limit, got HTTP %d (body %q) for URL %q", resp.StatusCode, respBody, resp.Request.URL)
|
||||
default:
|
||||
return fmt.Errorf("received HTTP %d (body %q) for URL %q", resp.StatusCode, respBody, resp.Request.URL)
|
||||
}
|
||||
}
|
||||
|
||||
var purgeInfo purgeResponse
|
||||
err = json.Unmarshal(respBody, &purgeInfo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while unmarshalling body %q from URL %q as JSON: %w", respBody, resp.Request.URL, err)
|
||||
}
|
||||
|
||||
// Ensure the unmarshaled body concurs with the status of the response
|
||||
// received.
|
||||
if purgeInfo.HTTPStatus != http.StatusCreated {
|
||||
if purgeInfo.HTTPStatus == http.StatusForbidden {
|
||||
return fmt.Errorf("client not authorized to make requests to URL %q: %w", resp.Request.URL, errFatal)
|
||||
}
|
||||
return fmt.Errorf("unmarshaled HTTP %d (body %q) from URL %q", purgeInfo.HTTPStatus, respBody, resp.Request.URL)
|
||||
}
|
||||
|
||||
cpc.log.AuditInfof("Purge request sent successfully (ID %s) (body %s). Purge expected in %ds",
|
||||
purgeInfo.PurgeID, reqBody, purgeInfo.EstimatedSeconds)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Purge dispatches the provided URLs in a request to the Akamai Fast-Purge API.
|
||||
// The request will be attempted cpc.retries number of times before giving up
|
||||
// and returning ErrAllRetriesFailed.
|
||||
func (cpc *CachePurgeClient) Purge(urls []string) error {
|
||||
successful := false
|
||||
for i := range cpc.retries + 1 {
|
||||
cpc.clk.Sleep(core.RetryBackoff(i, cpc.retryBackoff, time.Minute, 1.3))
|
||||
|
||||
err := cpc.purgeURLs(urls)
|
||||
if err != nil {
|
||||
if errors.Is(err, errFatal) {
|
||||
cpc.purges.WithLabelValues("fatal failure").Inc()
|
||||
return err
|
||||
}
|
||||
cpc.log.AuditErrf("Akamai cache purge failed, retrying: %s", err)
|
||||
cpc.purges.WithLabelValues("retryable failure").Inc()
|
||||
continue
|
||||
}
|
||||
successful = true
|
||||
break
|
||||
}
|
||||
|
||||
if !successful {
|
||||
cpc.purges.WithLabelValues("fatal failure").Inc()
|
||||
return ErrAllRetriesFailed
|
||||
}
|
||||
|
||||
cpc.purges.WithLabelValues("success").Inc()
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckSignature is exported for use in tests and akamai-test-srv.
|
||||
func CheckSignature(secret string, url string, r *http.Request, body []byte) error {
|
||||
bodyHash := sha256.Sum256(body)
|
||||
bodyHashB64 := base64.StdEncoding.EncodeToString(bodyHash[:])
|
||||
|
||||
authorization := r.Header.Get("Authorization")
|
||||
authValues := make(map[string]string)
|
||||
for _, v := range strings.Split(authorization, ";") {
|
||||
splitValue := strings.Split(v, "=")
|
||||
authValues[splitValue[0]] = splitValue[1]
|
||||
}
|
||||
headerTimestamp := authValues["timestamp"]
|
||||
splitHeader := strings.Split(authorization, "signature=")
|
||||
shortenedHeader, signature := splitHeader[0], splitHeader[1]
|
||||
hostPort := strings.Split(url, "://")[1]
|
||||
h := hmac.New(sha256.New, signingKey(secret, headerTimestamp))
|
||||
input := []byte(fmt.Sprintf("POST\thttp\t%s\t%s\t\t%s\t%s",
|
||||
hostPort,
|
||||
r.URL.Path,
|
||||
bodyHashB64,
|
||||
shortenedHeader,
|
||||
))
|
||||
h.Write(input)
|
||||
expectedSignature := base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
if signature != expectedSignature {
|
||||
return fmt.Errorf("expected signature %q, got %q in %q",
|
||||
signature, authorization, expectedSignature)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func reverseBytes(b []byte) []byte {
|
||||
for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
|
||||
b[i], b[j] = b[j], b[i]
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// makeOCSPCacheURLs constructs the 3 URLs associated with each cached OCSP
|
||||
// response.
|
||||
func makeOCSPCacheURLs(req []byte, ocspServer string) []string {
|
||||
hash := md5.Sum(req)
|
||||
encReq := base64.StdEncoding.EncodeToString(req)
|
||||
return []string{
|
||||
// POST Cache Key: the format of this entry is the URL that was POSTed
|
||||
// to with a query string with the parameter 'body-md5' and the value of
|
||||
// the first two uint32s in little endian order in hex of the MD5 hash
|
||||
// of the OCSP request body.
|
||||
//
|
||||
// There is limited public documentation of this feature. However, this
|
||||
// entry is what triggers the Akamai cache behavior that allows Akamai to
|
||||
// identify POST based OCSP for purging. For more information, see:
|
||||
// https://techdocs.akamai.com/property-mgr/reference/v2020-03-04-cachepost
|
||||
// https://techdocs.akamai.com/property-mgr/docs/cache-post-responses
|
||||
fmt.Sprintf("%s?body-md5=%x%x", ocspServer, reverseBytes(hash[0:4]), reverseBytes(hash[4:8])),
|
||||
|
||||
// URL (un-encoded): RFC 2560 and RFC 5019 state OCSP GET URLs 'MUST
|
||||
// properly url-encode the base64 encoded' request but a large enough
|
||||
// portion of tools do not properly do this (~10% of GET requests we
|
||||
// receive) such that we must purge both the encoded and un-encoded
|
||||
// URLs.
|
||||
//
|
||||
// Due to Akamai proxy/cache behavior which collapses '//' -> '/' we also
|
||||
// collapse double slashes in the un-encoded URL so that we properly purge
|
||||
// what is stored in the cache.
|
||||
fmt.Sprintf("%s%s", ocspServer, strings.Replace(encReq, "//", "/", -1)),
|
||||
|
||||
// URL (encoded): this entry is the url-encoded GET URL used to request
|
||||
// OCSP as specified in RFC 2560 and RFC 5019.
|
||||
fmt.Sprintf("%s%s", ocspServer, url.QueryEscape(encReq)),
|
||||
}
|
||||
}
|
||||
|
||||
// GeneratePurgeURLs generates akamai URLs that can be POSTed to in order to
|
||||
// purge akamai's cache of the corresponding OCSP responses. The URLs encode
|
||||
// the contents of the OCSP request, so this method constructs a full OCSP
|
||||
// request.
|
||||
func GeneratePurgeURLs(cert, issuer *x509.Certificate) ([]string, error) {
|
||||
req, err := ocsp.CreateRequest(cert, issuer, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create a GET and special Akamai POST style OCSP url for each endpoint in
|
||||
// cert.OCSPServer.
|
||||
urls := []string{}
|
||||
for _, ocspServer := range cert.OCSPServer {
|
||||
if !strings.HasSuffix(ocspServer, "/") {
|
||||
ocspServer += "/"
|
||||
}
|
||||
urls = append(urls, makeOCSPCacheURLs(req, ocspServer)...)
|
||||
}
|
||||
return urls, nil
|
||||
}
|
||||
|
|
@ -1,275 +0,0 @@
|
|||
package akamai
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/jmhodges/clock"
|
||||
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/metrics"
|
||||
"github.com/letsencrypt/boulder/test"
|
||||
)
|
||||
|
||||
func TestMakeAuthHeader(t *testing.T) {
|
||||
log := blog.NewMock()
|
||||
stats := metrics.NoopRegisterer
|
||||
cpc, err := NewCachePurgeClient(
|
||||
"https://akaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net",
|
||||
"akab-client-token-xxx-xxxxxxxxxxxxxxxx",
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=",
|
||||
"akab-access-token-xxx-xxxxxxxxxxxxxxxx",
|
||||
"production",
|
||||
2,
|
||||
time.Second,
|
||||
log,
|
||||
stats,
|
||||
)
|
||||
test.AssertNotError(t, err, "Failed to create cache purge client")
|
||||
fc := clock.NewFake()
|
||||
cpc.clk = fc
|
||||
wantedTimestamp, err := time.Parse(timestampFormat, "20140321T19:34:21+0000")
|
||||
test.AssertNotError(t, err, "Failed to parse timestamp")
|
||||
fc.Set(wantedTimestamp)
|
||||
|
||||
expectedHeader := "EG1-HMAC-SHA256 client_token=akab-client-token-xxx-xxxxxxxxxxxxxxxx;access_token=akab-access-token-xxx-xxxxxxxxxxxxxxxx;timestamp=20140321T19:34:21+0000;nonce=nonce-xx-xxxx-xxxx-xxxx-xxxxxxxxxxxx;signature=hXm4iCxtpN22m4cbZb4lVLW5rhX8Ca82vCFqXzSTPe4="
|
||||
authHeader := cpc.makeAuthHeader(
|
||||
[]byte("datadatadatadatadatadatadatadata"),
|
||||
"/testapi/v1/t3",
|
||||
"nonce-xx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
)
|
||||
test.AssertEquals(t, authHeader, expectedHeader)
|
||||
}
|
||||
|
||||
type akamaiServer struct {
|
||||
responseCode int
|
||||
*httptest.Server
|
||||
}
|
||||
|
||||
func (as *akamaiServer) sendResponse(w http.ResponseWriter, resp purgeResponse) {
|
||||
respBytes, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to marshal response body: %s\n", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(as.responseCode)
|
||||
w.Write(respBytes)
|
||||
}
|
||||
|
||||
func (as *akamaiServer) purgeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var req struct {
|
||||
Objects []string
|
||||
}
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to read request body: %s\n", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = CheckSignature("secret", as.URL, r, body)
|
||||
if err != nil {
|
||||
fmt.Printf("Error checking signature: %s\n", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, &req)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to unmarshal request body: %s\n", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
resp := purgeResponse{
|
||||
HTTPStatus: as.responseCode,
|
||||
Detail: "?",
|
||||
EstimatedSeconds: 10,
|
||||
PurgeID: "?",
|
||||
}
|
||||
|
||||
fmt.Println(r.URL.Path, v3PurgePath)
|
||||
if strings.HasPrefix(r.URL.Path, v3PurgePath) {
|
||||
for _, testURL := range req.Objects {
|
||||
if !strings.HasPrefix(testURL, "http://") {
|
||||
resp.HTTPStatus = http.StatusForbidden
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
as.sendResponse(w, resp)
|
||||
}
|
||||
func newAkamaiServer(code int) *akamaiServer {
|
||||
m := http.NewServeMux()
|
||||
as := akamaiServer{
|
||||
responseCode: code,
|
||||
Server: httptest.NewServer(m),
|
||||
}
|
||||
m.HandleFunc(v3PurgePath, as.purgeHandler)
|
||||
m.HandleFunc(v3PurgeTagPath, as.purgeHandler)
|
||||
return &as
|
||||
}
|
||||
|
||||
// TestV3Purge tests the Akamai CCU v3 purge API
|
||||
func TestV3Purge(t *testing.T) {
|
||||
as := newAkamaiServer(http.StatusCreated)
|
||||
defer as.Close()
|
||||
|
||||
// Client is a purge client with a "production" v3Network parameter
|
||||
client, err := NewCachePurgeClient(
|
||||
as.URL,
|
||||
"token",
|
||||
"secret",
|
||||
"accessToken",
|
||||
"production",
|
||||
3,
|
||||
time.Second,
|
||||
blog.NewMock(),
|
||||
metrics.NoopRegisterer,
|
||||
)
|
||||
test.AssertNotError(t, err, "Failed to create CachePurgeClient")
|
||||
client.clk = clock.NewFake()
|
||||
|
||||
err = client.Purge([]string{"http://test.com"})
|
||||
test.AssertNotError(t, err, "Purge failed; expected 201 response")
|
||||
|
||||
started := client.clk.Now()
|
||||
as.responseCode = http.StatusInternalServerError
|
||||
err = client.Purge([]string{"http://test.com"})
|
||||
test.AssertError(t, err, "Purge succeeded; expected 500 response")
|
||||
t.Log(client.clk.Since(started))
|
||||
// Given 3 retries, with a retry interval of 1 second, a growth factor of 1.3,
|
||||
// and a jitter of 0.2, the minimum amount of elapsed time is:
|
||||
// (1 * 0.8) + (1 * 1.3 * 0.8) + (1 * 1.3 * 1.3 * 0.8) = 3.192s
|
||||
test.Assert(t, client.clk.Since(started) > (time.Second*3), "Retries should've taken at least 3.192 seconds")
|
||||
|
||||
started = client.clk.Now()
|
||||
as.responseCode = http.StatusCreated
|
||||
err = client.Purge([]string{"http:/test.com"})
|
||||
test.AssertError(t, err, "Purge succeeded; expected a 403 response from malformed URL")
|
||||
test.Assert(t, client.clk.Since(started) < time.Second, "Purge should've failed out immediately")
|
||||
}
|
||||
|
||||
func TestPurgeTags(t *testing.T) {
|
||||
as := newAkamaiServer(http.StatusCreated)
|
||||
defer as.Close()
|
||||
|
||||
// Client is a purge client with a "production" v3Network parameter
|
||||
client, err := NewCachePurgeClient(
|
||||
as.URL,
|
||||
"token",
|
||||
"secret",
|
||||
"accessToken",
|
||||
"production",
|
||||
3,
|
||||
time.Second,
|
||||
blog.NewMock(),
|
||||
metrics.NoopRegisterer,
|
||||
)
|
||||
test.AssertNotError(t, err, "Failed to create CachePurgeClient")
|
||||
fc := clock.NewFake()
|
||||
client.clk = fc
|
||||
|
||||
err = client.PurgeTags([]string{"ff"})
|
||||
test.AssertNotError(t, err, "Purge failed; expected response 201")
|
||||
|
||||
as.responseCode = http.StatusForbidden
|
||||
err = client.PurgeTags([]string{"http://test.com"})
|
||||
test.AssertError(t, err, "Purge succeeded; expected Forbidden response")
|
||||
}
|
||||
|
||||
func TestNewCachePurgeClient(t *testing.T) {
|
||||
// Creating a new cache purge client with an invalid "network" parameter should error
|
||||
_, err := NewCachePurgeClient(
|
||||
"http://127.0.0.1:9000/",
|
||||
"token",
|
||||
"secret",
|
||||
"accessToken",
|
||||
"fake",
|
||||
3,
|
||||
time.Second,
|
||||
blog.NewMock(),
|
||||
metrics.NoopRegisterer,
|
||||
)
|
||||
test.AssertError(t, err, "NewCachePurgeClient with invalid network parameter didn't error")
|
||||
|
||||
// Creating a new cache purge client with a valid "network" parameter shouldn't error
|
||||
_, err = NewCachePurgeClient(
|
||||
"http://127.0.0.1:9000/",
|
||||
"token",
|
||||
"secret",
|
||||
"accessToken",
|
||||
"staging",
|
||||
3,
|
||||
time.Second,
|
||||
blog.NewMock(),
|
||||
metrics.NoopRegisterer,
|
||||
)
|
||||
test.AssertNotError(t, err, "NewCachePurgeClient with valid network parameter errored")
|
||||
|
||||
// Creating a new cache purge client with an invalid server URL parameter should error
|
||||
_, err = NewCachePurgeClient(
|
||||
"h&ttp://whatever",
|
||||
"token",
|
||||
"secret",
|
||||
"accessToken",
|
||||
"staging",
|
||||
3,
|
||||
time.Second,
|
||||
blog.NewMock(),
|
||||
metrics.NoopRegisterer,
|
||||
)
|
||||
test.AssertError(t, err, "NewCachePurgeClient with invalid server url parameter didn't error")
|
||||
}
|
||||
|
||||
func TestBigBatchPurge(t *testing.T) {
|
||||
log := blog.NewMock()
|
||||
|
||||
as := newAkamaiServer(http.StatusCreated)
|
||||
|
||||
client, err := NewCachePurgeClient(
|
||||
as.URL,
|
||||
"token",
|
||||
"secret",
|
||||
"accessToken",
|
||||
"production",
|
||||
3,
|
||||
time.Second,
|
||||
log,
|
||||
metrics.NoopRegisterer,
|
||||
)
|
||||
test.AssertNotError(t, err, "Failed to create CachePurgeClient")
|
||||
|
||||
var urls []string
|
||||
for i := range 250 {
|
||||
urls = append(urls, fmt.Sprintf("http://test.com/%d", i))
|
||||
}
|
||||
|
||||
err = client.Purge(urls)
|
||||
test.AssertNotError(t, err, "Purge failed.")
|
||||
}
|
||||
|
||||
func TestReverseBytes(t *testing.T) {
|
||||
a := []byte{0, 1, 2, 3}
|
||||
test.AssertDeepEquals(t, reverseBytes(a), []byte{3, 2, 1, 0})
|
||||
}
|
||||
|
||||
func TestGenerateOCSPCacheKeys(t *testing.T) {
|
||||
der := []byte{105, 239, 255}
|
||||
test.AssertDeepEquals(
|
||||
t,
|
||||
makeOCSPCacheURLs(der, "ocsp.invalid/"),
|
||||
[]string{
|
||||
"ocsp.invalid/?body-md5=d6101198a9d9f1f6",
|
||||
"ocsp.invalid/ae/",
|
||||
"ocsp.invalid/ae%2F%2F",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.5
|
||||
// protoc v3.20.1
|
||||
// source: akamai.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type PurgeRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Urls []string `protobuf:"bytes,1,rep,name=urls,proto3" json:"urls,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PurgeRequest) Reset() {
|
||||
*x = PurgeRequest{}
|
||||
mi := &file_akamai_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *PurgeRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PurgeRequest) ProtoMessage() {}
|
||||
|
||||
func (x *PurgeRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_akamai_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PurgeRequest.ProtoReflect.Descriptor instead.
|
||||
func (*PurgeRequest) Descriptor() ([]byte, []int) {
|
||||
return file_akamai_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *PurgeRequest) GetUrls() []string {
|
||||
if x != nil {
|
||||
return x.Urls
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_akamai_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_akamai_proto_rawDesc = string([]byte{
|
||||
0x0a, 0x0c, 0x61, 0x6b, 0x61, 0x6d, 0x61, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06,
|
||||
0x61, 0x6b, 0x61, 0x6d, 0x61, 0x69, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x22, 0x22, 0x0a, 0x0c, 0x50, 0x75, 0x72, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x72, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x04, 0x75, 0x72, 0x6c, 0x73, 0x32, 0x47, 0x0a, 0x0c, 0x41, 0x6b, 0x61, 0x6d, 0x61,
|
||||
0x69, 0x50, 0x75, 0x72, 0x67, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x05, 0x50, 0x75, 0x72, 0x67, 0x65,
|
||||
0x12, 0x14, 0x2e, 0x61, 0x6b, 0x61, 0x6d, 0x61, 0x69, 0x2e, 0x50, 0x75, 0x72, 0x67, 0x65, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00,
|
||||
0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c,
|
||||
0x65, 0x74, 0x73, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2f, 0x62, 0x6f, 0x75, 0x6c, 0x64,
|
||||
0x65, 0x72, 0x2f, 0x61, 0x6b, 0x61, 0x6d, 0x61, 0x69, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
})
|
||||
|
||||
var (
|
||||
file_akamai_proto_rawDescOnce sync.Once
|
||||
file_akamai_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_akamai_proto_rawDescGZIP() []byte {
|
||||
file_akamai_proto_rawDescOnce.Do(func() {
|
||||
file_akamai_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_akamai_proto_rawDesc), len(file_akamai_proto_rawDesc)))
|
||||
})
|
||||
return file_akamai_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_akamai_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_akamai_proto_goTypes = []any{
|
||||
(*PurgeRequest)(nil), // 0: akamai.PurgeRequest
|
||||
(*emptypb.Empty)(nil), // 1: google.protobuf.Empty
|
||||
}
|
||||
var file_akamai_proto_depIdxs = []int32{
|
||||
0, // 0: akamai.AkamaiPurger.Purge:input_type -> akamai.PurgeRequest
|
||||
1, // 1: akamai.AkamaiPurger.Purge:output_type -> google.protobuf.Empty
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_akamai_proto_init() }
|
||||
func file_akamai_proto_init() {
|
||||
if File_akamai_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_akamai_proto_rawDesc), len(file_akamai_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_akamai_proto_goTypes,
|
||||
DependencyIndexes: file_akamai_proto_depIdxs,
|
||||
MessageInfos: file_akamai_proto_msgTypes,
|
||||
}.Build()
|
||||
File_akamai_proto = out.File
|
||||
file_akamai_proto_goTypes = nil
|
||||
file_akamai_proto_depIdxs = nil
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package akamai;
|
||||
option go_package = "github.com/letsencrypt/boulder/akamai/proto";
|
||||
|
||||
import "google/protobuf/empty.proto";
|
||||
|
||||
service AkamaiPurger {
|
||||
rpc Purge(PurgeRequest) returns (google.protobuf.Empty) {}
|
||||
}
|
||||
|
||||
message PurgeRequest {
|
||||
repeated string urls = 1;
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v3.20.1
|
||||
// source: akamai.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
AkamaiPurger_Purge_FullMethodName = "/akamai.AkamaiPurger/Purge"
|
||||
)
|
||||
|
||||
// AkamaiPurgerClient is the client API for AkamaiPurger service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type AkamaiPurgerClient interface {
|
||||
Purge(ctx context.Context, in *PurgeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
}
|
||||
|
||||
type akamaiPurgerClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewAkamaiPurgerClient(cc grpc.ClientConnInterface) AkamaiPurgerClient {
|
||||
return &akamaiPurgerClient{cc}
|
||||
}
|
||||
|
||||
func (c *akamaiPurgerClient) Purge(ctx context.Context, in *PurgeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(emptypb.Empty)
|
||||
err := c.cc.Invoke(ctx, AkamaiPurger_Purge_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AkamaiPurgerServer is the server API for AkamaiPurger service.
|
||||
// All implementations must embed UnimplementedAkamaiPurgerServer
|
||||
// for forward compatibility.
|
||||
type AkamaiPurgerServer interface {
|
||||
Purge(context.Context, *PurgeRequest) (*emptypb.Empty, error)
|
||||
mustEmbedUnimplementedAkamaiPurgerServer()
|
||||
}
|
||||
|
||||
// UnimplementedAkamaiPurgerServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedAkamaiPurgerServer struct{}
|
||||
|
||||
func (UnimplementedAkamaiPurgerServer) Purge(context.Context, *PurgeRequest) (*emptypb.Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Purge not implemented")
|
||||
}
|
||||
func (UnimplementedAkamaiPurgerServer) mustEmbedUnimplementedAkamaiPurgerServer() {}
|
||||
func (UnimplementedAkamaiPurgerServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeAkamaiPurgerServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to AkamaiPurgerServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeAkamaiPurgerServer interface {
|
||||
mustEmbedUnimplementedAkamaiPurgerServer()
|
||||
}
|
||||
|
||||
func RegisterAkamaiPurgerServer(s grpc.ServiceRegistrar, srv AkamaiPurgerServer) {
|
||||
// If the following call pancis, it indicates UnimplementedAkamaiPurgerServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&AkamaiPurger_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _AkamaiPurger_Purge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(PurgeRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AkamaiPurgerServer).Purge(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: AkamaiPurger_Purge_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AkamaiPurgerServer).Purge(ctx, req.(*PurgeRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// AkamaiPurger_ServiceDesc is the grpc.ServiceDesc for AkamaiPurger service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var AkamaiPurger_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "akamai.AkamaiPurger",
|
||||
HandlerType: (*AkamaiPurgerServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Purge",
|
||||
Handler: _AkamaiPurger_Purge_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "akamai.proto",
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
package allowlist
|
||||
|
||||
import (
|
||||
"github.com/letsencrypt/boulder/strictyaml"
|
||||
)
|
||||
|
||||
// List holds a unique collection of items of type T. Membership can be checked
|
||||
// by calling the Contains method.
|
||||
type List[T comparable] struct {
|
||||
members map[T]struct{}
|
||||
}
|
||||
|
||||
// NewList returns a *List[T] populated with the provided members of type T. All
|
||||
// duplicate entries are ignored, ensuring uniqueness.
|
||||
func NewList[T comparable](members []T) *List[T] {
|
||||
l := &List[T]{members: make(map[T]struct{})}
|
||||
for _, m := range members {
|
||||
l.members[m] = struct{}{}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// NewFromYAML reads a YAML sequence of values of type T and returns a *List[T]
|
||||
// containing those values. If data is empty, an empty (deny all) list is
|
||||
// returned. If data cannot be parsed, an error is returned.
|
||||
func NewFromYAML[T comparable](data []byte) (*List[T], error) {
|
||||
if len(data) == 0 {
|
||||
return NewList([]T{}), nil
|
||||
}
|
||||
|
||||
var entries []T
|
||||
err := strictyaml.Unmarshal(data, &entries)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewList(entries), nil
|
||||
}
|
||||
|
||||
// Contains reports whether the provided entry is a member of the list.
|
||||
func (l *List[T]) Contains(entry T) bool {
|
||||
_, ok := l.members[entry]
|
||||
return ok
|
||||
}
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
package allowlist
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewFromYAML(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
yamlData string
|
||||
check []string
|
||||
expectAnswers []bool
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid YAML",
|
||||
yamlData: "- oak\n- maple\n- cherry",
|
||||
check: []string{"oak", "walnut", "maple", "cherry"},
|
||||
expectAnswers: []bool{true, false, true, true},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "empty YAML",
|
||||
yamlData: "",
|
||||
check: []string{"oak", "walnut", "maple", "cherry"},
|
||||
expectAnswers: []bool{false, false, false, false},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid YAML",
|
||||
yamlData: "{ invalid_yaml",
|
||||
check: []string{},
|
||||
expectAnswers: []bool{},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
list, err := NewFromYAML[string]([]byte(tt.yamlData))
|
||||
if (err != nil) != tt.expectErr {
|
||||
t.Fatalf("NewFromYAML() error = %v, expectErr = %v", err, tt.expectErr)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
for i, item := range tt.check {
|
||||
got := list.Contains(item)
|
||||
if got != tt.expectAnswers[i] {
|
||||
t.Errorf("Contains(%q) got %v, want %v", item, got, tt.expectAnswers[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewList(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
members []string
|
||||
check []string
|
||||
expectAnswers []bool
|
||||
}{
|
||||
{
|
||||
name: "unique members",
|
||||
members: []string{"oak", "maple", "cherry"},
|
||||
check: []string{"oak", "walnut", "maple", "cherry"},
|
||||
expectAnswers: []bool{true, false, true, true},
|
||||
},
|
||||
{
|
||||
name: "duplicate members",
|
||||
members: []string{"oak", "maple", "cherry", "oak"},
|
||||
check: []string{"oak", "walnut", "maple", "cherry"},
|
||||
expectAnswers: []bool{true, false, true, true},
|
||||
},
|
||||
{
|
||||
name: "nil list",
|
||||
members: nil,
|
||||
check: []string{"oak", "walnut", "maple", "cherry"},
|
||||
expectAnswers: []bool{false, false, false, false},
|
||||
},
|
||||
{
|
||||
name: "empty list",
|
||||
members: []string{},
|
||||
check: []string{"oak", "walnut", "maple", "cherry"},
|
||||
expectAnswers: []bool{false, false, false, false},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
list := NewList[string](tt.members)
|
||||
for i, item := range tt.check {
|
||||
got := list.Contains(item)
|
||||
if got != tt.expectAnswers[i] {
|
||||
t.Errorf("Contains(%q) got %v, want %v", item, got, tt.expectAnswers[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,586 +0,0 @@
|
|||
package bdns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/jmhodges/clock"
|
||||
"github.com/miekg/dns"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/letsencrypt/boulder/iana"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/metrics"
|
||||
)
|
||||
|
||||
// ResolverAddrs contains DNS resolver(s) that were chosen to perform a
|
||||
// validation request or CAA recheck. A ResolverAddr will be in the form of
|
||||
// host:port, A:host:port, or AAAA:host:port depending on which type of lookup
|
||||
// was done.
|
||||
type ResolverAddrs []string
|
||||
|
||||
// Client queries for DNS records
|
||||
type Client interface {
|
||||
LookupTXT(context.Context, string) (txts []string, resolver ResolverAddrs, err error)
|
||||
LookupHost(context.Context, string) ([]netip.Addr, ResolverAddrs, error)
|
||||
LookupCAA(context.Context, string) ([]*dns.CAA, string, ResolverAddrs, error)
|
||||
}
|
||||
|
||||
// impl represents a client that talks to an external resolver
|
||||
type impl struct {
|
||||
dnsClient exchanger
|
||||
servers ServerProvider
|
||||
allowRestrictedAddresses bool
|
||||
maxTries int
|
||||
clk clock.Clock
|
||||
log blog.Logger
|
||||
|
||||
queryTime *prometheus.HistogramVec
|
||||
totalLookupTime *prometheus.HistogramVec
|
||||
timeoutCounter *prometheus.CounterVec
|
||||
idMismatchCounter *prometheus.CounterVec
|
||||
}
|
||||
|
||||
var _ Client = &impl{}
|
||||
|
||||
type exchanger interface {
|
||||
Exchange(m *dns.Msg, a string) (*dns.Msg, time.Duration, error)
|
||||
}
|
||||
|
||||
// New constructs a new DNS resolver object that utilizes the
|
||||
// provided list of DNS servers for resolution.
|
||||
//
|
||||
// `tlsConfig` is the configuration used for outbound DoH queries,
|
||||
// if applicable.
|
||||
func New(
|
||||
readTimeout time.Duration,
|
||||
servers ServerProvider,
|
||||
stats prometheus.Registerer,
|
||||
clk clock.Clock,
|
||||
maxTries int,
|
||||
userAgent string,
|
||||
log blog.Logger,
|
||||
tlsConfig *tls.Config,
|
||||
) Client {
|
||||
var client exchanger
|
||||
|
||||
// Clone the default transport because it comes with various settings
|
||||
// that we like, which are different from the zero value of an
|
||||
// `http.Transport`.
|
||||
transport := http.DefaultTransport.(*http.Transport).Clone()
|
||||
transport.TLSClientConfig = tlsConfig
|
||||
// The default transport already sets this field, but it isn't
|
||||
// documented that it will always be set. Set it again to be sure,
|
||||
// because Unbound will reject non-HTTP/2 DoH requests.
|
||||
transport.ForceAttemptHTTP2 = true
|
||||
client = &dohExchanger{
|
||||
clk: clk,
|
||||
hc: http.Client{
|
||||
Timeout: readTimeout,
|
||||
Transport: transport,
|
||||
},
|
||||
userAgent: userAgent,
|
||||
}
|
||||
|
||||
queryTime := prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "dns_query_time",
|
||||
Help: "Time taken to perform a DNS query",
|
||||
Buckets: metrics.InternetFacingBuckets,
|
||||
},
|
||||
[]string{"qtype", "result", "resolver"},
|
||||
)
|
||||
totalLookupTime := prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "dns_total_lookup_time",
|
||||
Help: "Time taken to perform a DNS lookup, including all retried queries",
|
||||
Buckets: metrics.InternetFacingBuckets,
|
||||
},
|
||||
[]string{"qtype", "result", "retries", "resolver"},
|
||||
)
|
||||
timeoutCounter := prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "dns_timeout",
|
||||
Help: "Counter of various types of DNS query timeouts",
|
||||
},
|
||||
[]string{"qtype", "type", "resolver", "isTLD"},
|
||||
)
|
||||
idMismatchCounter := prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "dns_id_mismatch",
|
||||
Help: "Counter of DNS ErrId errors sliced by query type and resolver",
|
||||
},
|
||||
[]string{"qtype", "resolver"},
|
||||
)
|
||||
stats.MustRegister(queryTime, totalLookupTime, timeoutCounter, idMismatchCounter)
|
||||
return &impl{
|
||||
dnsClient: client,
|
||||
servers: servers,
|
||||
allowRestrictedAddresses: false,
|
||||
maxTries: maxTries,
|
||||
clk: clk,
|
||||
queryTime: queryTime,
|
||||
totalLookupTime: totalLookupTime,
|
||||
timeoutCounter: timeoutCounter,
|
||||
idMismatchCounter: idMismatchCounter,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTest constructs a new DNS resolver object that utilizes the
|
||||
// provided list of DNS servers for resolution and will allow loopback addresses.
|
||||
// This constructor should *only* be called from tests (unit or integration).
|
||||
func NewTest(
|
||||
readTimeout time.Duration,
|
||||
servers ServerProvider,
|
||||
stats prometheus.Registerer,
|
||||
clk clock.Clock,
|
||||
maxTries int,
|
||||
userAgent string,
|
||||
log blog.Logger,
|
||||
tlsConfig *tls.Config,
|
||||
) Client {
|
||||
resolver := New(readTimeout, servers, stats, clk, maxTries, userAgent, log, tlsConfig)
|
||||
resolver.(*impl).allowRestrictedAddresses = true
|
||||
return resolver
|
||||
}
|
||||
|
||||
// exchangeOne performs a single DNS exchange with a randomly chosen server
|
||||
// out of the server list, returning the response, time, and error (if any).
|
||||
// We assume that the upstream resolver requests and validates DNSSEC records
|
||||
// itself.
|
||||
func (dnsClient *impl) exchangeOne(ctx context.Context, hostname string, qtype uint16) (resp *dns.Msg, resolver string, err error) {
|
||||
m := new(dns.Msg)
|
||||
// Set question type
|
||||
m.SetQuestion(dns.Fqdn(hostname), qtype)
|
||||
// Set the AD bit in the query header so that the resolver knows that
|
||||
// we are interested in this bit in the response header. If this isn't
|
||||
// set the AD bit in the response is useless (RFC 6840 Section 5.7).
|
||||
// This has no security implications, it simply allows us to gather
|
||||
// metrics about the percentage of responses that are secured with
|
||||
// DNSSEC.
|
||||
m.AuthenticatedData = true
|
||||
// Tell the resolver that we're willing to receive responses up to 4096 bytes.
|
||||
// This happens sometimes when there are a very large number of CAA records
|
||||
// present.
|
||||
m.SetEdns0(4096, false)
|
||||
|
||||
servers, err := dnsClient.servers.Addrs()
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("failed to list DNS servers: %w", err)
|
||||
}
|
||||
chosenServerIndex := 0
|
||||
chosenServer := servers[chosenServerIndex]
|
||||
resolver = chosenServer
|
||||
|
||||
// Strip off the IP address part of the server address because
|
||||
// we talk to the same server on multiple ports, and don't want
|
||||
// to blow up the cardinality.
|
||||
chosenServerIP, _, err := net.SplitHostPort(chosenServer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
start := dnsClient.clk.Now()
|
||||
client := dnsClient.dnsClient
|
||||
qtypeStr := dns.TypeToString[qtype]
|
||||
tries := 1
|
||||
defer func() {
|
||||
result := "failed"
|
||||
if resp != nil {
|
||||
result = dns.RcodeToString[resp.Rcode]
|
||||
}
|
||||
dnsClient.totalLookupTime.With(prometheus.Labels{
|
||||
"qtype": qtypeStr,
|
||||
"result": result,
|
||||
"retries": strconv.Itoa(tries),
|
||||
"resolver": chosenServerIP,
|
||||
}).Observe(dnsClient.clk.Since(start).Seconds())
|
||||
}()
|
||||
for {
|
||||
ch := make(chan dnsResp, 1)
|
||||
|
||||
// Strip off the IP address part of the server address because
|
||||
// we talk to the same server on multiple ports, and don't want
|
||||
// to blow up the cardinality.
|
||||
// Note: validateServerAddress() has already checked net.SplitHostPort()
|
||||
// and ensures that chosenServer can't be a bare port, e.g. ":1337"
|
||||
chosenServerIP, _, err = net.SplitHostPort(chosenServer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
rsp, rtt, err := client.Exchange(m, chosenServer)
|
||||
result := "failed"
|
||||
if rsp != nil {
|
||||
result = dns.RcodeToString[rsp.Rcode]
|
||||
}
|
||||
if err != nil {
|
||||
logDNSError(dnsClient.log, chosenServer, hostname, m, rsp, err)
|
||||
if err == dns.ErrId {
|
||||
dnsClient.idMismatchCounter.With(prometheus.Labels{
|
||||
"qtype": qtypeStr,
|
||||
"resolver": chosenServerIP,
|
||||
}).Inc()
|
||||
}
|
||||
}
|
||||
dnsClient.queryTime.With(prometheus.Labels{
|
||||
"qtype": qtypeStr,
|
||||
"result": result,
|
||||
"resolver": chosenServerIP,
|
||||
}).Observe(rtt.Seconds())
|
||||
ch <- dnsResp{m: rsp, err: err}
|
||||
}()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
if ctx.Err() == context.DeadlineExceeded {
|
||||
dnsClient.timeoutCounter.With(prometheus.Labels{
|
||||
"qtype": qtypeStr,
|
||||
"type": "deadline exceeded",
|
||||
"resolver": chosenServerIP,
|
||||
"isTLD": isTLD(hostname),
|
||||
}).Inc()
|
||||
} else if ctx.Err() == context.Canceled {
|
||||
dnsClient.timeoutCounter.With(prometheus.Labels{
|
||||
"qtype": qtypeStr,
|
||||
"type": "canceled",
|
||||
"resolver": chosenServerIP,
|
||||
"isTLD": isTLD(hostname),
|
||||
}).Inc()
|
||||
} else {
|
||||
dnsClient.timeoutCounter.With(prometheus.Labels{
|
||||
"qtype": qtypeStr,
|
||||
"type": "unknown",
|
||||
"resolver": chosenServerIP,
|
||||
}).Inc()
|
||||
}
|
||||
err = ctx.Err()
|
||||
return
|
||||
case r := <-ch:
|
||||
if r.err != nil {
|
||||
var isRetryable bool
|
||||
// According to the http package documentation, retryable
|
||||
// errors emitted by the http package are of type *url.Error.
|
||||
var urlErr *url.Error
|
||||
isRetryable = errors.As(r.err, &urlErr) && urlErr.Temporary()
|
||||
hasRetriesLeft := tries < dnsClient.maxTries
|
||||
if isRetryable && hasRetriesLeft {
|
||||
tries++
|
||||
// Chose a new server to retry the query with by incrementing the
|
||||
// chosen server index modulo the number of servers. This ensures that
|
||||
// if one dns server isn't available we retry with the next in the
|
||||
// list.
|
||||
chosenServerIndex = (chosenServerIndex + 1) % len(servers)
|
||||
chosenServer = servers[chosenServerIndex]
|
||||
resolver = chosenServer
|
||||
continue
|
||||
} else if isRetryable && !hasRetriesLeft {
|
||||
dnsClient.timeoutCounter.With(prometheus.Labels{
|
||||
"qtype": qtypeStr,
|
||||
"type": "out of retries",
|
||||
"resolver": chosenServerIP,
|
||||
"isTLD": isTLD(hostname),
|
||||
}).Inc()
|
||||
}
|
||||
}
|
||||
resp, err = r.m, r.err
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// isTLD returns a simplified view of whether something is a TLD: does it have
|
||||
// any dots in it? This returns true or false as a string, and is meant solely
|
||||
// for Prometheus metrics.
|
||||
func isTLD(hostname string) string {
|
||||
if strings.Contains(hostname, ".") {
|
||||
return "false"
|
||||
} else {
|
||||
return "true"
|
||||
}
|
||||
}
|
||||
|
||||
type dnsResp struct {
|
||||
m *dns.Msg
|
||||
err error
|
||||
}
|
||||
|
||||
// LookupTXT sends a DNS query to find all TXT records associated with
|
||||
// the provided hostname which it returns along with the returned
|
||||
// DNS authority section.
|
||||
func (dnsClient *impl) LookupTXT(ctx context.Context, hostname string) ([]string, ResolverAddrs, error) {
|
||||
var txt []string
|
||||
dnsType := dns.TypeTXT
|
||||
r, resolver, err := dnsClient.exchangeOne(ctx, hostname, dnsType)
|
||||
errWrap := wrapErr(dnsType, hostname, r, err)
|
||||
if errWrap != nil {
|
||||
return nil, ResolverAddrs{resolver}, errWrap
|
||||
}
|
||||
|
||||
for _, answer := range r.Answer {
|
||||
if answer.Header().Rrtype == dnsType {
|
||||
if txtRec, ok := answer.(*dns.TXT); ok {
|
||||
txt = append(txt, strings.Join(txtRec.Txt, ""))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return txt, ResolverAddrs{resolver}, err
|
||||
}
|
||||
|
||||
func (dnsClient *impl) lookupIP(ctx context.Context, hostname string, ipType uint16) ([]dns.RR, string, error) {
|
||||
resp, resolver, err := dnsClient.exchangeOne(ctx, hostname, ipType)
|
||||
switch ipType {
|
||||
case dns.TypeA:
|
||||
if resolver != "" {
|
||||
resolver = "A:" + resolver
|
||||
}
|
||||
case dns.TypeAAAA:
|
||||
if resolver != "" {
|
||||
resolver = "AAAA:" + resolver
|
||||
}
|
||||
}
|
||||
errWrap := wrapErr(ipType, hostname, resp, err)
|
||||
if errWrap != nil {
|
||||
return nil, resolver, errWrap
|
||||
}
|
||||
return resp.Answer, resolver, nil
|
||||
}
|
||||
|
||||
// LookupHost sends a DNS query to find all A and AAAA records associated with
|
||||
// the provided hostname. This method assumes that the external resolver will
|
||||
// chase CNAME/DNAME aliases and return relevant records. It will retry
|
||||
// requests in the case of temporary network errors. It returns an error if
|
||||
// both the A and AAAA lookups fail or are empty, but succeeds otherwise.
|
||||
func (dnsClient *impl) LookupHost(ctx context.Context, hostname string) ([]netip.Addr, ResolverAddrs, error) {
|
||||
var recordsA, recordsAAAA []dns.RR
|
||||
var errA, errAAAA error
|
||||
var resolverA, resolverAAAA string
|
||||
var wg sync.WaitGroup
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
recordsA, resolverA, errA = dnsClient.lookupIP(ctx, hostname, dns.TypeA)
|
||||
}()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
recordsAAAA, resolverAAAA, errAAAA = dnsClient.lookupIP(ctx, hostname, dns.TypeAAAA)
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
resolvers := ResolverAddrs{resolverA, resolverAAAA}
|
||||
resolvers = slices.DeleteFunc(resolvers, func(a string) bool {
|
||||
return a == ""
|
||||
})
|
||||
|
||||
var addrsA []netip.Addr
|
||||
if errA == nil {
|
||||
for _, answer := range recordsA {
|
||||
if answer.Header().Rrtype == dns.TypeA {
|
||||
a, ok := answer.(*dns.A)
|
||||
if ok && a.A.To4() != nil {
|
||||
netIP, ok := netip.AddrFromSlice(a.A)
|
||||
if ok && (iana.IsReservedAddr(netIP) == nil || dnsClient.allowRestrictedAddresses) {
|
||||
addrsA = append(addrsA, netIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(addrsA) == 0 {
|
||||
errA = fmt.Errorf("no valid A records found for %s", hostname)
|
||||
}
|
||||
}
|
||||
|
||||
var addrsAAAA []netip.Addr
|
||||
if errAAAA == nil {
|
||||
for _, answer := range recordsAAAA {
|
||||
if answer.Header().Rrtype == dns.TypeAAAA {
|
||||
aaaa, ok := answer.(*dns.AAAA)
|
||||
if ok && aaaa.AAAA.To16() != nil {
|
||||
netIP, ok := netip.AddrFromSlice(aaaa.AAAA)
|
||||
if ok && (iana.IsReservedAddr(netIP) == nil || dnsClient.allowRestrictedAddresses) {
|
||||
addrsAAAA = append(addrsAAAA, netIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(addrsAAAA) == 0 {
|
||||
errAAAA = fmt.Errorf("no valid AAAA records found for %s", hostname)
|
||||
}
|
||||
}
|
||||
|
||||
if errA != nil && errAAAA != nil {
|
||||
// Construct a new error from both underlying errors. We can only use %w for
|
||||
// one of them, because the go error unwrapping protocol doesn't support
|
||||
// branching. We don't use ProblemDetails and SubProblemDetails here, because
|
||||
// this error will get wrapped in a DNSError and further munged by higher
|
||||
// layers in the stack.
|
||||
return nil, resolvers, fmt.Errorf("%w; %s", errA, errAAAA)
|
||||
}
|
||||
|
||||
return append(addrsA, addrsAAAA...), resolvers, nil
|
||||
}
|
||||
|
||||
// LookupCAA sends a DNS query to find all CAA records associated with
|
||||
// the provided hostname and the complete dig-style RR `response`. This
|
||||
// response is quite verbose, however it's only populated when the CAA
|
||||
// response is non-empty.
|
||||
func (dnsClient *impl) LookupCAA(ctx context.Context, hostname string) ([]*dns.CAA, string, ResolverAddrs, error) {
|
||||
dnsType := dns.TypeCAA
|
||||
r, resolver, err := dnsClient.exchangeOne(ctx, hostname, dnsType)
|
||||
|
||||
// Special case: when checking CAA for non-TLD names, treat NXDOMAIN as a
|
||||
// successful response containing an empty set of records. This can come up in
|
||||
// situations where records were provisioned for validation (e.g. TXT records
|
||||
// for DNS-01 challenge) and then removed after validation but before CAA
|
||||
// rechecking. But allow NXDOMAIN for TLDs to fall through to the error code
|
||||
// below, so we don't issue for gTLDs that have been removed by ICANN.
|
||||
if err == nil && r.Rcode == dns.RcodeNameError && strings.Contains(hostname, ".") {
|
||||
return nil, "", ResolverAddrs{resolver}, nil
|
||||
}
|
||||
|
||||
errWrap := wrapErr(dnsType, hostname, r, err)
|
||||
if errWrap != nil {
|
||||
return nil, "", ResolverAddrs{resolver}, errWrap
|
||||
}
|
||||
|
||||
var CAAs []*dns.CAA
|
||||
for _, answer := range r.Answer {
|
||||
if caaR, ok := answer.(*dns.CAA); ok {
|
||||
CAAs = append(CAAs, caaR)
|
||||
}
|
||||
}
|
||||
var response string
|
||||
if len(CAAs) > 0 {
|
||||
response = r.String()
|
||||
}
|
||||
return CAAs, response, ResolverAddrs{resolver}, nil
|
||||
}
|
||||
|
||||
// logDNSError logs the provided err result from making a query for hostname to
|
||||
// the chosenServer. If the err is a `dns.ErrId` instance then the Base64
|
||||
// encoded bytes of the query (and if not-nil, the response) in wire format
|
||||
// is logged as well. This function is called from exchangeOne only for the case
|
||||
// where an error occurs querying a hostname that indicates a problem between
|
||||
// the VA and the chosenServer.
|
||||
func logDNSError(
|
||||
logger blog.Logger,
|
||||
chosenServer string,
|
||||
hostname string,
|
||||
msg, resp *dns.Msg,
|
||||
underlying error) {
|
||||
// We don't expect logDNSError to be called with a nil msg or err but
|
||||
// if it happens return early. We allow resp to be nil.
|
||||
if msg == nil || len(msg.Question) == 0 || underlying == nil {
|
||||
return
|
||||
}
|
||||
queryType := dns.TypeToString[msg.Question[0].Qtype]
|
||||
|
||||
// If the error indicates there was a query/response ID mismatch then we want
|
||||
// to log more detail.
|
||||
if underlying == dns.ErrId {
|
||||
packedMsgBytes, err := msg.Pack()
|
||||
if err != nil {
|
||||
logger.Errf("logDNSError failed to pack msg: %v", err)
|
||||
return
|
||||
}
|
||||
encodedMsg := base64.StdEncoding.EncodeToString(packedMsgBytes)
|
||||
|
||||
var encodedResp string
|
||||
var respQname string
|
||||
if resp != nil {
|
||||
packedRespBytes, err := resp.Pack()
|
||||
if err != nil {
|
||||
logger.Errf("logDNSError failed to pack resp: %v", err)
|
||||
return
|
||||
}
|
||||
encodedResp = base64.StdEncoding.EncodeToString(packedRespBytes)
|
||||
if len(resp.Answer) > 0 && resp.Answer[0].Header() != nil {
|
||||
respQname = resp.Answer[0].Header().Name
|
||||
}
|
||||
}
|
||||
|
||||
logger.Infof(
|
||||
"logDNSError ID mismatch chosenServer=[%s] hostname=[%s] respHostname=[%s] queryType=[%s] msg=[%s] resp=[%s] err=[%s]",
|
||||
chosenServer,
|
||||
hostname,
|
||||
respQname,
|
||||
queryType,
|
||||
encodedMsg,
|
||||
encodedResp,
|
||||
underlying)
|
||||
} else {
|
||||
// Otherwise log a general DNS error
|
||||
logger.Infof("logDNSError chosenServer=[%s] hostname=[%s] queryType=[%s] err=[%s]",
|
||||
chosenServer,
|
||||
hostname,
|
||||
queryType,
|
||||
underlying)
|
||||
}
|
||||
}
|
||||
|
||||
type dohExchanger struct {
|
||||
clk clock.Clock
|
||||
hc http.Client
|
||||
userAgent string
|
||||
}
|
||||
|
||||
// Exchange sends a DoH query to the provided DoH server and returns the response.
|
||||
func (d *dohExchanger) Exchange(query *dns.Msg, server string) (*dns.Msg, time.Duration, error) {
|
||||
q, err := query.Pack()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// The default Unbound URL template
|
||||
url := fmt.Sprintf("https://%s/dns-query", server)
|
||||
req, err := http.NewRequest("POST", url, strings.NewReader(string(q)))
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/dns-message")
|
||||
req.Header.Set("Accept", "application/dns-message")
|
||||
if len(d.userAgent) > 0 {
|
||||
req.Header.Set("User-Agent", d.userAgent)
|
||||
}
|
||||
|
||||
start := d.clk.Now()
|
||||
resp, err := d.hc.Do(req)
|
||||
if err != nil {
|
||||
return nil, d.clk.Since(start), err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, d.clk.Since(start), fmt.Errorf("doh: http status %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
b, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, d.clk.Since(start), fmt.Errorf("doh: reading response body: %w", err)
|
||||
}
|
||||
|
||||
response := new(dns.Msg)
|
||||
err = response.Unpack(b)
|
||||
if err != nil {
|
||||
return nil, d.clk.Since(start), fmt.Errorf("doh: unpacking response: %w", err)
|
||||
}
|
||||
|
||||
return response, d.clk.Since(start), nil
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue