Merge branch 'trunk' into kw/first-pass-accessible-prompter
This commit is contained in:
commit
861563269a
60 changed files with 968 additions and 489 deletions
10
.github/workflows/deployment.yml
vendored
10
.github/workflows/deployment.yml
vendored
|
|
@ -50,7 +50,7 @@ jobs:
|
|||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- name: Install GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552
|
||||
with:
|
||||
version: "~1.17.1"
|
||||
install-only: true
|
||||
|
|
@ -103,7 +103,7 @@ jobs:
|
|||
security set-key-partition-list -S "apple-tool:,apple:,codesign:" -s -k "$keychain_password" "$keychain"
|
||||
rm "$RUNNER_TEMP/cert.p12"
|
||||
- name: Install GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552
|
||||
with:
|
||||
version: "~1.17.1"
|
||||
install-only: true
|
||||
|
|
@ -157,7 +157,7 @@ jobs:
|
|||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- name: Install GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552
|
||||
with:
|
||||
version: "~1.17.1"
|
||||
install-only: true
|
||||
|
|
@ -196,7 +196,7 @@ jobs:
|
|||
run: script/release --local "$TAG_NAME" --platform windows
|
||||
- name: Set up MSBuild
|
||||
id: setupmsbuild
|
||||
uses: microsoft/setup-msbuild@v2.0.0
|
||||
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce
|
||||
- name: Build MSI
|
||||
shell: bash
|
||||
env:
|
||||
|
|
@ -384,7 +384,7 @@ jobs:
|
|||
git diff --name-status @{upstream}..
|
||||
fi
|
||||
- name: Bump homebrew-core formula
|
||||
uses: mislav/bump-homebrew-formula-action@v3
|
||||
uses: mislav/bump-homebrew-formula-action@942e550c6344cfdb9e1ab29b9bb9bf0c43efa19b
|
||||
if: inputs.environment == 'production' && !contains(inputs.tag_name, '-')
|
||||
with:
|
||||
formula-name: gh
|
||||
|
|
|
|||
2
.github/workflows/homebrew-bump.yml
vendored
2
.github/workflows/homebrew-bump.yml
vendored
|
|
@ -17,7 +17,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Bump homebrew-core formula
|
||||
uses: mislav/bump-homebrew-formula-action@v3
|
||||
uses: mislav/bump-homebrew-formula-action@942e550c6344cfdb9e1ab29b9bb9bf0c43efa19b
|
||||
if: inputs.environment == 'production' && !contains(inputs.tag_name, '-')
|
||||
with:
|
||||
formula-name: gh
|
||||
|
|
|
|||
43
acceptance/testdata/issue/issue-create-edit-with-project.txtar
vendored
Normal file
43
acceptance/testdata/issue/issue-create-edit-with-project.txtar
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
env REPO=${SCRIPT_NAME}-${RANDOM_STRING}
|
||||
|
||||
# Create a repository with a file so it has a default branch
|
||||
exec gh repo create ${ORG}/${REPO} --add-readme --private
|
||||
|
||||
# Defer repo cleanup
|
||||
defer gh repo delete --yes ${ORG}/${REPO}
|
||||
|
||||
# Create a project
|
||||
env PROJECT_TITLE=${REPO}-project
|
||||
exec gh project create --owner=${ORG} --title=${PROJECT_TITLE} --format='json' --jq='.number'
|
||||
stdout2env PROJECT_NUMBER
|
||||
|
||||
defer gh project delete --owner=${ORG} ${PROJECT_NUMBER}
|
||||
|
||||
# Clone the repo
|
||||
exec gh repo clone ${ORG}/${REPO}
|
||||
|
||||
# Create an issue in the repo
|
||||
cd ${REPO}
|
||||
exec gh issue create --title 'Feature Request' --body 'Feature Body' --project ${PROJECT_TITLE}
|
||||
stdout2env ISSUE_URL
|
||||
|
||||
# Check that default issue view is working
|
||||
exec gh issue view ${ISSUE_URL}
|
||||
|
||||
# Check the issue was added to the project
|
||||
exec gh issue view ${ISSUE_URL} --json projectItems --jq '.projectItems[0].title'
|
||||
stdout ${PROJECT_TITLE}
|
||||
|
||||
# Remove the issue from the project
|
||||
exec gh issue edit ${ISSUE_URL} --remove-project ${PROJECT_TITLE}
|
||||
|
||||
# Check the issue was removed from the project
|
||||
exec gh issue view ${ISSUE_URL} --json projectItems --jq '.projectItems[0].title'
|
||||
! stdout ${PROJECT_TITLE}
|
||||
|
||||
# Re add the issue to the project
|
||||
exec gh issue edit ${ISSUE_URL} --add-project ${PROJECT_TITLE}
|
||||
|
||||
# Check the issue was added to the project
|
||||
exec gh issue view ${ISSUE_URL} --json projectItems --jq '.projectItems[0].title'
|
||||
stdout ${PROJECT_TITLE}
|
||||
51
acceptance/testdata/pr/pr-create-edit-with-project.txtar
vendored
Normal file
51
acceptance/testdata/pr/pr-create-edit-with-project.txtar
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# Use gh as a credential helper
|
||||
exec gh auth setup-git
|
||||
|
||||
env REPO=${SCRIPT_NAME}-${RANDOM_STRING}
|
||||
|
||||
# Create a repository with a file so it has a default branch
|
||||
exec gh repo create ${ORG}/${REPO} --add-readme --private
|
||||
|
||||
# Defer repo cleanup
|
||||
defer gh repo delete --yes ${ORG}/${REPO}
|
||||
|
||||
# Create a project
|
||||
env PROJECT_TITLE=${REPO}-project
|
||||
exec gh project create --owner=${ORG} --title=${PROJECT_TITLE} --format='json' --jq='.number'
|
||||
stdout2env PROJECT_NUMBER
|
||||
|
||||
defer gh project delete --owner=${ORG} ${PROJECT_NUMBER}
|
||||
|
||||
# Clone the repo
|
||||
exec gh repo clone ${ORG}/${REPO}
|
||||
|
||||
# Prepare a branch to PR
|
||||
cd ${REPO}
|
||||
exec git checkout -b feature-branch
|
||||
exec git commit --allow-empty -m 'Empty Commit'
|
||||
exec git push -u origin feature-branch
|
||||
|
||||
# Create the PR
|
||||
exec gh pr create --title 'Feature Title' --body 'Feature Body' --project ${PROJECT_TITLE}
|
||||
stdout2env PR_URL
|
||||
|
||||
# Check that default pr view is working
|
||||
exec gh pr view ${PR_URL}
|
||||
|
||||
# Check the pr was added to the project
|
||||
exec gh pr view ${PR_URL} --json projectItems --jq '.projectItems[0].title'
|
||||
stdout ${PROJECT_TITLE}
|
||||
|
||||
# Remove the pr from the project
|
||||
exec gh pr edit ${PR_URL} --remove-project ${PROJECT_TITLE}
|
||||
|
||||
# Check the pr was removed from the project
|
||||
exec gh pr view ${PR_URL} --json projectItems --jq '.projectItems[0].title'
|
||||
! stdout ${PROJECT_TITLE}
|
||||
|
||||
# Re add the pr to the project
|
||||
exec gh pr edit ${PR_URL} --add-project ${PROJECT_TITLE}
|
||||
|
||||
# Check the pr was added to the project
|
||||
exec gh pr view ${PR_URL} --json projectItems --jq '.projectItems[0].title'
|
||||
stdout ${PROJECT_TITLE}
|
||||
64
go.mod
64
go.mod
|
|
@ -24,7 +24,7 @@ require (
|
|||
github.com/gabriel-vasile/mimetype v1.4.8
|
||||
github.com/gdamore/tcell/v2 v2.5.4
|
||||
github.com/golang/snappy v0.0.4
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/google/go-containerregistry v0.20.3
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
|
|
@ -43,18 +43,18 @@ require (
|
|||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/rivo/tview v0.0.0-20221029100920-c4a7e501810d
|
||||
github.com/shurcooL/githubv4 v0.0.0-20240120211514-18a1ae0e79dc
|
||||
github.com/sigstore/protobuf-specs v0.3.3
|
||||
github.com/sigstore/sigstore-go v0.7.0
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/sigstore/protobuf-specs v0.4.1
|
||||
github.com/sigstore/sigstore-go v0.7.1
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/pflag v1.0.6
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/zalando/go-keyring v0.2.5
|
||||
golang.org/x/crypto v0.35.0
|
||||
golang.org/x/sync v0.12.0
|
||||
golang.org/x/term v0.30.0
|
||||
golang.org/x/text v0.23.0
|
||||
google.golang.org/grpc v1.69.4
|
||||
google.golang.org/protobuf v1.36.5
|
||||
golang.org/x/crypto v0.37.0
|
||||
golang.org/x/sync v0.13.0
|
||||
golang.org/x/term v0.31.0
|
||||
golang.org/x/text v0.24.0
|
||||
google.golang.org/grpc v1.71.0
|
||||
google.golang.org/protobuf v1.36.6
|
||||
gopkg.in/h2non/gock.v1 v1.1.2
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
|
@ -93,29 +93,29 @@ require (
|
|||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||
github.com/gdamore/encoding v1.0.0 // indirect
|
||||
github.com/go-chi/chi v4.1.2+incompatible // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // 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.0 // indirect
|
||||
github.com/go-openapi/errors v0.22.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // 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.23.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.1 // indirect
|
||||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/google/certificate-transparency-go v1.3.1 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/css v1.0.1 // indirect
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/in-toto/in-toto-golang v0.9.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
|
|
@ -127,8 +127,6 @@ require (
|
|||
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
|
|
@ -143,27 +141,26 @@ 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.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/pkg/errors v0.9.1 // 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.0.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.7.0 // indirect
|
||||
github.com/sassoftware/relic v7.2.1+incompatible // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.9.0 // 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.3.8 // indirect
|
||||
github.com/sigstore/sigstore v1.8.12 // indirect
|
||||
github.com/sigstore/timestamp-authority v1.2.4 // indirect
|
||||
github.com/sigstore/rekor v1.3.9 // indirect
|
||||
github.com/sigstore/sigstore v1.9.1 // indirect
|
||||
github.com/sigstore/timestamp-authority v1.2.5 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
github.com/spf13/viper v1.19.0 // indirect
|
||||
github.com/spf13/afero v1.12.0 // indirect
|
||||
github.com/spf13/cast v1.7.1 // indirect
|
||||
github.com/spf13/viper v1.20.1 // 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
|
||||
|
|
@ -177,18 +174,17 @@ require (
|
|||
github.com/yuin/goldmark-emoji v1.0.5 // indirect
|
||||
go.mongodb.org/mongo-driver v1.14.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/net v0.36.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/tools v0.29.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
)
|
||||
|
|
|
|||
326
go.sum
326
go.sum
|
|
@ -1,18 +1,17 @@
|
|||
cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE=
|
||||
cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U=
|
||||
cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs=
|
||||
cloud.google.com/go/auth v0.13.0/go.mod h1:COOjD9gwfKNKz+IIduatIhYJQIc0mG3H102r/EMxX6Q=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyTuciBG5hFkU=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8=
|
||||
cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg=
|
||||
cloud.google.com/go v0.118.3 h1:jsypSnrE/w4mJysioGdMBg4MiW/hHx/sArFpaBWHdME=
|
||||
cloud.google.com/go v0.118.3/go.mod h1:Lhs3YLnBlwJ4KA6nuObNMZ/fCbOQBPuWKPoE0Wa/9Vc=
|
||||
cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps=
|
||||
cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc=
|
||||
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
|
||||
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
|
||||
cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA=
|
||||
cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY=
|
||||
cloud.google.com/go/kms v1.20.4 h1:CJ0hMpOg1ANN9tx/a/GPJ+Uxudy8k6f3fvGFuTHiE5A=
|
||||
cloud.google.com/go/kms v1.20.4/go.mod h1:gPLsp1r4FblUgBYPOcvI/bUPpdMg2Jm1ZVKU4tQUfcc=
|
||||
cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc=
|
||||
cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI=
|
||||
cloud.google.com/go/iam v1.4.1 h1:cFC25Nv+u5BkTR/BT1tXdoF2daiVbZ1RLx2eqfQ9RMM=
|
||||
cloud.google.com/go/iam v1.4.1/go.mod h1:2vUEJpUG3Q9p2UdsyksaKpDzlwOrnMzS30isdReIcLM=
|
||||
cloud.google.com/go/kms v1.21.1 h1:r1Auo+jlfJSf8B7mUnVw5K0fI7jWyoUy65bV53VjKyk=
|
||||
cloud.google.com/go/kms v1.21.1/go.mod h1:s0wCyByc9LjTdCjG88toVs70U9W+cc6RKFc8zAqX7nE=
|
||||
cloud.google.com/go/longrunning v0.6.5 h1:sD+t8DO8j4HKW4QfouCklg7ZC1qC4uzVZt8iz3uTW+Q=
|
||||
cloud.google.com/go/longrunning v0.6.5/go.mod h1:Et04XK+0TTLKa5IPYryKf5DkpwImy6TluQ1QTLwlKmY=
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
|
|
@ -21,18 +20,18 @@ github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230919221257-8b5d3ce2d11d h1:zjq
|
|||
github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230919221257-8b5d3ce2d11d/go.mod h1:XNqJ7hv2kY++g8XEHREpi+JqZo3+0l+CH2egBVN4yqM=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.1 h1:DSDNVxqkoXJiko6x8a90zidoYqnYYa6c1MTzDKzKkTo=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.1/go.mod h1:zGqV2R4Cr/k8Uye5w+dgQ06WJtEcbQG/8J7BB6hnCr4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 h1:F0gBpfdPLGsw+nsgk6aqqkZS1jiixa5WwFe3fk/T3Ys=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2/go.mod h1:SqINnQ9lVVdRlyC8cd1lCI0SdX4n2paeABd2K8ggfnE=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.0 h1:7rKG7UmnrxX4N53TFhkYqjc+kVUZuw0fL8I3Fh+Ld9E=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.0/go.mod h1:Wjo+24QJVhhl/L7jy6w9yzFF2yDOf3cKECAa8ecf9vE=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.0 h1:eXnN9kaS8TiDwXjoie3hMRLuwdUBUMW9KRgOqB3mCaw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.0/go.mod h1:XIpam8wumeZ5rVMuhdDQLMfIPDf1WO3IzrCRO3e3e3o=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.1 h1:gUDtaZk8heteyfdmv+pcfHvhR9llnh7c7GMwZ8RVG04=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 h1:Wgf5rZba3YZqeTNJPtvqZoBu1sBN/L4sry+u2U3Y75w=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1/go.mod h1:xxCBG/f/4Vbmh2XQJBsOmNdxWUY5j/s27jujKPbQf14=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1/go.mod h1:Vih/3yc6yac2JzU4hzpaDupBJP0Flaia9rXXrU8xyww=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 h1:H5xDQaE3XowWfhZRUpnfC+rGZMEVoSiji+b+/HFAPU4=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
|
||||
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
|
|
@ -55,36 +54,36 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d
|
|||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
|
||||
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.8 h1:cZV+NUS/eGxKXMtmyhtYPJ7Z4YLoI/V8bkTdRZfYhGo=
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.8/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.28.10 h1:fKODZHfqQu06pCzR69KJ3GuttraRJkhlC8g80RZ0Dfg=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.28.10/go.mod h1:PvdxRYZ5Um9QMq9PQ0zHHNdtKK+he2NHtFCUFMXWXeg=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.51 h1:F/9Sm6Y6k4LqDesZDPJCLxQGXNNHd/ZtJiWd0lCZKRk=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.51/go.mod h1:TKbzCHm43AoPyA+iLGGcruXd4AFhF8tOmLex2R9jWNQ=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.23 h1:IBAoD/1d8A8/1aA8g4MBVtTRHhXRiNAgwdbo/xRM2DI=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.23/go.mod h1:vfENuCM7dofkgKpYzuzf1VT1UKkA/YL3qanfBn7HCaA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27 h1:jSJjSBzw8VDIbWv+mmvBSP8ezsztMYJGH+eKqi9AmNs=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27/go.mod h1:/DAhLbFRgwhmvJdOfSm+WwikZrCuUJiA4WgJG0fTNSw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27 h1:l+X4K77Dui85pIj5foXDhPlnqcNRG2QUyvca300lXh8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27/go.mod h1:KvZXSFEXm6x84yE8qffKvT3x8J5clWnVFXphpohhzJ8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8 h1:cWno7lefSH6Pp+mSznagKCgfDGeZRin66UvYUqAkyeA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8/go.mod h1:tPD+VjU3ABTBoEJ3nctu5Nyg4P4yjqSH5bJGGkY4+XE=
|
||||
github.com/aws/aws-sdk-go-v2/service/kms v1.37.8 h1:KbLZjYqhQ9hyB4HwXiheiflTlYQa0+Fz0Ms/rh5f3mk=
|
||||
github.com/aws/aws-sdk-go-v2/service/kms v1.37.8/go.mod h1:ANs9kBhK4Ghj9z1W+bsr3WsNaPF71qkgd6eE6Ekol/Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.9 h1:YqtxripbjWb2QLyzRK9pByfEDvgg95gpC2AyDq4hFE8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.9/go.mod h1:lV8iQpg6OLOfBnqbGMBKYjilBlf633qwHnBEiMSPoHY=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8 h1:6dBT1Lz8fK11m22R+AqfRsFn8320K0T5DTGxxOQBSMw=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8/go.mod h1:/kiBvRQXBc6xeJTYzhSdGvJ5vm1tjaDEjH+MSeRJnlY=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.6 h1:VwhTrsTuVn52an4mXx29PqRzs2Dvu921NpGk7y43tAM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.6/go.mod h1:+8h7PZb3yY5ftmVLD7ocEoE98hdc8PoKS0H3wfx1dlc=
|
||||
github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro=
|
||||
github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
|
||||
github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk=
|
||||
github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.10 h1:yNjgjiGBp4GgaJrGythyBXg2wAs+Im9fSWIUwvi1CAc=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.10/go.mod h1:A0mbLXSdtob/2t59n1X0iMkPQ5d+YzYZB4rwu7SZ7aA=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.63 h1:rv1V3kIJ14pdmTu01hwcMJ0WAERensSiD9rEWEBb1Tk=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.63/go.mod h1:EJj+yDf0txT26Ulo0VWTavBl31hOsaeuMxIHu2m0suY=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=
|
||||
github.com/aws/aws-sdk-go-v2/service/kms v1.38.1 h1:tecq7+mAav5byF+Mr+iONJnCBf4B4gon8RSp4BrweSc=
|
||||
github.com/aws/aws-sdk-go-v2/service/kms v1.38.1/go.mod h1:cQn6tAF77Di6m4huxovNM7NVAozWTZLsDRp9t8Z/WYk=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.1 h1:8JdC7Gr9NROg1Rusk25IcZeTO59zLxsKgE0gkh5O6h0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.1/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.2 h1:wK8O+j2dOolmpNVY1EWIbLgxrGCHJKVPm08Hv/u80M8=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.2/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 h1:PZV5W8yk4OtH1JAuhV2PXwwO9v5G5Aoj+eMCn4T+1Kc=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.17/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=
|
||||
github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
|
||||
github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
|
||||
|
|
@ -143,7 +142,6 @@ github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUo
|
|||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
|
|
@ -183,8 +181,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2
|
|||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
||||
|
|
@ -193,8 +191,6 @@ github.com/gdamore/tcell/v2 v2.5.4 h1:TGU4tSjD3sCL788vFNeJnTdzpNKIw1H5dgLnJRQVv/
|
|||
github.com/gdamore/tcell/v2 v2.5.4/go.mod h1:dZgRy5v4iMobMEcWNYBtREnDZAT9DYmfqIkrgEMxLyw=
|
||||
github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec=
|
||||
github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
|
|
@ -204,8 +200,8 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
|||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
|
||||
github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
|
||||
github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w=
|
||||
github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE=
|
||||
github.com/go-openapi/errors v0.22.1 h1:kslMRRnK7NCb/CvR1q1VWuEQCEIsBGn5GgKD9e+HYhU=
|
||||
github.com/go-openapi/errors v0.22.1/go.mod h1:+n/5UdIqdVnLIJ6Q9Se8HNGUXYaY6CN8ImWzfi/Gzp0=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
|
||||
|
|
@ -218,32 +214,34 @@ github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9Z
|
|||
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||
github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=
|
||||
github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
|
||||
github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
|
||||
github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
|
||||
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
|
||||
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/certificate-transparency-go v1.3.1 h1:akbcTfQg0iZlANZLn0L9xOeWtyCIdeoYhKrqi5iH3Go=
|
||||
github.com/google/certificate-transparency-go v1.3.1/go.mod h1:gg+UQlx6caKEDQ9EElFOujyxEQEfOiQzAt6782Bvi8k=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/go-containerregistry v0.20.3 h1:oNx7IdTI936V8CQRveCjaxOiegWwvM7kqkbXTpyiovI=
|
||||
github.com/google/go-containerregistry v0.20.3/go.mod h1:w00pIgBRDVUDFM6bq+Qx8lwNWK+cxgCuX1vd3PIBDNI=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
|
||||
github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=
|
||||
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/tink/go v1.7.0 h1:6Eox8zONGebBFcCBqkVmt60LaWZa6xg1cl/DwAh/J1w=
|
||||
|
|
@ -252,8 +250,8 @@ github.com/google/trillian v1.7.1 h1:+zX8jLM3524bAMPS+VxaDIDgsMv3/ty6DuLWerHXcek
|
|||
github.com/google/trillian v1.7.1/go.mod h1:E1UMAHqpZCA8AQdrKdWmHmtUfSeiD0sDWD1cv00Xa+c=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
|
||||
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
|
||||
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
||||
|
|
@ -281,13 +279,12 @@ github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0S
|
|||
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
|
||||
github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
|
||||
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/vault/api v1.15.0 h1:O24FYQCWwhwKnF7CuSqP30S51rTV7vz1iACXE/pj5DA=
|
||||
github.com/hashicorp/vault/api v1.15.0/go.mod h1:+5YTO09JGn0u+b6ySD/LLVf8WkJCPLAL2Vkmrn2+CM8=
|
||||
github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4=
|
||||
github.com/hashicorp/vault/api v1.16.0/go.mod h1:KhuUhzOD8lDSk29AtzNjgAu2kxRA9jL9NAbkFlqvkBA=
|
||||
github.com/henvic/httpretty v0.1.4 h1:Jo7uwIRWVFxkqOnErcoYfH90o3ddQyVrSANeS4cxYmU=
|
||||
github.com/henvic/httpretty v0.1.4/go.mod h1:Dn60sQTZfbt2dYsdUSNsCljyF4AfdqnuJFDLJA1I4AM=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
|
|
@ -346,10 +343,8 @@ github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2T
|
|||
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
|
|
@ -402,8 +397,8 @@ github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQ
|
|||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
|
|
@ -411,12 +406,12 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
|
||||
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/rivo/tview v0.0.0-20221029100920-c4a7e501810d h1:jKIUJdMcIVGOSHi6LSqJqw9RqblyblE2ZrHvFbWR3S0=
|
||||
|
|
@ -433,10 +428,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
|
|||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
|
||||
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||
github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
|
||||
github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
|
||||
github.com/sassoftware/relic v7.2.1+incompatible h1:Pwyh1F3I0r4clFJXkSI8bOyJINGqpgjJU3DYAZeI05A=
|
||||
github.com/sassoftware/relic v7.2.1+incompatible/go.mod h1:CWfAxv73/iLZ17rbyhIEq3K9hs5w6FpNMdUT//qR+zk=
|
||||
github.com/sassoftware/relic/v7 v7.6.2 h1:rS44Lbv9G9eXsukknS4mSjIAuuX+lMq/FnStgmZlUv4=
|
||||
|
|
@ -453,51 +446,44 @@ github.com/shurcooL/githubv4 v0.0.0-20240120211514-18a1ae0e79dc h1:vH0NQbIDk+mJL
|
|||
github.com/shurcooL/githubv4 v0.0.0-20240120211514-18a1ae0e79dc/go.mod h1:zqMwyHmnN/eDOZOdiTohqIUKUrTFX62PNlu7IJdu0q8=
|
||||
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 h1:17JxqqJY66GmZVHkmAsGEkcIu0oCe3AM420QDgGwZx0=
|
||||
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466/go.mod h1:9dIRpgIY7hVhoqfe0/FcYp0bpInZaT7dc3BYOprrIUE=
|
||||
github.com/sigstore/protobuf-specs v0.3.3 h1:RMZQgXTD/pF7KW6b5NaRLYxFYZ/wzx44PQFXN2PEo5g=
|
||||
github.com/sigstore/protobuf-specs v0.3.3/go.mod h1:vIhZ6Uor1a38+wvRrKcqL2PtYNlgoIW9lhzYzkyy4EU=
|
||||
github.com/sigstore/rekor v1.3.8 h1:B8kJI8mpSIXova4Jxa6vXdJyysRxFGsEsLKBDl0rRjA=
|
||||
github.com/sigstore/rekor v1.3.8/go.mod h1:/dHFYKSuxEygfDRnEwyJ+ZD6qoVYNXQdi1mJrKvKWsI=
|
||||
github.com/sigstore/sigstore v1.8.12 h1:S8xMVZbE2z9ZBuQUEG737pxdLjnbOIcFi5v9UFfkJFc=
|
||||
github.com/sigstore/sigstore v1.8.12/go.mod h1:+PYQAa8rfw0QdPpBcT+Gl3egKD9c+TUgAlF12H3Nmjo=
|
||||
github.com/sigstore/sigstore-go v0.7.0 h1:bIGPc2IbnbxnzlqQcKlh1o96bxVJ4yRElpP1gHrOH48=
|
||||
github.com/sigstore/sigstore-go v0.7.0/go.mod h1:4RrCK+i+jhx7lyOG2Vgef0/kFLbKlDI1hrioUYvkxxA=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.12 h1:EC3UmIaa7nV9sCgSpVevmvgvTYTkMqyrRbj5ojPp7tE=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.12/go.mod h1:aw60vs3crnQdM/DYH+yF2P0MVKtItwAX34nuaMrY7Lk=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.12 h1:FPpliDTywSy0woLHMAdmTSZ5IS/lVBZ0dY0I+2HmnSY=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.12/go.mod h1:NkPiz4XA0JcBSXzJUrjMj7Xi7oSTew1Ip3Zmt56mHlw=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.12 h1:kweBChR6M9FEvmxN3BMEcl7SNnwxTwKF7THYFKLOE5U=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.12/go.mod h1:6+d+A6oYt1W5OgtzgEVb21V7tAZ/C2Ihtzc5MNJbayY=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.12 h1:jvY1B9bjP+tKzdKDyuq5K7O19CG2IKzGJNTy5tuL2Gs=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.12/go.mod h1:2uEeOb8xE2RC6OvzxKux1wkS39Zv8gA27z92m49xUTc=
|
||||
github.com/sigstore/timestamp-authority v1.2.4 h1:RjXZxOWorEiem/uSr0pFHVtQpyzpcFxgugo5jVqm3mw=
|
||||
github.com/sigstore/timestamp-authority v1.2.4/go.mod h1:ExrbobKdEuwuBptZIiKp1IaVBRiUeKbiuSyZTO8Okik=
|
||||
github.com/sigstore/protobuf-specs v0.4.1 h1:5SsMqZbdkcO/DNHudaxuCUEjj6x29tS2Xby1BxGU7Zc=
|
||||
github.com/sigstore/protobuf-specs v0.4.1/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc=
|
||||
github.com/sigstore/rekor v1.3.9 h1:sUjRpKVh/hhgqGMs0t+TubgYsksArZ6poLEC3MsGAzU=
|
||||
github.com/sigstore/rekor v1.3.9/go.mod h1:xThNUhm6eNEmkJ/SiU/FVU7pLY2f380fSDZFsdDWlcM=
|
||||
github.com/sigstore/sigstore v1.9.1 h1:bNMsfFATsMPaagcf+uppLk4C9rQZ2dh5ysmCxQBYWaw=
|
||||
github.com/sigstore/sigstore v1.9.1/go.mod h1:zUoATYzR1J3rLNp3jmp4fzIJtWdhC3ZM6MnpcBtnsE4=
|
||||
github.com/sigstore/sigstore-go v0.7.1 h1:lyzi3AjO6+BHc5zCf9fniycqPYOt3RaC08M/FRmQhVY=
|
||||
github.com/sigstore/sigstore-go v0.7.1/go.mod h1:AIRj4I3LC82qd07VFm3T2zXYiddxeBV1k/eoS8nTz0E=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.9.1 h1:/YcNq687WnXpIRXl04nLfJX741G4iW+w+7Nem2Zy0f4=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.9.1/go.mod h1:ApL9RpKsi7gkSYN0bMNdm/3jZ9EefxMmfYHfUmq2ZYM=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.9.1 h1:FnusXyTIInnwfIOzzl5PFilRm1I97dxMSOcCkZBu9Kc=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.9.1/go.mod h1:d5m5LOa/69a+t2YC9pDPwS1n2i/PhqB4cUKbpVDlKKE=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.9.1 h1:LFiYK1DEWQ6Hf/nroFzBMM+s5rVSjVL45Alpb5Ctl5A=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.9.1/go.mod h1:GFyFmDsE2wDuIHZD+4+JErGpA0S4zJsKNz5l2JVJd8s=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.9.1 h1:sIW6xe4yU5eIMH8fve2C78d+r29KmHnIb+7po+80bsY=
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.9.1/go.mod h1:3pNf99GnK9eu3XUa5ebHzgEQSVYf9hqAoPFwbwD6O6M=
|
||||
github.com/sigstore/timestamp-authority v1.2.5 h1:W22JmwRv1Salr/NFFuP7iJuhytcZszQjldoB8GiEdnw=
|
||||
github.com/sigstore/timestamp-authority v1.2.5/go.mod h1:gWPKWq4HMWgPCETre0AakgBzcr9DRqHrsgbrRqsigOs=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
||||
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
|
||||
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
|
||||
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
|
||||
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
||||
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
||||
github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
|
||||
github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
|
|
@ -508,6 +494,12 @@ github.com/theupdateframework/go-tuf/v2 v2.0.2 h1:PyNnjV9BJNzN1ZE6BcWK+5JbF+if37
|
|||
github.com/theupdateframework/go-tuf/v2 v2.0.2/go.mod h1:baB22nBHeHBCeuGZcIlctNq4P61PcOdyARlplg5xmLA=
|
||||
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e h1:BuzhfgfWQbX0dWzYzT1zsORLnHRv3bcRcsaUk0VmXA8=
|
||||
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI=
|
||||
github.com/tink-crypto/tink-go-awskms/v2 v2.1.0 h1:N9UxlsOzu5mttdjhxkDLbzwtEecuXmlxZVo/ds7JKJI=
|
||||
github.com/tink-crypto/tink-go-awskms/v2 v2.1.0/go.mod h1:PxSp9GlOkKL9rlybW804uspnHuO9nbD98V/fDX4uSis=
|
||||
github.com/tink-crypto/tink-go-gcpkms/v2 v2.2.0 h1:3B9i6XBXNTRspfkTC0asN5W0K6GhOSgcujNiECNRNb0=
|
||||
github.com/tink-crypto/tink-go-gcpkms/v2 v2.2.0/go.mod h1:jY5YN2BqD/KSCHM9SqZPIpJNG/u3zwfLXHgws4x2IRw=
|
||||
github.com/tink-crypto/tink-go/v2 v2.3.0 h1:4/TA0lw0lA/iVKBL9f8R5eP7397bfc4antAMXF5JRhs=
|
||||
github.com/tink-crypto/tink-go/v2 v2.3.0/go.mod h1:kfPOtXIadHlekBTeBtJrHWqoGL+Fm3JQg0wtltPuxLU=
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
|
||||
github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4=
|
||||
|
|
@ -528,22 +520,22 @@ go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd
|
|||
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=
|
||||
go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw=
|
||||
go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I=
|
||||
go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ=
|
||||
go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M=
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM=
|
||||
go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.step.sm/crypto v0.57.0 h1:YjoRQDaJYAxHLVwjst0Bl0xcnoKzVwuHCJtEo2VSHYU=
|
||||
go.step.sm/crypto v0.57.0/go.mod h1:+Lwp5gOVPaTa3H/Ul/TzGbxQPXZZcKIUGMS0lG6n9Go=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.step.sm/crypto v0.60.0 h1:UgSw8DFG5xUOGB3GUID17UA32G4j1iNQ4qoMhBmsVFw=
|
||||
go.step.sm/crypto v0.60.0/go.mod h1:Ep83Lv818L4gV0vhFTdPWRKnL6/5fRMpi8SaoP5ArSw=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
|
|
@ -552,24 +544,24 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
|||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
|
||||
golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
|
||||
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
|
||||
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
|
||||
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -580,46 +572,44 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
|
||||
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
||||
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
|
||||
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
|
||||
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
|
||||
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.216.0 h1:xnEHy+xWFrtYInWPy8OdGFsyIfWJjtVnO39g7pz2BFY=
|
||||
google.golang.org/api v0.216.0/go.mod h1:K9wzQMvWi47Z9IU7OgdOofvZuw75Ge3PPITImZR/UyI=
|
||||
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk=
|
||||
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A=
|
||||
google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/api v0.227.0 h1:QvIHF9IuyG6d6ReE+BNd11kIB8hZvjN8Z5xY5t21zYc=
|
||||
google.golang.org/api v0.227.0/go.mod h1:EIpaG6MbTgQarWF5xJvX0eOJPK9n/5D4Bynb9j2HXvQ=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import (
|
|||
const (
|
||||
aliasesKey = "aliases"
|
||||
browserKey = "browser"
|
||||
colorLabelsKey = "color_labels"
|
||||
editorKey = "editor"
|
||||
gitProtocolKey = "git_protocol"
|
||||
hostsKey = "hosts"
|
||||
|
|
@ -113,6 +114,11 @@ func (c *cfg) Browser(hostname string) gh.ConfigEntry {
|
|||
return c.GetOrDefault(hostname, browserKey).Unwrap()
|
||||
}
|
||||
|
||||
func (c *cfg) ColorLabels(hostname string) gh.ConfigEntry {
|
||||
// Intentionally panic if there is no user provided value or default value (which would be a programmer error)
|
||||
return c.GetOrDefault(hostname, colorLabelsKey).Unwrap()
|
||||
}
|
||||
|
||||
func (c *cfg) Editor(hostname string) gh.ConfigEntry {
|
||||
// Intentionally panic if there is no user provided value or default value (which would be a programmer error)
|
||||
return c.GetOrDefault(hostname, editorKey).Unwrap()
|
||||
|
|
@ -532,6 +538,8 @@ aliases:
|
|||
http_unix_socket:
|
||||
# What web browser gh should use when opening URLs. If blank, will refer to environment.
|
||||
browser:
|
||||
# Whether to display labels using their RGB hex color codes in terminals that support truecolor. Supported values: enabled, disabled
|
||||
color_labels: disabled
|
||||
`
|
||||
|
||||
type ConfigOption struct {
|
||||
|
|
@ -602,6 +610,15 @@ var Options = []ConfigOption{
|
|||
return c.Browser(hostname).Value
|
||||
},
|
||||
},
|
||||
{
|
||||
Key: colorLabelsKey,
|
||||
Description: "whether to display labels using their RGB hex color codes in terminals that support truecolor",
|
||||
DefaultValue: "disabled",
|
||||
AllowedValues: []string{"enabled", "disabled"},
|
||||
CurrentValue: func(c gh.Config, hostname string) string {
|
||||
return c.ColorLabels(hostname).Value
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func HomeDirPath(subdir string) (string, error) {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ func TestNewConfigProvidesFallback(t *testing.T) {
|
|||
requireKeyWithValue(t, spiedCfg, []string{aliasesKey, "co"}, "pr checkout")
|
||||
requireKeyWithValue(t, spiedCfg, []string{httpUnixSocketKey}, "")
|
||||
requireKeyWithValue(t, spiedCfg, []string{browserKey}, "")
|
||||
requireKeyWithValue(t, spiedCfg, []string{colorLabelsKey}, "disabled")
|
||||
}
|
||||
|
||||
func TestGetOrDefaultApplicationDefaults(t *testing.T) {
|
||||
|
|
@ -137,6 +138,7 @@ func TestFallbackConfig(t *testing.T) {
|
|||
requireKeyWithValue(t, cfg, []string{aliasesKey, "co"}, "pr checkout")
|
||||
requireKeyWithValue(t, cfg, []string{httpUnixSocketKey}, "")
|
||||
requireKeyWithValue(t, cfg, []string{browserKey}, "")
|
||||
requireKeyWithValue(t, cfg, []string{colorLabelsKey}, "disabled")
|
||||
requireNoKey(t, cfg, []string{"unknown"})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ func NewFromString(cfgStr string) *ghmock.ConfigMock {
|
|||
mock.BrowserFunc = func(hostname string) gh.ConfigEntry {
|
||||
return cfg.Browser(hostname)
|
||||
}
|
||||
mock.ColorLabelsFunc = func(hostname string) gh.ConfigEntry {
|
||||
return cfg.ColorLabels(hostname)
|
||||
}
|
||||
mock.EditorFunc = func(hostname string) gh.ConfigEntry {
|
||||
return cfg.Editor(hostname)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ type Config interface {
|
|||
|
||||
// Browser returns the configured browser, optionally scoped by host.
|
||||
Browser(hostname string) ConfigEntry
|
||||
// ColorLabels returns the configured color_label setting, optionally scoped by host.
|
||||
ColorLabels(hostname string) ConfigEntry
|
||||
// Editor returns the configured editor, optionally scoped by host.
|
||||
Editor(hostname string) ConfigEntry
|
||||
// GitProtocol returns the configured git protocol, optionally scoped by host.
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ var _ gh.Config = &ConfigMock{}
|
|||
// CacheDirFunc: func() string {
|
||||
// panic("mock out the CacheDir method")
|
||||
// },
|
||||
// ColorLabelsFunc: func(hostname string) gh.ConfigEntry {
|
||||
// panic("mock out the ColorLabels method")
|
||||
// },
|
||||
// EditorFunc: func(hostname string) gh.ConfigEntry {
|
||||
// panic("mock out the Editor method")
|
||||
// },
|
||||
|
|
@ -83,6 +86,9 @@ type ConfigMock struct {
|
|||
// CacheDirFunc mocks the CacheDir method.
|
||||
CacheDirFunc func() string
|
||||
|
||||
// ColorLabelsFunc mocks the ColorLabels method.
|
||||
ColorLabelsFunc func(hostname string) gh.ConfigEntry
|
||||
|
||||
// EditorFunc mocks the Editor method.
|
||||
EditorFunc func(hostname string) gh.ConfigEntry
|
||||
|
||||
|
|
@ -132,6 +138,11 @@ type ConfigMock struct {
|
|||
// CacheDir holds details about calls to the CacheDir method.
|
||||
CacheDir []struct {
|
||||
}
|
||||
// ColorLabels holds details about calls to the ColorLabels method.
|
||||
ColorLabels []struct {
|
||||
// Hostname is the hostname argument value.
|
||||
Hostname string
|
||||
}
|
||||
// Editor holds details about calls to the Editor method.
|
||||
Editor []struct {
|
||||
// Hostname is the hostname argument value.
|
||||
|
|
@ -194,6 +205,7 @@ type ConfigMock struct {
|
|||
lockAuthentication sync.RWMutex
|
||||
lockBrowser sync.RWMutex
|
||||
lockCacheDir sync.RWMutex
|
||||
lockColorLabels sync.RWMutex
|
||||
lockEditor sync.RWMutex
|
||||
lockGetOrDefault sync.RWMutex
|
||||
lockGitProtocol sync.RWMutex
|
||||
|
|
@ -320,6 +332,38 @@ func (mock *ConfigMock) CacheDirCalls() []struct {
|
|||
return calls
|
||||
}
|
||||
|
||||
// ColorLabels calls ColorLabelsFunc.
|
||||
func (mock *ConfigMock) ColorLabels(hostname string) gh.ConfigEntry {
|
||||
if mock.ColorLabelsFunc == nil {
|
||||
panic("ConfigMock.ColorLabelsFunc: method is nil but Config.ColorLabels was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
Hostname string
|
||||
}{
|
||||
Hostname: hostname,
|
||||
}
|
||||
mock.lockColorLabels.Lock()
|
||||
mock.calls.ColorLabels = append(mock.calls.ColorLabels, callInfo)
|
||||
mock.lockColorLabels.Unlock()
|
||||
return mock.ColorLabelsFunc(hostname)
|
||||
}
|
||||
|
||||
// ColorLabelsCalls gets all the calls that were made to ColorLabels.
|
||||
// Check the length with:
|
||||
//
|
||||
// len(mockedConfig.ColorLabelsCalls())
|
||||
func (mock *ConfigMock) ColorLabelsCalls() []struct {
|
||||
Hostname string
|
||||
} {
|
||||
var calls []struct {
|
||||
Hostname string
|
||||
}
|
||||
mock.lockColorLabels.RLock()
|
||||
calls = mock.calls.ColorLabels
|
||||
mock.lockColorLabels.RUnlock()
|
||||
return calls
|
||||
}
|
||||
|
||||
// Editor calls EditorFunc.
|
||||
func (mock *ConfigMock) Editor(hostname string) gh.ConfigEntry {
|
||||
if mock.EditorFunc == nil {
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ func NewWithWriter(w io.Writer, isTTY bool, maxWidth int, cs *iostreams.ColorSch
|
|||
// was not padded. In tests cs.Enabled() is false which allows us to avoid having to fix up
|
||||
// numerous tests that verify header padding.
|
||||
var paddingFunc func(int, string) string
|
||||
if cs.Enabled() {
|
||||
if cs.Enabled {
|
||||
paddingFunc = text.PadRight
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,13 +5,17 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/sigstore/sigstore-go/pkg/bundle"
|
||||
sgData "github.com/sigstore/sigstore-go/pkg/testing/data"
|
||||
)
|
||||
|
||||
//go:embed sigstore-js-2.1.0-bundle.json
|
||||
var SigstoreBundleRaw []byte
|
||||
|
||||
// SigstoreBundle returns a test *sigstore.Bundle
|
||||
// SigstoreBundle returns a test sigstore-go bundle.Bundle
|
||||
func SigstoreBundle(t *testing.T) *bundle.Bundle {
|
||||
return sgData.TestBundle(t, SigstoreBundleRaw)
|
||||
b := &bundle.Bundle{}
|
||||
err := b.UnmarshalJSON(SigstoreBundleRaw)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to unmarshal sigstore bundle: %v", err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ func validateSignerWorkflow(hostname, signerWorkflow string) (string, error) {
|
|||
// if the provided workflow did not match the expect format
|
||||
// we move onto creating a signer workflow using the provided host name
|
||||
if hostname == "" {
|
||||
return "", errors.New("unknown host")
|
||||
return "", errors.New("unknown signer workflow host")
|
||||
}
|
||||
|
||||
return fmt.Sprintf("^https://%s/%s", hostname, signerWorkflow), nil
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ func TestValidateSignerWorkflow(t *testing.T) {
|
|||
name: "workflow with no host specified",
|
||||
providedSignerWorkflow: "github/artifact-attestations-workflows/.github/workflows/attest.yml",
|
||||
expectErr: true,
|
||||
errContains: "unknown host",
|
||||
errContains: "unknown signer workflow host",
|
||||
},
|
||||
{
|
||||
name: "workflow with default host",
|
||||
|
|
|
|||
|
|
@ -30,58 +30,107 @@ func NewVerifyCmd(f *cmdutil.Factory, runF func(*Options) error) *cobra.Command
|
|||
Verify the integrity and provenance of an artifact using its associated
|
||||
cryptographically signed attestations.
|
||||
|
||||
In order to verify an attestation, you must validate the identity of the Actions
|
||||
workflow that produced the attestation (a.k.a. the signer workflow). Given this
|
||||
identity, the verification process checks the signatures in the attestations,
|
||||
and confirms that the attestation refers to provided artifact.
|
||||
## Understanding Verification
|
||||
|
||||
To specify the artifact, the command requires:
|
||||
An attestation is a claim (i.e. a provenance statement) made by an actor
|
||||
(i.e. a GitHub Actions workflow) regarding a subject (i.e. an artifact).
|
||||
|
||||
In order to verify an attestation, you must provide an artifact and validate:
|
||||
* the identity of the actor that produced the attestation
|
||||
* the expected attestation predicate type (the nature of the claim)
|
||||
|
||||
By default, this command enforces the %[1]s%[2]s%[1]s
|
||||
predicate type. To verify other attestation predicate types use the
|
||||
%[1]s--predicate-type%[1]s flag.
|
||||
|
||||
The "actor identity" consists of:
|
||||
* the repository or the repository owner the artifact is linked with
|
||||
* the Actions workflow that produced the attestation (a.k.a the
|
||||
signer workflow)
|
||||
|
||||
This identity is then validated against the attestation's certificate's
|
||||
SourceRepository, SourceRepositoryOwner, and SubjectAlternativeName
|
||||
(SAN) fields, among others.
|
||||
|
||||
It is up to you to decide how precisely you want to enforce this identity.
|
||||
|
||||
At a minimum, this command requires either:
|
||||
* the %[1]s--owner%[1]s flag (e.g. --owner github), or
|
||||
* the %[1]s--repo%[1]s flag (e.g. --repo github/example)
|
||||
|
||||
The more precisely you specify the identity, the more control you will
|
||||
have over the security guarantees offered by the verification process.
|
||||
|
||||
Ideally, the path of the signer workflow is also validated using the
|
||||
%[1]s--signer-workflow%[1]s or %[1]s--cert-identity%[1]s flags.
|
||||
|
||||
Please note: if your attestation was generated via a reusable workflow then
|
||||
that reusable workflow is the signer whose identity needs to be validated.
|
||||
In this situation, you must use either the %[1]s--signer-workflow%[1]s or
|
||||
the %[1]s--signer-repo%[1]s flag.
|
||||
|
||||
For more options, see the other available flags.
|
||||
|
||||
## Loading Artifacts And Attestations
|
||||
|
||||
To specify the artifact, this command requires:
|
||||
* a file path to an artifact, or
|
||||
* a container image URI (e.g. %[1]soci://<image-uri>%[1]s)
|
||||
* (note that if you provide an OCI URL, you must already be authenticated with
|
||||
its container registry)
|
||||
|
||||
To fetch the attestation, and validate the identity of the signer, the command
|
||||
requires either:
|
||||
* the %[1]s--repo%[1]s flag (e.g. --repo github/example).
|
||||
* the %[1]s--owner%[1]s flag (e.g. --owner github), or
|
||||
By default, this command will attempt to fetch relevant attestations via the
|
||||
GitHub API using the values provided to %[1]s--owner%[1]s or %[1]s--repo%[1]s.
|
||||
|
||||
The %[1]s--repo%[1]s flag value must match the name of the GitHub repository
|
||||
that the artifact is linked with.
|
||||
To instead fetch attestations from your artifact's OCI registry, use the
|
||||
%[1]s--bundle-from-oci%[1]s flag.
|
||||
|
||||
The %[1]s--owner%[1]s flag value must match the name of the GitHub organization
|
||||
that the artifact's linked repository belongs to.
|
||||
For offline verification using attestations stored on disk (c.f. the download command)
|
||||
provide a path to the %[1]s--bundle%[1]s flag.
|
||||
|
||||
By default, the verify command will:
|
||||
- only verify provenance attestations
|
||||
- attempt to fetch relevant attestations via the GitHub API.
|
||||
## Additional Policy Enforcement
|
||||
|
||||
To verify other types of attestations, use the %[1]s--predicate-type%[1]s flag.
|
||||
Given the %[1]s--format=json%[1]s flag, upon successful verification this
|
||||
command will output a JSON array containing one entry per verified attestation.
|
||||
|
||||
To use your artifact's OCI registry instead of GitHub's API, use the
|
||||
%[1]s--bundle-from-oci%[1]s flag. For offline verification, using attestations
|
||||
stored on desk (c.f. the download command), provide a path to the %[1]s--bundle%[1]s flag.
|
||||
This output can then be used for additional policy enforcement, i.e. by being
|
||||
piped into a policy engine.
|
||||
|
||||
To see the full results that are generated upon successful verification, i.e.
|
||||
for use with a policy engine, provide the %[1]s--format=json%[1]s flag.
|
||||
Each object in the array contains two properties:
|
||||
* an %[1]sattestation%[1]s object, which contains the bundle that was verified
|
||||
* a %[1]sverificationResult%[1]s object, which is a parsed representation of the
|
||||
contents of the bundle that was verified.
|
||||
|
||||
The signer workflow's identity is validated against the Subject Alternative Name (SAN)
|
||||
within the attestation certificate. Often, the signer workflow is the
|
||||
same workflow that started the run and generated the attestation, and will be
|
||||
located inside your repository. For this reason, by default this command uses
|
||||
either the %[1]s--repo%[1]s or the %[1]s--owner%[1]s flag value to validate the SAN.
|
||||
Within the %[1]sverificationResult%[1]s object you will find:
|
||||
* %[1]ssignature.certificate%[1]s, which is a parsed representation of the X.509
|
||||
certificate embedded in the attestation,
|
||||
* %[1]sverifiedTimestamps%[1]s, an array of objects denoting when the attestation
|
||||
was witnessed by a transparency log or a timestamp authority
|
||||
* %[1]sstatement%[1]s, which contains the %[1]ssubject%[1]s array referencing artifacts,
|
||||
the %[1]spredicateType%[1]s field, and the %[1]spredicate%[1]s object which contains
|
||||
additional, often user-controllable, metadata
|
||||
|
||||
However, sometimes the caller workflow is not the same workflow that
|
||||
performed the signing. If your attestation was generated via a reusable
|
||||
workflow, then that reusable workflow is the signer whose identity needs to be
|
||||
validated. In this situation, the signer workflow may or may not be located
|
||||
inside your %[1]s--repo%[1]s or %[1]s--owner%[1]s.
|
||||
IMPORTANT: please note that only the %[1]ssignature.certificate%[1]s and the
|
||||
%[1]sverifiedTimestamps%[1]s properties contain values that cannot be
|
||||
manipulated by the workflow that originated the attestation.
|
||||
|
||||
When using reusable workflows, use the %[1]s--signer-repo%[1]s, %[1]s--signer-workflow%[1]s,
|
||||
or %[1]s--cert-identity%[1]s flags to validate the signer workflow's identity.
|
||||
When dealing with attestations created within GitHub Actions, the contents of
|
||||
%[1]ssignature.certificate%[1]s are populated directly from the OpenID Connect
|
||||
token that GitHub has generated. The contents of the %[1]sverifiedTimestamps%[1]s
|
||||
array are populated from the signed timestamps originating from either a
|
||||
transparency log or a timestamp authority – and likewise cannot be forged by users.
|
||||
|
||||
For more policy verification options, see the other available flags.
|
||||
`, "`"),
|
||||
When designing policy enforcement using this output, special care must be taken
|
||||
when examining the contents of the %[1]sstatement.predicate%[1]s property:
|
||||
should an attacker gain access to your workflow's execution context, they
|
||||
could then falsify the contents of the %[1]sstatement.predicate%[1]s.
|
||||
|
||||
To mitigate this attack vector, consider using a "trusted builder": when generating
|
||||
an artifact, have the build and attestation signing occur within a reusable workflow
|
||||
whose execution cannot be influenced by input provided through the caller workflow.
|
||||
|
||||
See above re: %[1]s--signer-workflow%[1]s.
|
||||
`, "`", verification.SLSAPredicateV1),
|
||||
Example: heredoc.Doc(`
|
||||
# Verify an artifact linked with a repository
|
||||
$ gh attestation verify example.bin --repo github/example
|
||||
|
|
@ -181,23 +230,23 @@ func NewVerifyCmd(f *cmdutil.Factory, runF func(*Options) error) *cobra.Command
|
|||
verifyCmd.Flags().StringVarP(&opts.Repo, "repo", "R", "", "Repository name in the format <owner>/<repo>")
|
||||
verifyCmd.MarkFlagsMutuallyExclusive("owner", "repo")
|
||||
verifyCmd.MarkFlagsOneRequired("owner", "repo")
|
||||
verifyCmd.Flags().StringVarP(&opts.PredicateType, "predicate-type", "", verification.SLSAPredicateV1, "Filter attestations by provided predicate type")
|
||||
verifyCmd.Flags().BoolVarP(&opts.NoPublicGood, "no-public-good", "", false, "Do not verify attestations signed with Sigstore public good instance")
|
||||
verifyCmd.Flags().StringVarP(&opts.TrustedRoot, "custom-trusted-root", "", "", "Path to a trusted_root.jsonl file; likely for offline verification")
|
||||
verifyCmd.Flags().IntVarP(&opts.Limit, "limit", "L", api.DefaultLimit, "Maximum number of attestations to fetch")
|
||||
cmdutil.AddFormatFlags(verifyCmd, &opts.exporter)
|
||||
// policy enforcement flags
|
||||
verifyCmd.Flags().BoolVarP(&opts.DenySelfHostedRunner, "deny-self-hosted-runners", "", false, "Fail verification for attestations generated on self-hosted runners")
|
||||
verifyCmd.Flags().StringVarP(&opts.SAN, "cert-identity", "", "", "Enforce that the certificate's subject alternative name matches the provided value exactly")
|
||||
verifyCmd.Flags().StringVarP(&opts.SANRegex, "cert-identity-regex", "i", "", "Enforce that the certificate's subject alternative name matches the provided regex")
|
||||
verifyCmd.Flags().StringVarP(&opts.SignerRepo, "signer-repo", "", "", "Repository of reusable workflow that signed attestation in the format <owner>/<repo>")
|
||||
verifyCmd.Flags().StringVarP(&opts.SignerWorkflow, "signer-workflow", "", "", "Workflow that signed attestation in the format [host/]<owner>/<repo>/<path>/<to>/<workflow>")
|
||||
verifyCmd.MarkFlagsMutuallyExclusive("cert-identity", "cert-identity-regex", "signer-repo", "signer-workflow")
|
||||
verifyCmd.Flags().StringVarP(&opts.OIDCIssuer, "cert-oidc-issuer", "", verification.GitHubOIDCIssuer, "Issuer of the OIDC token")
|
||||
verifyCmd.Flags().StringVarP(&opts.Hostname, "hostname", "", "", "Configure host to use")
|
||||
verifyCmd.Flags().StringVarP(&opts.SignerDigest, "signer-digest", "", "", "Digest associated with the signer workflow")
|
||||
verifyCmd.Flags().StringVarP(&opts.SourceRef, "source-ref", "", "", "Ref associated with the source workflow")
|
||||
verifyCmd.Flags().StringVarP(&opts.SourceDigest, "source-digest", "", "", "Digest associated with the source workflow")
|
||||
// policy enforcement flags
|
||||
verifyCmd.Flags().StringVarP(&opts.PredicateType, "predicate-type", "", verification.SLSAPredicateV1, "Enforce that verified attestations' predicate type matches the provided value")
|
||||
verifyCmd.Flags().BoolVarP(&opts.DenySelfHostedRunner, "deny-self-hosted-runners", "", false, "Fail verification for attestations generated on self-hosted runners")
|
||||
verifyCmd.Flags().StringVarP(&opts.SAN, "cert-identity", "", "", "Enforce that the certificate's SubjectAlternativeName matches the provided value exactly")
|
||||
verifyCmd.Flags().StringVarP(&opts.SANRegex, "cert-identity-regex", "i", "", "Enforce that the certificate's SubjectAlternativeName matches the provided regex")
|
||||
verifyCmd.Flags().StringVarP(&opts.SignerRepo, "signer-repo", "", "", "Enforce that the workflow that signed the attestation's repository matches the provided value (<owner>/<repo>)")
|
||||
verifyCmd.Flags().StringVarP(&opts.SignerWorkflow, "signer-workflow", "", "", "Enforce that the workflow that signed the attestation matches the provided value ([host/]<owner>/<repo>/<path>/<to>/<workflow>)")
|
||||
verifyCmd.MarkFlagsMutuallyExclusive("cert-identity", "cert-identity-regex", "signer-repo", "signer-workflow")
|
||||
verifyCmd.Flags().StringVarP(&opts.OIDCIssuer, "cert-oidc-issuer", "", verification.GitHubOIDCIssuer, "Enforce that the issuer of the OIDC token matches the provided value")
|
||||
verifyCmd.Flags().StringVarP(&opts.SignerDigest, "signer-digest", "", "", "Enforce that the digest associated with the signer workflow matches the provided value")
|
||||
verifyCmd.Flags().StringVarP(&opts.SourceRef, "source-ref", "", "", "Enforce that the git ref associated with the source repository matches the provided value")
|
||||
verifyCmd.Flags().StringVarP(&opts.SourceDigest, "source-digest", "", "", "Enforce that the digest associated with the source repository matches the provided value")
|
||||
|
||||
return verifyCmd
|
||||
}
|
||||
|
|
|
|||
9
pkg/cmd/cache/list/list.go
vendored
9
pkg/cmd/cache/list/list.go
vendored
|
|
@ -99,11 +99,12 @@ func listRun(opts *ListOptions) error {
|
|||
}
|
||||
client := api.NewClientFromHTTP(httpClient)
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
opts.IO.StartProgressIndicator()
|
||||
result, err := shared.GetCaches(client, repo, shared.GetCachesOptions{Limit: opts.Limit, Sort: opts.Sort, Order: opts.Order, Key: opts.Key, Ref: opts.Ref})
|
||||
opts.IO.StopProgressIndicator()
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s Failed to get caches: %w", opts.IO.ColorScheme().FailureIcon(), err)
|
||||
return fmt.Errorf("%s Failed to get caches: %w", cs.FailureIcon(), err)
|
||||
}
|
||||
|
||||
if len(result.ActionsCaches) == 0 && opts.Exporter == nil {
|
||||
|
|
@ -130,11 +131,11 @@ func listRun(opts *ListOptions) error {
|
|||
|
||||
tp := tableprinter.New(opts.IO, tableprinter.WithHeader("ID", "KEY", "SIZE", "CREATED", "ACCESSED"))
|
||||
for _, cache := range result.ActionsCaches {
|
||||
tp.AddField(opts.IO.ColorScheme().Cyan(fmt.Sprintf("%d", cache.Id)))
|
||||
tp.AddField(cs.Cyanf("%d", cache.Id))
|
||||
tp.AddField(cache.Key)
|
||||
tp.AddField(humanFileSize(cache.SizeInBytes))
|
||||
tp.AddTimeField(opts.Now, cache.CreatedAt, opts.IO.ColorScheme().Gray)
|
||||
tp.AddTimeField(opts.Now, cache.LastAccessedAt, opts.IO.ColorScheme().Gray)
|
||||
tp.AddTimeField(opts.Now, cache.CreatedAt, cs.Muted)
|
||||
tp.AddTimeField(opts.Now, cache.LastAccessedAt, cs.Muted)
|
||||
tp.EndRow()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ func (a *App) List(ctx context.Context, opts *listOptions, exporter cmdutil.Expo
|
|||
case false:
|
||||
nameColor = cs.Yellow
|
||||
case true:
|
||||
nameColor = cs.Gray
|
||||
nameColor = cs.Muted
|
||||
}
|
||||
|
||||
tp.AddField(formattedName, tableprinter.WithColor(nameColor))
|
||||
|
|
@ -172,7 +172,7 @@ func (a *App) List(ctx context.Context, opts *listOptions, exporter cmdutil.Expo
|
|||
if err != nil {
|
||||
return fmt.Errorf("error parsing date %q: %w", c.CreatedAt, err)
|
||||
}
|
||||
tp.AddTimeField(time.Now(), ct, cs.Gray)
|
||||
tp.AddTimeField(time.Now(), ct, cs.Muted)
|
||||
|
||||
if hasNonProdVSCSTarget {
|
||||
tp.AddField(c.VSCSTarget)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/MakeNowJust/heredoc"
|
||||
"github.com/cli/cli/v2/internal/config"
|
||||
"github.com/cli/cli/v2/internal/gh"
|
||||
"github.com/cli/cli/v2/pkg/cmdutil"
|
||||
|
|
@ -91,14 +92,16 @@ func Test_listRun(t *testing.T) {
|
|||
return cfg
|
||||
}(),
|
||||
input: &ListOptions{Hostname: "HOST"},
|
||||
stdout: `git_protocol=ssh
|
||||
editor=/usr/bin/vim
|
||||
prompt=disabled
|
||||
prefer_editor_prompt=enabled
|
||||
pager=less
|
||||
http_unix_socket=
|
||||
browser=brave
|
||||
`,
|
||||
stdout: heredoc.Doc(`
|
||||
git_protocol=ssh
|
||||
editor=/usr/bin/vim
|
||||
prompt=disabled
|
||||
prefer_editor_prompt=enabled
|
||||
pager=less
|
||||
http_unix_socket=
|
||||
browser=brave
|
||||
color_labels=disabled
|
||||
`),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/cli/cli/v2/pkg/cmd/extension"
|
||||
"github.com/cli/cli/v2/pkg/cmdutil"
|
||||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
xcolor "github.com/cli/go-gh/v2/pkg/x/color"
|
||||
)
|
||||
|
||||
var ssoHeader string
|
||||
|
|
@ -292,6 +293,19 @@ func ioStreams(f *cmdutil.Factory) *iostreams.IOStreams {
|
|||
io.SetPager(pager.Value)
|
||||
}
|
||||
|
||||
if ghColorLabels, ghColorLabelsExists := os.LookupEnv("GH_COLOR_LABELS"); ghColorLabelsExists {
|
||||
switch ghColorLabels {
|
||||
case "", "0", "false", "no":
|
||||
io.SetColorLabels(false)
|
||||
default:
|
||||
io.SetColorLabels(true)
|
||||
}
|
||||
} else if prompt := cfg.ColorLabels(""); prompt.Value == "enabled" {
|
||||
io.SetColorLabels(true)
|
||||
}
|
||||
|
||||
io.SetAccessibleColorsEnabled(xcolor.IsAccessibleColorsEnabled())
|
||||
|
||||
return io
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -432,6 +432,84 @@ func Test_ioStreams_prompt(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_ioStreams_colorLabels(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config gh.Config
|
||||
colorLabelsEnabled bool
|
||||
env map[string]string
|
||||
}{
|
||||
{
|
||||
name: "default config",
|
||||
colorLabelsEnabled: false,
|
||||
},
|
||||
{
|
||||
name: "config with colorLabels enabled",
|
||||
config: enableColorLabelsConfig(),
|
||||
colorLabelsEnabled: true,
|
||||
},
|
||||
{
|
||||
name: "config with colorLabels disabled",
|
||||
config: disableColorLabelsConfig(),
|
||||
colorLabelsEnabled: false,
|
||||
},
|
||||
{
|
||||
name: "colorLabels enabled via `1` in GH_COLOR_LABELS env var",
|
||||
env: map[string]string{"GH_COLOR_LABELS": "1"},
|
||||
colorLabelsEnabled: true,
|
||||
},
|
||||
{
|
||||
name: "colorLabels enabled via `true` in GH_COLOR_LABELS env var",
|
||||
env: map[string]string{"GH_COLOR_LABELS": "true"},
|
||||
colorLabelsEnabled: true,
|
||||
},
|
||||
{
|
||||
name: "colorLabels enabled via `yes` in GH_COLOR_LABELS env var",
|
||||
env: map[string]string{"GH_COLOR_LABELS": "yes"},
|
||||
colorLabelsEnabled: true,
|
||||
},
|
||||
{
|
||||
name: "colorLabels disable via empty string in GH_COLOR_LABELS env var",
|
||||
env: map[string]string{"GH_COLOR_LABELS": ""},
|
||||
colorLabelsEnabled: false,
|
||||
},
|
||||
{
|
||||
name: "colorLabels disabled via `0` in GH_COLOR_LABELS env var",
|
||||
env: map[string]string{"GH_COLOR_LABELS": "0"},
|
||||
colorLabelsEnabled: false,
|
||||
},
|
||||
{
|
||||
name: "colorLabels disabled via `false` in GH_COLOR_LABELS env var",
|
||||
env: map[string]string{"GH_COLOR_LABELS": "false"},
|
||||
colorLabelsEnabled: false,
|
||||
},
|
||||
{
|
||||
name: "colorLabels disabled via `no` in GH_COLOR_LABELS env var",
|
||||
env: map[string]string{"GH_COLOR_LABELS": "no"},
|
||||
colorLabelsEnabled: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.env != nil {
|
||||
for k, v := range tt.env {
|
||||
t.Setenv(k, v)
|
||||
}
|
||||
}
|
||||
f := New("1")
|
||||
f.Config = func() (gh.Config, error) {
|
||||
if tt.config == nil {
|
||||
return config.NewBlankConfig(), nil
|
||||
} else {
|
||||
return tt.config, nil
|
||||
}
|
||||
}
|
||||
io := ioStreams(f)
|
||||
assert.Equal(t, tt.colorLabelsEnabled, io.ColorLabels())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSSOURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
@ -537,3 +615,11 @@ func pagerConfig() gh.Config {
|
|||
func disablePromptConfig() gh.Config {
|
||||
return config.NewFromString("prompt: disabled")
|
||||
}
|
||||
|
||||
func disableColorLabelsConfig() gh.Config {
|
||||
return config.NewFromString("color_labels: disabled")
|
||||
}
|
||||
|
||||
func enableColorLabelsConfig() gh.Config {
|
||||
return config.NewFromString("color_labels: enabled")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ func createRun(opts *CreateOptions) error {
|
|||
processMessage = fmt.Sprintf("Creating gist %s", gistName)
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(errOut, "%s %s\n", cs.Gray("-"), processMessage)
|
||||
fmt.Fprintf(errOut, "%s %s\n", cs.Muted("-"), processMessage)
|
||||
|
||||
httpClient, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ func printTable(io *iostreams.IOStreams, gists []shared.Gist, filter *regexp.Reg
|
|||
tableprinter.WithColor(highlightFilesFunc(&gist)),
|
||||
)
|
||||
tp.AddField(visibility, tableprinter.WithColor(visColor))
|
||||
tp.AddTimeField(time.Now(), gist.UpdatedAt, cs.Gray)
|
||||
tp.AddTimeField(time.Now(), gist.UpdatedAt, cs.Muted)
|
||||
tp.EndRow()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -487,8 +487,8 @@ func Test_listRun(t *testing.T) {
|
|||
},
|
||||
wantOut: heredoc.Docf(`
|
||||
%[1]s[0;4;39mID %[1]s[0m %[1]s[0;4;39mDESCRIPTION %[1]s[0m %[1]s[0;4;39mFILES %[1]s[0m %[1]s[0;4;39mVISIBILITY%[1]s[0m %[1]s[0;4;39mUPDATED %[1]s[0m
|
||||
1234 %[1]s[0;30;43mocto%[1]s[0m%[1]s[0;1;39m match in the description%[1]s[0m 1 file %[1]s[0;32mpublic %[1]s[0m %[1]s[38;5;242mabout 6 hours ago%[1]s[m
|
||||
2345 %[1]s[0;1;39mmatch in the file name %[1]s[0m %[1]s[0;30;43m2 files%[1]s[0m %[1]s[0;31msecret %[1]s[0m %[1]s[38;5;242mabout 6 hours ago%[1]s[m
|
||||
1234 %[1]s[0;30;43mocto%[1]s[0m%[1]s[0;1;39m match in the description%[1]s[0m 1 file %[1]s[0;32mpublic %[1]s[0m %[1]s[38;5;242mabout 6 hours ago%[1]s[0m
|
||||
2345 %[1]s[0;1;39mmatch in the file name %[1]s[0m %[1]s[0;30;43m2 files%[1]s[0m %[1]s[0;31msecret %[1]s[0m %[1]s[38;5;242mabout 6 hours ago%[1]s[0m
|
||||
`, "\x1b"),
|
||||
},
|
||||
{
|
||||
|
|
@ -654,50 +654,57 @@ func Test_highlightMatch(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
color bool
|
||||
cs *iostreams.ColorScheme
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "single match",
|
||||
input: "Octo",
|
||||
cs: &iostreams.ColorScheme{},
|
||||
want: "Octo",
|
||||
},
|
||||
{
|
||||
name: "single match (color)",
|
||||
input: "Octo",
|
||||
color: true,
|
||||
want: "\x1b[0;30;43mOcto\x1b[0m",
|
||||
cs: &iostreams.ColorScheme{
|
||||
Enabled: true,
|
||||
},
|
||||
want: "\x1b[0;30;43mOcto\x1b[0m",
|
||||
},
|
||||
{
|
||||
name: "single match with extra",
|
||||
input: "Hello, Octocat!",
|
||||
cs: &iostreams.ColorScheme{},
|
||||
want: "Hello, Octocat!",
|
||||
},
|
||||
{
|
||||
name: "single match with extra (color)",
|
||||
input: "Hello, Octocat!",
|
||||
color: true,
|
||||
want: "\x1b[0;34mHello, \x1b[0m\x1b[0;30;43mOcto\x1b[0m\x1b[0;34mcat!\x1b[0m",
|
||||
cs: &iostreams.ColorScheme{
|
||||
Enabled: true,
|
||||
},
|
||||
want: "\x1b[0;34mHello, \x1b[0m\x1b[0;30;43mOcto\x1b[0m\x1b[0;34mcat!\x1b[0m",
|
||||
},
|
||||
{
|
||||
name: "multiple matches",
|
||||
input: "Octocat/octo",
|
||||
cs: &iostreams.ColorScheme{},
|
||||
want: "Octocat/octo",
|
||||
},
|
||||
{
|
||||
name: "multiple matches (color)",
|
||||
input: "Octocat/octo",
|
||||
color: true,
|
||||
want: "\x1b[0;30;43mOcto\x1b[0m\x1b[0;34mcat/\x1b[0m\x1b[0;30;43mocto\x1b[0m",
|
||||
cs: &iostreams.ColorScheme{
|
||||
Enabled: true,
|
||||
},
|
||||
want: "\x1b[0;30;43mOcto\x1b[0m\x1b[0;34mcat/\x1b[0m\x1b[0;30;43mocto\x1b[0m",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cs := iostreams.NewColorScheme(tt.color, false, false, iostreams.NoTheme)
|
||||
|
||||
matched := false
|
||||
got, err := highlightMatch(tt.input, regex, &matched, cs.Blue, cs.Highlight)
|
||||
got, err := highlightMatch(tt.input, regex, &matched, tt.cs.Blue, tt.cs.Highlight)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, matched)
|
||||
assert.Equal(t, tt.want, got)
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ func PromptGists(prompter prompter.Prompter, client *http.Client, host string, c
|
|||
for i, gist := range gists {
|
||||
gistTime := text.FuzzyAgo(time.Now(), gist.UpdatedAt)
|
||||
// TODO: support dynamic maxWidth
|
||||
opts[i] = fmt.Sprintf("%s %s %s", cs.Bold(gist.Filename()), gist.TruncDescription(), cs.Gray(gistTime))
|
||||
opts[i] = fmt.Sprintf("%s %s %s", cs.Bold(gist.Filename()), gist.TruncDescription(), cs.Muted(gistTime))
|
||||
}
|
||||
|
||||
result, err := prompter.Select("Select a gist", "", opts)
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ func viewRun(opts *ViewOptions) error {
|
|||
if len(gist.Files) == 1 || opts.Filename != "" {
|
||||
return fmt.Errorf("error: file is binary")
|
||||
}
|
||||
_, err = fmt.Fprintln(opts.IO.Out, cs.Gray("(skipping rendering binary content)"))
|
||||
_, err = fmt.Fprintln(opts.IO.Out, cs.Muted("(skipping rendering binary content)"))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -197,7 +197,7 @@ func viewRun(opts *ViewOptions) error {
|
|||
|
||||
for i, fn := range filenames {
|
||||
if showFilenames {
|
||||
fmt.Fprintf(opts.IO.Out, "%s\n\n", cs.Gray(fn))
|
||||
fmt.Fprintf(opts.IO.Out, "%s\n\n", cs.Muted(fn))
|
||||
}
|
||||
if err := render(gist.Files[fn]); err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ func listRun(opts *ListOptions) error {
|
|||
t.AddField(gpgKey.Emails.String())
|
||||
t.AddField(gpgKey.KeyID)
|
||||
t.AddField(gpgKey.PublicKey, tableprinter.WithTruncate(truncateMiddle))
|
||||
t.AddTimeField(now, gpgKey.CreatedAt, cs.Gray)
|
||||
t.AddTimeField(now, gpgKey.CreatedAt, cs.Muted)
|
||||
expiresAt := gpgKey.ExpiresAt.Format(time.RFC3339)
|
||||
if t.IsTTY() {
|
||||
if gpgKey.ExpiresAt.IsZero() {
|
||||
|
|
@ -87,7 +87,7 @@ func listRun(opts *ListOptions) error {
|
|||
expiresAt = gpgKey.ExpiresAt.Format("2006-01-02")
|
||||
}
|
||||
}
|
||||
t.AddField(expiresAt, tableprinter.WithColor(cs.Gray))
|
||||
t.AddField(expiresAt, tableprinter.WithColor(cs.Muted))
|
||||
t.EndRow()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,13 +38,13 @@ func PrintIssues(io *iostreams.IOStreams, now time.Time, prefix string, totalCou
|
|||
}
|
||||
table.AddField(text.RemoveExcessiveWhitespace(issue.Title))
|
||||
table.AddField(issueLabelList(&issue, cs, isTTY))
|
||||
table.AddTimeField(now, issue.UpdatedAt, cs.Gray)
|
||||
table.AddTimeField(now, issue.UpdatedAt, cs.Muted)
|
||||
table.EndRow()
|
||||
}
|
||||
_ = table.Render()
|
||||
remaining := totalCount - len(issues)
|
||||
if remaining > 0 {
|
||||
fmt.Fprintf(io.Out, cs.Gray("%sAnd %d more\n"), prefix, remaining)
|
||||
fmt.Fprintf(io.Out, cs.Muted("%sAnd %d more\n"), prefix, remaining)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ func issueLabelList(issue *api.Issue, cs *iostreams.ColorScheme, colorize bool)
|
|||
labelNames := make([]string, 0, len(issue.Labels.Nodes))
|
||||
for _, label := range issue.Labels.Nodes {
|
||||
if colorize {
|
||||
labelNames = append(labelNames, cs.HexToRGB(label.Color, label.Name))
|
||||
labelNames = append(labelNames, cs.Label(label.Color, label.Name))
|
||||
} else {
|
||||
labelNames = append(labelNames, label.Name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ func printHumanIssuePreview(opts *ViewOptions, baseRepo ghrepo.Interface, issue
|
|||
var md string
|
||||
var err error
|
||||
if issue.Body == "" {
|
||||
md = fmt.Sprintf("\n %s\n\n", cs.Gray("No description provided"))
|
||||
md = fmt.Sprintf("\n %s\n\n", cs.Muted("No description provided"))
|
||||
} else {
|
||||
md, err = markdown.Render(issue.Body,
|
||||
markdown.WithTheme(opts.IO.TerminalTheme()),
|
||||
|
|
@ -250,7 +250,7 @@ func printHumanIssuePreview(opts *ViewOptions, baseRepo ghrepo.Interface, issue
|
|||
}
|
||||
|
||||
// Footer
|
||||
fmt.Fprintf(out, cs.Gray("View this issue on GitHub: %s\n"), issue.URL)
|
||||
fmt.Fprintf(out, cs.Muted("View this issue on GitHub: %s\n"), issue.URL)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -317,7 +317,7 @@ func issueLabelList(issue *api.Issue, cs *iostreams.ColorScheme) string {
|
|||
if cs == nil {
|
||||
labelNames[i] = label.Name
|
||||
} else {
|
||||
labelNames[i] = cs.HexToRGB(label.Color, label.Name)
|
||||
labelNames[i] = cs.Label(label.Color, label.Name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -137,7 +137,12 @@ func printLabels(io *iostreams.IOStreams, labels []label) error {
|
|||
table := tableprinter.New(io, tableprinter.WithHeader("NAME", "DESCRIPTION", "COLOR"))
|
||||
|
||||
for _, label := range labels {
|
||||
table.AddField(label.Name, tableprinter.WithColor(cs.ColorFromRGB(label.Color)))
|
||||
// Colorize the label using tableprinter's WithColor function for it to handle non-TTY situations
|
||||
labelColor := tableprinter.WithColor(func(s string) string {
|
||||
return cs.Label(label.Color, s)
|
||||
})
|
||||
|
||||
table.AddField(label.Name, labelColor)
|
||||
table.AddField(label.Description)
|
||||
table.AddField("#" + label.Color)
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ func addRow(tp *tableprinter.TablePrinter, io *iostreams.IOStreams, o check) {
|
|||
markColor = cs.Yellow
|
||||
case "skipping", "cancel":
|
||||
mark = "-"
|
||||
markColor = cs.Gray
|
||||
markColor = cs.Muted
|
||||
}
|
||||
|
||||
if io.IsStdoutTTY() {
|
||||
|
|
|
|||
|
|
@ -879,37 +879,37 @@ func renderPullRequestPlain(w io.Writer, params map[string]interface{}, state *s
|
|||
}
|
||||
|
||||
func renderPullRequestTTY(io *iostreams.IOStreams, params map[string]interface{}, state *shared.IssueMetadataState) error {
|
||||
iofmt := io.ColorScheme()
|
||||
cs := io.ColorScheme()
|
||||
out := io.Out
|
||||
|
||||
fmt.Fprint(out, "Would have created a Pull Request with:\n")
|
||||
fmt.Fprintf(out, "%s: %s\n", iofmt.Bold("Title"), params["title"].(string))
|
||||
fmt.Fprintf(out, "%s: %t\n", iofmt.Bold("Draft"), params["draft"])
|
||||
fmt.Fprintf(out, "%s: %s\n", iofmt.Bold("Base"), params["baseRefName"])
|
||||
fmt.Fprintf(out, "%s: %s\n", iofmt.Bold("Head"), params["headRefName"])
|
||||
fmt.Fprintf(out, "%s: %s\n", cs.Bold("Title"), params["title"].(string))
|
||||
fmt.Fprintf(out, "%s: %t\n", cs.Bold("Draft"), params["draft"])
|
||||
fmt.Fprintf(out, "%s: %s\n", cs.Bold("Base"), params["baseRefName"])
|
||||
fmt.Fprintf(out, "%s: %s\n", cs.Bold("Head"), params["headRefName"])
|
||||
if len(state.Labels) != 0 {
|
||||
fmt.Fprintf(out, "%s: %s\n", iofmt.Bold("Labels"), strings.Join(state.Labels, ", "))
|
||||
fmt.Fprintf(out, "%s: %s\n", cs.Bold("Labels"), strings.Join(state.Labels, ", "))
|
||||
}
|
||||
if len(state.Reviewers) != 0 {
|
||||
fmt.Fprintf(out, "%s: %s\n", iofmt.Bold("Reviewers"), strings.Join(state.Reviewers, ", "))
|
||||
fmt.Fprintf(out, "%s: %s\n", cs.Bold("Reviewers"), strings.Join(state.Reviewers, ", "))
|
||||
}
|
||||
if len(state.Assignees) != 0 {
|
||||
fmt.Fprintf(out, "%s: %s\n", iofmt.Bold("Assignees"), strings.Join(state.Assignees, ", "))
|
||||
fmt.Fprintf(out, "%s: %s\n", cs.Bold("Assignees"), strings.Join(state.Assignees, ", "))
|
||||
}
|
||||
if len(state.Milestones) != 0 {
|
||||
fmt.Fprintf(out, "%s: %s\n", iofmt.Bold("Milestones"), strings.Join(state.Milestones, ", "))
|
||||
fmt.Fprintf(out, "%s: %s\n", cs.Bold("Milestones"), strings.Join(state.Milestones, ", "))
|
||||
}
|
||||
if len(state.Projects) != 0 {
|
||||
fmt.Fprintf(out, "%s: %s\n", iofmt.Bold("Projects"), strings.Join(state.Projects, ", "))
|
||||
fmt.Fprintf(out, "%s: %s\n", cs.Bold("Projects"), strings.Join(state.Projects, ", "))
|
||||
}
|
||||
fmt.Fprintf(out, "%s: %t\n", iofmt.Bold("MaintainerCanModify"), params["maintainerCanModify"])
|
||||
fmt.Fprintf(out, "%s: %t\n", cs.Bold("MaintainerCanModify"), params["maintainerCanModify"])
|
||||
|
||||
fmt.Fprintf(out, "%s\n", iofmt.Bold("Body:"))
|
||||
fmt.Fprintf(out, "%s\n", cs.Bold("Body:"))
|
||||
// Body
|
||||
var md string
|
||||
var err error
|
||||
if len(params["body"].(string)) == 0 {
|
||||
md = fmt.Sprintf("%s\n", iofmt.Gray("No description provided"))
|
||||
md = fmt.Sprintf("%s\n", cs.Muted("No description provided"))
|
||||
} else {
|
||||
md, err = markdown.Render(params["body"].(string),
|
||||
markdown.WithTheme(io.TerminalTheme()),
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ func listRun(opts *ListOptions) error {
|
|||
if !isTTY {
|
||||
table.AddField(shared.PrStateWithDraft(&pr))
|
||||
}
|
||||
table.AddTimeField(opts.Now(), pr.CreatedAt, cs.Gray)
|
||||
table.AddTimeField(opts.Now(), pr.CreatedAt, cs.Muted)
|
||||
table.EndRow()
|
||||
}
|
||||
err = table.Render()
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ func reviewRun(opts *ReviewOptions) error {
|
|||
|
||||
switch reviewData.State {
|
||||
case api.ReviewComment:
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Reviewed pull request %s#%d\n", cs.Gray("-"), ghrepo.FullName(baseRepo), pr.Number)
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Reviewed pull request %s#%d\n", cs.Muted("-"), ghrepo.FullName(baseRepo), pr.Number)
|
||||
case api.ReviewApprove:
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s Approved pull request %s#%d\n", cs.SuccessIcon(), ghrepo.FullName(baseRepo), pr.Number)
|
||||
case api.ReviewRequestChanges:
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ func CommentList(io *iostreams.IOStreams, comments api.Comments, reviews api.Pul
|
|||
hiddenCount := totalCount - retrievedCount
|
||||
|
||||
if preview && hiddenCount > 0 {
|
||||
fmt.Fprint(&b, cs.Gray(fmt.Sprintf("———————— Not showing %s ————————", text.Pluralize(hiddenCount, "comment"))))
|
||||
fmt.Fprint(&b, cs.Muted(fmt.Sprintf("———————— Not showing %s ————————", text.Pluralize(hiddenCount, "comment"))))
|
||||
fmt.Fprintf(&b, "\n\n\n")
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ func CommentList(io *iostreams.IOStreams, comments api.Comments, reviews api.Pul
|
|||
}
|
||||
|
||||
if preview && hiddenCount > 0 {
|
||||
fmt.Fprint(&b, cs.Gray("Use --comments to view the full conversation"))
|
||||
fmt.Fprint(&b, cs.Muted("Use --comments to view the full conversation"))
|
||||
fmt.Fprintln(&b)
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ func formatComment(io *iostreams.IOStreams, comment Comment, newest bool) (strin
|
|||
var md string
|
||||
var err error
|
||||
if comment.Content() == "" {
|
||||
md = fmt.Sprintf("\n %s\n\n", cs.Gray("No body provided"))
|
||||
md = fmt.Sprintf("\n %s\n\n", cs.Muted("No body provided"))
|
||||
} else {
|
||||
md, err = markdown.Render(comment.Content(),
|
||||
markdown.WithTheme(io.TerminalTheme()),
|
||||
|
|
@ -135,7 +135,7 @@ func formatComment(io *iostreams.IOStreams, comment Comment, newest bool) (strin
|
|||
|
||||
// Footer
|
||||
if comment.Link() != "" {
|
||||
fmt.Fprintf(&b, cs.Gray("View the full review: %s\n\n"), comment.Link())
|
||||
fmt.Fprintf(&b, cs.Muted("View the full review: %s\n\n"), comment.Link())
|
||||
}
|
||||
|
||||
return b.String(), nil
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ func PrintHeader(io *iostreams.IOStreams, s string) {
|
|||
}
|
||||
|
||||
func PrintMessage(io *iostreams.IOStreams, s string) {
|
||||
fmt.Fprintln(io.Out, io.ColorScheme().Gray(s))
|
||||
fmt.Fprintln(io.Out, io.ColorScheme().Muted(s))
|
||||
}
|
||||
|
||||
func ListNoResults(repoName string, itemName string, hasFilters bool) error {
|
||||
|
|
@ -83,7 +83,7 @@ func ListHeader(repoName string, itemName string, matchCount int, totalMatchCoun
|
|||
}
|
||||
|
||||
func PrCheckStatusSummaryWithColor(cs *iostreams.ColorScheme, checks api.PullRequestChecksStatus) string {
|
||||
var summary = cs.Gray("No checks")
|
||||
var summary = cs.Muted("No checks")
|
||||
if checks.Total > 0 {
|
||||
if checks.Failing > 0 {
|
||||
if checks.Failing == checks.Total {
|
||||
|
|
|
|||
|
|
@ -316,6 +316,6 @@ func printPrs(io *iostreams.IOStreams, totalCount int, prs ...api.PullRequest) {
|
|||
}
|
||||
remaining := totalCount - len(prs)
|
||||
if remaining > 0 {
|
||||
fmt.Fprintf(w, cs.Gray(" And %d more\n"), remaining)
|
||||
fmt.Fprintln(w, cs.Mutedf(" And %d more", remaining))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ func printHumanPrPreview(opts *ViewOptions, baseRepo ghrepo.Interface, pr *api.P
|
|||
var md string
|
||||
var err error
|
||||
if pr.Body == "" {
|
||||
md = fmt.Sprintf("\n %s\n\n", cs.Gray("No description provided"))
|
||||
md = fmt.Sprintf("\n %s\n\n", cs.Muted("No description provided"))
|
||||
} else {
|
||||
md, err = markdown.Render(pr.Body,
|
||||
markdown.WithTheme(opts.IO.TerminalTheme()),
|
||||
|
|
@ -282,7 +282,7 @@ func printHumanPrPreview(opts *ViewOptions, baseRepo ghrepo.Interface, pr *api.P
|
|||
}
|
||||
|
||||
// Footer
|
||||
fmt.Fprintf(out, cs.Gray("View this pull request on GitHub: %s\n"), pr.URL)
|
||||
fmt.Fprintf(out, cs.Muted("View this pull request on GitHub: %s\n"), pr.URL)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -423,7 +423,7 @@ func prLabelList(pr api.PullRequest, cs *iostreams.ColorScheme) string {
|
|||
|
||||
labelNames := make([]string, 0, len(pr.Labels.Nodes))
|
||||
for _, label := range pr.Labels.Nodes {
|
||||
labelNames = append(labelNames, cs.HexToRGB(label.Color, label.Name))
|
||||
labelNames = append(labelNames, cs.Label(label.Color, label.Name))
|
||||
}
|
||||
|
||||
list := strings.Join(labelNames, ", ")
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ func listRun(opts *ListOptions) error {
|
|||
}
|
||||
|
||||
table := tableprinter.New(opts.IO, tableprinter.WithHeader("Title", "Type", "Tag name", "Published"))
|
||||
iofmt := opts.IO.ColorScheme()
|
||||
cs := opts.IO.ColorScheme()
|
||||
for _, rel := range releases {
|
||||
title := text.RemoveExcessiveWhitespace(rel.Name)
|
||||
if title == "" {
|
||||
|
|
@ -100,13 +100,13 @@ func listRun(opts *ListOptions) error {
|
|||
var badgeColor func(string) string
|
||||
if rel.IsLatest {
|
||||
badge = "Latest"
|
||||
badgeColor = iofmt.Green
|
||||
badgeColor = cs.Green
|
||||
} else if rel.IsDraft {
|
||||
badge = "Draft"
|
||||
badgeColor = iofmt.Red
|
||||
badgeColor = cs.Red
|
||||
} else if rel.IsPrerelease {
|
||||
badge = "Pre-release"
|
||||
badgeColor = iofmt.Yellow
|
||||
badgeColor = cs.Yellow
|
||||
}
|
||||
table.AddField(badge, tableprinter.WithColor(badgeColor))
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ func listRun(opts *ListOptions) error {
|
|||
if rel.PublishedAt.IsZero() {
|
||||
pubDate = rel.CreatedAt
|
||||
}
|
||||
table.AddTimeField(time.Now(), pubDate, iofmt.Gray)
|
||||
table.AddTimeField(time.Now(), pubDate, cs.Muted)
|
||||
table.EndRow()
|
||||
}
|
||||
err = table.Render()
|
||||
|
|
|
|||
|
|
@ -129,19 +129,19 @@ func viewRun(opts *ViewOptions) error {
|
|||
}
|
||||
|
||||
func renderReleaseTTY(io *iostreams.IOStreams, release *shared.Release) error {
|
||||
iofmt := io.ColorScheme()
|
||||
cs := io.ColorScheme()
|
||||
w := io.Out
|
||||
|
||||
fmt.Fprintf(w, "%s\n", iofmt.Bold(release.TagName))
|
||||
fmt.Fprintf(w, "%s\n", cs.Bold(release.TagName))
|
||||
if release.IsDraft {
|
||||
fmt.Fprintf(w, "%s • ", iofmt.Red("Draft"))
|
||||
fmt.Fprintf(w, "%s • ", cs.Red("Draft"))
|
||||
} else if release.IsPrerelease {
|
||||
fmt.Fprintf(w, "%s • ", iofmt.Yellow("Pre-release"))
|
||||
fmt.Fprintf(w, "%s • ", cs.Yellow("Pre-release"))
|
||||
}
|
||||
if release.IsDraft {
|
||||
fmt.Fprintf(w, "%s\n", iofmt.Gray(fmt.Sprintf("%s created this %s", release.Author.Login, text.FuzzyAgo(time.Now(), release.CreatedAt))))
|
||||
fmt.Fprintln(w, cs.Mutedf("%s created this %s", release.Author.Login, text.FuzzyAgo(time.Now(), release.CreatedAt)))
|
||||
} else {
|
||||
fmt.Fprintf(w, "%s\n", iofmt.Gray(fmt.Sprintf("%s released this %s", release.Author.Login, text.FuzzyAgo(time.Now(), *release.PublishedAt))))
|
||||
fmt.Fprintln(w, cs.Mutedf("%s released this %s", release.Author.Login, text.FuzzyAgo(time.Now(), *release.PublishedAt)))
|
||||
}
|
||||
|
||||
renderedDescription, err := markdown.Render(release.Body,
|
||||
|
|
@ -153,7 +153,7 @@ func renderReleaseTTY(io *iostreams.IOStreams, release *shared.Release) error {
|
|||
fmt.Fprintln(w, renderedDescription)
|
||||
|
||||
if len(release.Assets) > 0 {
|
||||
fmt.Fprintf(w, "%s\n", iofmt.Bold("Assets"))
|
||||
fmt.Fprintln(w, cs.Bold("Assets"))
|
||||
//nolint:staticcheck // SA1019: Showing NAME|SIZE headers adds nothing to table.
|
||||
table := tableprinter.New(io, tableprinter.NoHeader)
|
||||
for _, a := range release.Assets {
|
||||
|
|
@ -168,7 +168,7 @@ func renderReleaseTTY(io *iostreams.IOStreams, release *shared.Release) error {
|
|||
fmt.Fprint(w, "\n")
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "%s\n", iofmt.Gray(fmt.Sprintf("View on GitHub: %s", release.URL)))
|
||||
fmt.Fprintln(w, cs.Mutedf("View on GitHub: %s", release.URL))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ func listRun(opts *ListOptions) error {
|
|||
}
|
||||
t.AddField(sshType)
|
||||
t.AddField(deployKey.Key, tableprinter.WithTruncate(truncateMiddle))
|
||||
t.AddTimeField(now, deployKey.CreatedAt, cs.Gray)
|
||||
t.AddTimeField(now, deployKey.CreatedAt, cs.Muted)
|
||||
t.EndRow()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,9 +119,9 @@ func renderLicense(license *api.License, opts *ViewOptions) error {
|
|||
cs := opts.IO.ColorScheme()
|
||||
var out strings.Builder
|
||||
if opts.IO.IsStdoutTTY() {
|
||||
out.WriteString(fmt.Sprintf("\n%s\n", cs.Gray(license.Description)))
|
||||
out.WriteString(fmt.Sprintf("\n%s\n", cs.Grayf("To implement: %s", license.Implementation)))
|
||||
out.WriteString(fmt.Sprintf("\n%s\n\n", cs.Grayf("For more information, see: %s", license.HTMLURL)))
|
||||
out.WriteString(fmt.Sprintf("\n%s\n", cs.Muted(license.Description)))
|
||||
out.WriteString(fmt.Sprintf("\n%s\n", cs.Mutedf("To implement: %s", license.Implementation)))
|
||||
out.WriteString(fmt.Sprintf("\n%s\n\n", cs.Mutedf("For more information, see: %s", license.HTMLURL)))
|
||||
}
|
||||
out.WriteString(license.Body)
|
||||
_, err := opts.IO.Out.Write([]byte(out.String()))
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ func listRun(opts *ListOptions) error {
|
|||
totalMatchCount := len(listResult.Repositories)
|
||||
for _, repo := range listResult.Repositories {
|
||||
info := repoInfo(repo)
|
||||
infoColor := cs.Gray
|
||||
infoColor := cs.Muted
|
||||
|
||||
if repo.IsPrivate {
|
||||
infoColor = cs.Yellow
|
||||
|
|
@ -195,7 +195,7 @@ func listRun(opts *ListOptions) error {
|
|||
tp.AddField(repo.NameWithOwner, tableprinter.WithColor(cs.Bold))
|
||||
tp.AddField(text.RemoveExcessiveWhitespace(repo.Description))
|
||||
tp.AddField(info, tableprinter.WithColor(infoColor))
|
||||
tp.AddTimeField(opts.Now(), *t, cs.Gray)
|
||||
tp.AddTimeField(opts.Now(), *t, cs.Muted)
|
||||
tp.EndRow()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ func viewRun(opts *ViewOptions) error {
|
|||
|
||||
var readmeContent string
|
||||
if readme == nil {
|
||||
readmeContent = cs.Gray("This repository does not have a README")
|
||||
readmeContent = cs.Muted("This repository does not have a README")
|
||||
} else if isMarkdownFile(readme.Filename) {
|
||||
var err error
|
||||
readmeContent, err = markdown.Render(readme.Content,
|
||||
|
|
@ -197,7 +197,7 @@ func viewRun(opts *ViewOptions) error {
|
|||
|
||||
description := repo.Description
|
||||
if description == "" {
|
||||
description = cs.Gray("No description provided")
|
||||
description = cs.Muted("No description provided")
|
||||
}
|
||||
|
||||
repoData := struct {
|
||||
|
|
@ -209,7 +209,7 @@ func viewRun(opts *ViewOptions) error {
|
|||
FullName: cs.Bold(fullName),
|
||||
Description: description,
|
||||
Readme: readmeContent,
|
||||
View: cs.Gray(fmt.Sprintf("View this repository on GitHub: %s", openURL)),
|
||||
View: cs.Mutedf("View this repository on GitHub: %s", openURL),
|
||||
}
|
||||
|
||||
return tmpl.Execute(stdout, repoData)
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ func isRootCmd(command *cobra.Command) bool {
|
|||
return command != nil && !command.HasParent()
|
||||
}
|
||||
|
||||
func rootHelpFunc(f *cmdutil.Factory, command *cobra.Command, args []string) {
|
||||
func rootHelpFunc(f *cmdutil.Factory, command *cobra.Command, _ []string) {
|
||||
flags := command.Flags()
|
||||
|
||||
if isRootCmd(command) {
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@ var HelpTopics = []helpTopic{
|
|||
%[1]sCLICOLOR_FORCE%[1]s: set to a value other than %[1]s0%[1]s to keep ANSI colors in output
|
||||
even when the output is piped.
|
||||
|
||||
%[1]sGH_COLOR_LABELS%[1]s: set to any value to display labels using their RGB hex color codes in terminals that
|
||||
support truecolor.
|
||||
|
||||
%[1]sGH_FORCE_TTY%[1]s: set to any value to force terminal-style output even when the output is
|
||||
redirected. When the value is a number, it is interpreted as the number of columns
|
||||
available in the viewport. When the value is a percentage, it will be applied against
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ func listRun(opts *ListOptions) error {
|
|||
tp.AddField(string(run.Event))
|
||||
tp.AddField(fmt.Sprintf("%d", run.ID), tableprinter.WithColor(cs.Cyan))
|
||||
tp.AddField(run.Duration(opts.now).String())
|
||||
tp.AddTimeField(opts.now, run.StartedTime(), cs.Gray)
|
||||
tp.AddTimeField(opts.now, run.StartedTime(), cs.Muted)
|
||||
tp.EndRow()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ func RenderAnnotations(cs *iostreams.ColorScheme, annotations []Annotation) stri
|
|||
|
||||
for _, a := range annotations {
|
||||
lines = append(lines, fmt.Sprintf("%s %s", AnnotationSymbol(cs, a), a.Message))
|
||||
lines = append(lines, cs.Grayf("%s: %s#%d\n", a.JobName, a.Path, a.StartLine))
|
||||
// Following newline is essential for spacing between annotations
|
||||
lines = append(lines, cs.Mutedf("%s: %s#%d\n", a.JobName, a.Path, a.StartLine))
|
||||
}
|
||||
|
||||
return strings.Join(lines, "\n")
|
||||
|
|
|
|||
|
|
@ -575,7 +575,7 @@ func Symbol(cs *iostreams.ColorScheme, status Status, conclusion Conclusion) (st
|
|||
case Success:
|
||||
return cs.SuccessIconWithColor(noColor), cs.Green
|
||||
case Skipped, Neutral:
|
||||
return "-", cs.Gray
|
||||
return "-", cs.Muted
|
||||
default:
|
||||
return cs.FailureIconWithColor(noColor), cs.Red
|
||||
}
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ func runView(opts *ViewOptions) error {
|
|||
for _, a := range artifacts {
|
||||
expiredBadge := ""
|
||||
if a.Expired {
|
||||
expiredBadge = cs.Gray(" (expired)")
|
||||
expiredBadge = cs.Muted(" (expired)")
|
||||
}
|
||||
fmt.Fprintf(out, "%s%s\n", a.Name, expiredBadge)
|
||||
}
|
||||
|
|
@ -411,7 +411,7 @@ func runView(opts *ViewOptions) error {
|
|||
} else {
|
||||
fmt.Fprintf(out, "For more information about a job, try: gh run view --job=<job-id>\n")
|
||||
}
|
||||
fmt.Fprintf(out, cs.Gray("View this run on GitHub: %s\n"), run.URL)
|
||||
fmt.Fprintln(out, cs.Mutedf("View this run on GitHub: %s", run.URL))
|
||||
|
||||
if opts.ExitStatus && shared.IsFailureState(run.Conclusion) {
|
||||
return cmdutil.SilentError
|
||||
|
|
@ -423,7 +423,7 @@ func runView(opts *ViewOptions) error {
|
|||
} else {
|
||||
fmt.Fprintf(out, "To see the full job log, try: gh run view --log --job=%d\n", selectedJob.ID)
|
||||
}
|
||||
fmt.Fprintf(out, cs.Gray("View this run on GitHub: %s\n"), run.URL)
|
||||
fmt.Fprintln(out, cs.Mutedf("View this run on GitHub: %s", run.URL))
|
||||
|
||||
if opts.ExitStatus && shared.IsFailureState(selectedJob.Conclusion) {
|
||||
return cmdutil.SilentError
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ func displayResults(io *iostreams.IOStreams, now time.Time, results search.Commi
|
|||
tp.AddField(commit.Sha)
|
||||
tp.AddField(text.RemoveExcessiveWhitespace(commit.Info.Message))
|
||||
tp.AddField(commit.Author.Login)
|
||||
tp.AddTimeField(now, commit.Info.Author.Date, cs.Gray)
|
||||
tp.AddTimeField(now, commit.Info.Author.Date, cs.Muted)
|
||||
tp.EndRow()
|
||||
}
|
||||
if io.IsStdoutTTY() {
|
||||
|
|
|
|||
|
|
@ -171,14 +171,14 @@ func displayResults(io *iostreams.IOStreams, now time.Time, results search.Repos
|
|||
tags = append(tags, "archived")
|
||||
}
|
||||
info := strings.Join(tags, ", ")
|
||||
infoColor := cs.Gray
|
||||
infoColor := cs.Muted
|
||||
if repo.IsPrivate {
|
||||
infoColor = cs.Yellow
|
||||
}
|
||||
tp.AddField(repo.FullName, tableprinter.WithColor(cs.Bold))
|
||||
tp.AddField(text.RemoveExcessiveWhitespace(repo.Description))
|
||||
tp.AddField(info, tableprinter.WithColor(infoColor))
|
||||
tp.AddTimeField(now, repo.UpdatedAt, cs.Gray)
|
||||
tp.AddTimeField(now, repo.UpdatedAt, cs.Muted)
|
||||
tp.EndRow()
|
||||
}
|
||||
if io.IsStdoutTTY() {
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ func displayIssueResults(io *iostreams.IOStreams, now time.Time, et EntityType,
|
|||
}
|
||||
tp.AddField(text.RemoveExcessiveWhitespace(issue.Title))
|
||||
tp.AddField(listIssueLabels(&issue, cs, tp.IsTTY()))
|
||||
tp.AddTimeField(now, issue.UpdatedAt, cs.Gray)
|
||||
tp.AddTimeField(now, issue.UpdatedAt, cs.Muted)
|
||||
tp.EndRow()
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ func listIssueLabels(issue *search.Issue, cs *iostreams.ColorScheme, colorize bo
|
|||
labelNames := make([]string, 0, len(issue.Labels))
|
||||
for _, label := range issue.Labels {
|
||||
if colorize {
|
||||
labelNames = append(labelNames, cs.HexToRGB(label.Color, label.Name))
|
||||
labelNames = append(labelNames, cs.Label(label.Color, label.Name))
|
||||
} else {
|
||||
labelNames = append(labelNames, label.Name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,11 +89,11 @@ func listRun(opts *ListOptions) error {
|
|||
t.AddField(id)
|
||||
t.AddField(sshKey.Key, tableprinter.WithTruncate(truncateMiddle))
|
||||
t.AddField(sshKey.Type)
|
||||
t.AddTimeField(now, sshKey.CreatedAt, cs.Gray)
|
||||
t.AddTimeField(now, sshKey.CreatedAt, cs.Muted)
|
||||
} else {
|
||||
t.AddField(sshKey.Title)
|
||||
t.AddField(sshKey.Key)
|
||||
t.AddTimeField(now, sshKey.CreatedAt, cs.Gray)
|
||||
t.AddTimeField(now, sshKey.CreatedAt, cs.Muted)
|
||||
t.AddField(id)
|
||||
t.AddField(sshKey.Type)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -740,7 +740,7 @@ func statusRun(opts *StatusOptions) error {
|
|||
errs := sg.authErrors.ToSlice()
|
||||
sort.Strings(errs)
|
||||
for _, msg := range errs {
|
||||
fmt.Fprintln(out, cs.Gray(fmt.Sprintf("warning: %s", msg)))
|
||||
fmt.Fprintln(out, cs.Mutedf("warning: %s", msg))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ func viewWorkflowContent(opts *ViewOptions, client *api.Client, repo ghrepo.Inte
|
|||
out := opts.IO.Out
|
||||
|
||||
fileName := workflow.Base()
|
||||
fmt.Fprintf(out, "%s - %s\n", cs.Bold(workflow.Name), cs.Gray(fileName))
|
||||
fmt.Fprintf(out, "%s - %s\n", cs.Bold(workflow.Name), cs.Muted(fileName))
|
||||
fmt.Fprintf(out, "ID: %s", cs.Cyanf("%d", workflow.ID))
|
||||
|
||||
codeBlock := fmt.Sprintf("```yaml\n%s\n```", yaml)
|
||||
|
|
|
|||
|
|
@ -30,40 +30,35 @@ var (
|
|||
greenBold = ansi.ColorFunc("green+b")
|
||||
highlightStart = ansi.ColorCode(highlightStyle)
|
||||
highlight = ansi.ColorFunc(highlightStyle)
|
||||
darkThemeMuted = ansi.ColorFunc("white+d")
|
||||
darkThemeTableHeader = ansi.ColorFunc("white+du")
|
||||
lightThemeMuted = ansi.ColorFunc("black+h")
|
||||
lightThemeTableHeader = ansi.ColorFunc("black+hu")
|
||||
noThemeTableHeader = ansi.ColorFunc("default+u")
|
||||
|
||||
gray256 = func(t string) string {
|
||||
return fmt.Sprintf("\x1b[%d;5;%dm%s\x1b[m", 38, 242, t)
|
||||
return fmt.Sprintf("\x1b[%d;5;%dm%s\x1b[0m", 38, 242, t)
|
||||
}
|
||||
)
|
||||
|
||||
// NewColorScheme initializes color logic based on provided terminal capabilities.
|
||||
// Logic dealing with terminal theme detected, such as whether color is enabled, 8-bit color supported, true color supported,
|
||||
// and terminal theme detected.
|
||||
func NewColorScheme(enabled, is256enabled, trueColor bool, theme string) *ColorScheme {
|
||||
return &ColorScheme{
|
||||
enabled: enabled,
|
||||
is256enabled: is256enabled,
|
||||
hasTrueColor: trueColor,
|
||||
theme: theme,
|
||||
}
|
||||
}
|
||||
|
||||
// ColorScheme controls how text is colored based upon terminal capabilities and user preferences.
|
||||
type ColorScheme struct {
|
||||
enabled bool
|
||||
is256enabled bool
|
||||
hasTrueColor bool
|
||||
theme string
|
||||
}
|
||||
|
||||
func (c *ColorScheme) Enabled() bool {
|
||||
return c.enabled
|
||||
// Enabled is whether color is used at all.
|
||||
Enabled bool
|
||||
// EightBitColor is whether the terminal supports 8-bit, 256 colors.
|
||||
EightBitColor bool
|
||||
// TrueColor is whether the terminal supports 24-bit, 16 million colors.
|
||||
TrueColor bool
|
||||
// Accessible is whether colors must be base 16 colors that users can customize in terminal preferences.
|
||||
Accessible bool
|
||||
// ColorLabels is whether labels are colored based on their truecolor RGB hex color.
|
||||
ColorLabels bool
|
||||
// Theme is the terminal background color theme used to contextually color text for light, dark, or none at all.
|
||||
Theme string
|
||||
}
|
||||
|
||||
func (c *ColorScheme) Bold(t string) string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
return bold(t)
|
||||
|
|
@ -73,8 +68,33 @@ func (c *ColorScheme) Boldf(t string, args ...interface{}) string {
|
|||
return c.Bold(fmt.Sprintf(t, args...))
|
||||
}
|
||||
|
||||
func (c *ColorScheme) Muted(t string) string {
|
||||
// Fallback to previous logic if accessible colors preview is disabled.
|
||||
if !c.Accessible {
|
||||
return c.Gray(t)
|
||||
}
|
||||
|
||||
// Muted text is only stylized if color is enabled.
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
|
||||
switch c.Theme {
|
||||
case LightTheme:
|
||||
return lightThemeMuted(t)
|
||||
case DarkTheme:
|
||||
return darkThemeMuted(t)
|
||||
default:
|
||||
return t
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ColorScheme) Mutedf(t string, args ...interface{}) string {
|
||||
return c.Muted(fmt.Sprintf(t, args...))
|
||||
}
|
||||
|
||||
func (c *ColorScheme) Red(t string) string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
return red(t)
|
||||
|
|
@ -85,7 +105,7 @@ func (c *ColorScheme) Redf(t string, args ...interface{}) string {
|
|||
}
|
||||
|
||||
func (c *ColorScheme) Yellow(t string) string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
return yellow(t)
|
||||
|
|
@ -96,7 +116,7 @@ func (c *ColorScheme) Yellowf(t string, args ...interface{}) string {
|
|||
}
|
||||
|
||||
func (c *ColorScheme) Green(t string) string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
return green(t)
|
||||
|
|
@ -107,28 +127,30 @@ func (c *ColorScheme) Greenf(t string, args ...interface{}) string {
|
|||
}
|
||||
|
||||
func (c *ColorScheme) GreenBold(t string) string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
return greenBold(t)
|
||||
}
|
||||
|
||||
// Deprecated: Use Muted instead for thematically contrasting color.
|
||||
func (c *ColorScheme) Gray(t string) string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
if c.is256enabled {
|
||||
if c.EightBitColor {
|
||||
return gray256(t)
|
||||
}
|
||||
return gray(t)
|
||||
}
|
||||
|
||||
// Deprecated: Use Mutedf instead for thematically contrasting color.
|
||||
func (c *ColorScheme) Grayf(t string, args ...interface{}) string {
|
||||
return c.Gray(fmt.Sprintf(t, args...))
|
||||
}
|
||||
|
||||
func (c *ColorScheme) Magenta(t string) string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
return magenta(t)
|
||||
|
|
@ -139,7 +161,7 @@ func (c *ColorScheme) Magentaf(t string, args ...interface{}) string {
|
|||
}
|
||||
|
||||
func (c *ColorScheme) Cyan(t string) string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
return cyan(t)
|
||||
|
|
@ -150,14 +172,14 @@ func (c *ColorScheme) Cyanf(t string, args ...interface{}) string {
|
|||
}
|
||||
|
||||
func (c *ColorScheme) CyanBold(t string) string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
return cyanBold(t)
|
||||
}
|
||||
|
||||
func (c *ColorScheme) Blue(t string) string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
return blue(t)
|
||||
|
|
@ -188,7 +210,7 @@ func (c *ColorScheme) FailureIconWithColor(colo func(string) string) string {
|
|||
}
|
||||
|
||||
func (c *ColorScheme) HighlightStart() string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +218,7 @@ func (c *ColorScheme) HighlightStart() string {
|
|||
}
|
||||
|
||||
func (c *ColorScheme) Highlight(t string) string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +226,7 @@ func (c *ColorScheme) Highlight(t string) string {
|
|||
}
|
||||
|
||||
func (c *ColorScheme) Reset() string {
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +246,7 @@ func (c *ColorScheme) ColorFromString(s string) func(string) string {
|
|||
case "green":
|
||||
fn = c.Green
|
||||
case "gray":
|
||||
fn = c.Gray
|
||||
fn = c.Muted
|
||||
case "magenta":
|
||||
fn = c.Magenta
|
||||
case "cyan":
|
||||
|
|
@ -240,17 +262,9 @@ func (c *ColorScheme) ColorFromString(s string) func(string) string {
|
|||
return fn
|
||||
}
|
||||
|
||||
// ColorFromRGB returns a function suitable for TablePrinter.AddField
|
||||
// that calls HexToRGB, coloring text if supported by the terminal.
|
||||
func (c *ColorScheme) ColorFromRGB(hex string) func(string) string {
|
||||
return func(s string) string {
|
||||
return c.HexToRGB(hex, s)
|
||||
}
|
||||
}
|
||||
|
||||
// HexToRGB uses the given hex to color x if supported by the terminal.
|
||||
func (c *ColorScheme) HexToRGB(hex string, x string) string {
|
||||
if !c.enabled || !c.hasTrueColor || len(hex) != 6 {
|
||||
// Label stylizes text based on label's RGB hex color.
|
||||
func (c *ColorScheme) Label(hex string, x string) string {
|
||||
if !c.Enabled || !c.TrueColor || !c.ColorLabels || len(hex) != 6 {
|
||||
return x
|
||||
}
|
||||
|
||||
|
|
@ -262,11 +276,11 @@ func (c *ColorScheme) HexToRGB(hex string, x string) string {
|
|||
|
||||
func (c *ColorScheme) TableHeader(t string) string {
|
||||
// Table headers are only stylized if color is enabled including underline modifier.
|
||||
if !c.enabled {
|
||||
if !c.Enabled {
|
||||
return t
|
||||
}
|
||||
|
||||
switch c.theme {
|
||||
switch c.Theme {
|
||||
case DarkTheme:
|
||||
return darkThemeTableHeader(t)
|
||||
case LightTheme:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestColorFromRGB(t *testing.T) {
|
||||
func TestLabel(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
hex string
|
||||
|
|
@ -20,77 +20,57 @@ func TestColorFromRGB(t *testing.T) {
|
|||
hex: "fc0303",
|
||||
text: "red",
|
||||
wants: "\033[38;2;252;3;3mred\033[0m",
|
||||
cs: NewColorScheme(true, true, true, NoTheme),
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
TrueColor: true,
|
||||
ColorLabels: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no truecolor",
|
||||
hex: "fc0303",
|
||||
text: "red",
|
||||
wants: "red",
|
||||
cs: NewColorScheme(true, true, false, NoTheme),
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
ColorLabels: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no color",
|
||||
hex: "fc0303",
|
||||
text: "red",
|
||||
wants: "red",
|
||||
cs: NewColorScheme(false, false, false, NoTheme),
|
||||
cs: &ColorScheme{
|
||||
ColorLabels: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid hex",
|
||||
hex: "fc0",
|
||||
text: "red",
|
||||
wants: "red",
|
||||
cs: NewColorScheme(false, false, false, NoTheme),
|
||||
cs: &ColorScheme{
|
||||
ColorLabels: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no color labels",
|
||||
hex: "fc0303",
|
||||
text: "red",
|
||||
wants: "red",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
ColorLabels: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
fn := tt.cs.ColorFromRGB(tt.hex)
|
||||
assert.Equal(t, tt.wants, fn(tt.text))
|
||||
}
|
||||
}
|
||||
|
||||
func TestHexToRGB(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
hex string
|
||||
text string
|
||||
wants string
|
||||
cs *ColorScheme
|
||||
}{
|
||||
{
|
||||
name: "truecolor",
|
||||
hex: "fc0303",
|
||||
text: "red",
|
||||
wants: "\033[38;2;252;3;3mred\033[0m",
|
||||
cs: NewColorScheme(true, true, true, NoTheme),
|
||||
},
|
||||
{
|
||||
name: "no truecolor",
|
||||
hex: "fc0303",
|
||||
text: "red",
|
||||
wants: "red",
|
||||
cs: NewColorScheme(true, true, false, NoTheme),
|
||||
},
|
||||
{
|
||||
name: "no color",
|
||||
hex: "fc0303",
|
||||
text: "red",
|
||||
wants: "red",
|
||||
cs: NewColorScheme(false, false, false, NoTheme),
|
||||
},
|
||||
{
|
||||
name: "invalid hex",
|
||||
hex: "fc0",
|
||||
text: "red",
|
||||
wants: "red",
|
||||
cs: NewColorScheme(false, false, false, NoTheme),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
output := tt.cs.HexToRGB(tt.hex, tt.text)
|
||||
output := tt.cs.Label(tt.hex, tt.text)
|
||||
assert.Equal(t, tt.wants, output)
|
||||
}
|
||||
}
|
||||
|
|
@ -108,62 +88,110 @@ func TestTableHeader(t *testing.T) {
|
|||
expected string
|
||||
}{
|
||||
{
|
||||
name: "when color is disabled, text is not stylized",
|
||||
cs: NewColorScheme(false, false, false, NoTheme),
|
||||
name: "when color is disabled, text is not stylized",
|
||||
cs: &ColorScheme{
|
||||
Accessible: true,
|
||||
Theme: NoTheme,
|
||||
},
|
||||
input: "this should not be stylized",
|
||||
expected: "this should not be stylized",
|
||||
},
|
||||
{
|
||||
name: "when 4-bit color is enabled but no theme, 4-bit default color and underline are used",
|
||||
cs: NewColorScheme(true, false, false, NoTheme),
|
||||
name: "when 4-bit color is enabled but no theme, 4-bit default color and underline are used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
Accessible: true,
|
||||
Theme: NoTheme,
|
||||
},
|
||||
input: "this should have no explicit color but underlined",
|
||||
expected: fmt.Sprintf("%sthis should have no explicit color but underlined%s", defaultUnderline, reset),
|
||||
},
|
||||
{
|
||||
name: "when 4-bit color is enabled and theme is light, 4-bit dark color and underline are used",
|
||||
cs: NewColorScheme(true, false, false, LightTheme),
|
||||
name: "when 4-bit color is enabled and theme is light, 4-bit dark color and underline are used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
Accessible: true,
|
||||
Theme: LightTheme,
|
||||
},
|
||||
input: "this should have dark foreground color and underlined",
|
||||
expected: fmt.Sprintf("%sthis should have dark foreground color and underlined%s", brightBlackUnderline, reset),
|
||||
},
|
||||
{
|
||||
name: "when 4-bit color is enabled and theme is dark, 4-bit light color and underline are used",
|
||||
cs: NewColorScheme(true, false, false, DarkTheme),
|
||||
name: "when 4-bit color is enabled and theme is dark, 4-bit light color and underline are used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
Accessible: true,
|
||||
Theme: DarkTheme,
|
||||
},
|
||||
input: "this should have light foreground color and underlined",
|
||||
expected: fmt.Sprintf("%sthis should have light foreground color and underlined%s", dimBlackUnderline, reset),
|
||||
},
|
||||
{
|
||||
name: "when 8-bit color is enabled but no theme, 4-bit default color and underline are used",
|
||||
cs: NewColorScheme(true, true, false, NoTheme),
|
||||
name: "when 8-bit color is enabled but no theme, 4-bit default color and underline are used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
Accessible: true,
|
||||
Theme: NoTheme,
|
||||
},
|
||||
input: "this should have no explicit color but underlined",
|
||||
expected: fmt.Sprintf("%sthis should have no explicit color but underlined%s", defaultUnderline, reset),
|
||||
},
|
||||
{
|
||||
name: "when 8-bit color is enabled and theme is light, 4-bit dark color and underline are used",
|
||||
cs: NewColorScheme(true, true, false, LightTheme),
|
||||
name: "when 8-bit color is enabled and theme is light, 4-bit dark color and underline are used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
Accessible: true,
|
||||
Theme: LightTheme,
|
||||
},
|
||||
input: "this should have dark foreground color and underlined",
|
||||
expected: fmt.Sprintf("%sthis should have dark foreground color and underlined%s", brightBlackUnderline, reset),
|
||||
},
|
||||
{
|
||||
name: "when 8-bit color is true and theme is dark, 4-bit light color and underline are used",
|
||||
cs: NewColorScheme(true, true, false, DarkTheme),
|
||||
name: "when 8-bit color is true and theme is dark, 4-bit light color and underline are used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
Accessible: true,
|
||||
Theme: DarkTheme,
|
||||
},
|
||||
input: "this should have light foreground color and underlined",
|
||||
expected: fmt.Sprintf("%sthis should have light foreground color and underlined%s", dimBlackUnderline, reset),
|
||||
},
|
||||
{
|
||||
name: "when 24-bit color is enabled but no theme, 4-bit default color and underline are used",
|
||||
cs: NewColorScheme(true, true, true, NoTheme),
|
||||
name: "when 24-bit color is enabled but no theme, 4-bit default color and underline are used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
TrueColor: true,
|
||||
Accessible: true,
|
||||
Theme: NoTheme,
|
||||
},
|
||||
input: "this should have no explicit color but underlined",
|
||||
expected: fmt.Sprintf("%sthis should have no explicit color but underlined%s", defaultUnderline, reset),
|
||||
},
|
||||
{
|
||||
name: "when 24-bit color is enabled and theme is light, 4-bit dark color and underline are used",
|
||||
cs: NewColorScheme(true, true, true, LightTheme),
|
||||
name: "when 24-bit color is enabled and theme is light, 4-bit dark color and underline are used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
TrueColor: true,
|
||||
Accessible: true,
|
||||
Theme: LightTheme,
|
||||
},
|
||||
input: "this should have dark foreground color and underlined",
|
||||
expected: fmt.Sprintf("%sthis should have dark foreground color and underlined%s", brightBlackUnderline, reset),
|
||||
},
|
||||
{
|
||||
name: "when 24-bit color is true and theme is dark, 4-bit light color and underline are used",
|
||||
cs: NewColorScheme(true, true, true, DarkTheme),
|
||||
name: "when 24-bit color is true and theme is dark, 4-bit light color and underline are used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
TrueColor: true,
|
||||
Accessible: true,
|
||||
Theme: DarkTheme,
|
||||
},
|
||||
input: "this should have light foreground color and underlined",
|
||||
expected: fmt.Sprintf("%sthis should have light foreground color and underlined%s", dimBlackUnderline, reset),
|
||||
},
|
||||
|
|
@ -175,3 +203,94 @@ func TestTableHeader(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMuted(t *testing.T) {
|
||||
reset := "\x1b[0m"
|
||||
gray4bit := "\x1b[0;90m"
|
||||
gray8bit := "\x1b[38;5;242m"
|
||||
brightBlack4bit := "\x1b[0;90m"
|
||||
dimBlack4bit := "\x1b[0;2;37m"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
cs *ColorScheme
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "when color is disabled but accessible colors are disabled, text is not stylized",
|
||||
cs: &ColorScheme{},
|
||||
input: "this should not be stylized",
|
||||
expected: "this should not be stylized",
|
||||
},
|
||||
{
|
||||
name: "when 4-bit color is enabled but accessible colors are disabled, legacy 4-bit gray color is used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
},
|
||||
input: "this should be 4-bit gray",
|
||||
expected: fmt.Sprintf("%sthis should be 4-bit gray%s", gray4bit, reset),
|
||||
},
|
||||
{
|
||||
name: "when 8-bit color is enabled but accessible colors are disabled, legacy 8-bit gray color is used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
},
|
||||
input: "this should be 8-bit gray",
|
||||
expected: fmt.Sprintf("%sthis should be 8-bit gray%s", gray8bit, reset),
|
||||
},
|
||||
{
|
||||
name: "when 24-bit color is enabled but accessible colors are disabled, legacy 8-bit gray color is used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
TrueColor: true,
|
||||
},
|
||||
input: "this should be 8-bit gray",
|
||||
expected: fmt.Sprintf("%sthis should be 8-bit gray%s", gray8bit, reset),
|
||||
},
|
||||
{
|
||||
name: "when 4-bit color is enabled and theme is dark, 4-bit light color is used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
TrueColor: true,
|
||||
Accessible: true,
|
||||
Theme: DarkTheme,
|
||||
},
|
||||
input: "this should be 4-bit dim black",
|
||||
expected: fmt.Sprintf("%sthis should be 4-bit dim black%s", dimBlack4bit, reset),
|
||||
},
|
||||
{
|
||||
name: "when 4-bit color is enabled and theme is light, 4-bit dark color is used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
TrueColor: true,
|
||||
Accessible: true,
|
||||
Theme: LightTheme,
|
||||
},
|
||||
input: "this should be 4-bit bright black",
|
||||
expected: fmt.Sprintf("%sthis should be 4-bit bright black%s", brightBlack4bit, reset),
|
||||
},
|
||||
{
|
||||
name: "when 4-bit color is enabled but no theme, 4-bit default color is used",
|
||||
cs: &ColorScheme{
|
||||
Enabled: true,
|
||||
EightBitColor: true,
|
||||
TrueColor: true,
|
||||
Accessible: true,
|
||||
Theme: NoTheme,
|
||||
},
|
||||
input: "this should have no explicit color",
|
||||
expected: "this should have no explicit color",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, tt.cs.Muted(tt.input))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ package iostreams
|
|||
|
||||
import "os"
|
||||
|
||||
func hasAlternateScreenBuffer(hasTrueColor bool) bool {
|
||||
func hasAlternateScreenBuffer(_ bool) bool {
|
||||
// on non-Windows, we just assume that alternate screen buffer is supported in most cases
|
||||
return os.Getenv("TERM") != "dumb"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,8 +70,10 @@ type IOStreams struct {
|
|||
stderrTTYOverride bool
|
||||
stderrIsTTY bool
|
||||
|
||||
colorOverride bool
|
||||
colorEnabled bool
|
||||
colorOverride bool
|
||||
colorEnabled bool
|
||||
colorLabels bool
|
||||
accessibleColorsEnabled bool
|
||||
|
||||
pagerCommand string
|
||||
pagerProcess *os.Process
|
||||
|
|
@ -102,6 +104,10 @@ func (s *IOStreams) HasTrueColor() bool {
|
|||
return s.term.IsTrueColorSupported()
|
||||
}
|
||||
|
||||
func (s *IOStreams) ColorLabels() bool {
|
||||
return s.colorLabels
|
||||
}
|
||||
|
||||
// DetectTerminalTheme is a utility to call before starting the output pager so that the terminal background
|
||||
// can be reliably detected.
|
||||
func (s *IOStreams) DetectTerminalTheme() {
|
||||
|
|
@ -134,6 +140,10 @@ func (s *IOStreams) SetColorEnabled(colorEnabled bool) {
|
|||
s.colorEnabled = colorEnabled
|
||||
}
|
||||
|
||||
func (s *IOStreams) SetColorLabels(colorLabels bool) {
|
||||
s.colorLabels = colorLabels
|
||||
}
|
||||
|
||||
func (s *IOStreams) SetStdinTTY(isTTY bool) {
|
||||
s.stdinTTYOverride = true
|
||||
s.stdinIsTTY = isTTY
|
||||
|
|
@ -366,7 +376,14 @@ func (s *IOStreams) TerminalWidth() int {
|
|||
}
|
||||
|
||||
func (s *IOStreams) ColorScheme() *ColorScheme {
|
||||
return NewColorScheme(s.ColorEnabled(), s.ColorSupport256(), s.HasTrueColor(), s.TerminalTheme())
|
||||
return &ColorScheme{
|
||||
Enabled: s.ColorEnabled(),
|
||||
EightBitColor: s.ColorSupport256(),
|
||||
TrueColor: s.HasTrueColor(),
|
||||
Accessible: s.AccessibleColorsEnabled(),
|
||||
ColorLabels: s.ColorLabels(),
|
||||
Theme: s.TerminalTheme(),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IOStreams) ReadUserFile(fn string) ([]byte, error) {
|
||||
|
|
@ -391,6 +408,14 @@ func (s *IOStreams) TempFile(dir, pattern string) (*os.File, error) {
|
|||
return os.CreateTemp(dir, pattern)
|
||||
}
|
||||
|
||||
func (s *IOStreams) SetAccessibleColorsEnabled(enabled bool) {
|
||||
s.accessibleColorsEnabled = enabled
|
||||
}
|
||||
|
||||
func (s *IOStreams) AccessibleColorsEnabled() bool {
|
||||
return s.accessibleColorsEnabled
|
||||
}
|
||||
|
||||
func System() *IOStreams {
|
||||
terminal := ghTerm.FromEnv()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue