diff --git a/.github/scripts/test-summary.sh b/.github/scripts/test-summary.sh new file mode 100755 index 00000000..ba8b1124 --- /dev/null +++ b/.github/scripts/test-summary.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# test-summary.sh +# +# Post-run command for gotestsum (--post-run-command). +# Called automatically after all test runs and reruns complete. +# +# Responsibilities: +# 1. Detect flaky tests: tests that failed at least once but ultimately passed +# on rerun. These are identified by having both "fail" and "pass" actions +# for the same test name in the JSON output. +# 2. Expose outputs to subsequent GitHub Actions steps via $GITHUB_OUTPUT: +# - has_flaky: "true" if any flaky tests were detected, "false" otherwise +# - flaky_count: number of flaky tests +# 3. Append a summary to the GitHub Actions job summary ($GITHUB_STEP_SUMMARY). +# +# Environment variables provided by gotestsum: +# GOTESTSUM_JSONFILE path to the JSON file with all test events (test2json format) +# TESTS_FAILED number of tests that ultimately failed +# TESTS_TOTAL total number of tests run +# GOTESTSUM_ELAPSED total elapsed time (e.g. "12.34s") + +set -eo pipefail + +# Extract names of flaky tests: those that appear with both a "fail" and a "pass" +# action. These passed only after being rerun, making them flaky. +FLAKY_NAMES=$(jq -rs '[ + [.[] | select(.Test != null)] | + group_by(.Test)[] | + select(any(.[]; .Action == "fail") and any(.[]; .Action == "pass")) | + "- `\(.[0].Package)/\(.[0].Test)`" +] | join("\n")' "$GOTESTSUM_JSONFILE") + +FLAKY=$(echo "$FLAKY_NAMES" | grep -c "^-" || true) + +# Determine the overall status line based on final failure count. +if [ "$TESTS_FAILED" -gt 0 ]; then + STATUS="❌ $TESTS_FAILED test(s) failed" +else + STATUS="✅ All tests passed!" +fi + +# Expose flaky test info to subsequent steps in the same job. +# flaky_names uses the multiline delimiter syntax required by GitHub Actions. +echo "has_flaky=$([ "$FLAKY" -gt 0 ] && echo true || echo false)" >> "$GITHUB_OUTPUT" +echo "flaky_count=$FLAKY" >> "$GITHUB_OUTPUT" +echo "tests_total=$TESTS_TOTAL" >> "$GITHUB_OUTPUT" +echo "elapsed=$GOTESTSUM_ELAPSED" >> "$GITHUB_OUTPUT" +{ + echo "flaky_names<> "$GITHUB_OUTPUT" + +# Write a summary to the GitHub Actions job summary page. +{ + echo "## Test Results" + echo "$STATUS | $TESTS_TOTAL tests in $GOTESTSUM_ELAPSED" + if [ "$FLAKY" -gt 0 ]; then + printf '\n> ⚠️ %s test(s) were flaky (failed then passed on rerun)\n\n' "$FLAKY" + echo "$FLAKY_NAMES" + fi +} >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 20533e1b..ed1e69a0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,7 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: @@ -15,8 +16,6 @@ jobs: name: Build permissions: contents: read - id-token: write # OIDC with Codecov - issues: write pull-requests: write runs-on: ubuntu-latest steps: @@ -39,37 +38,61 @@ jobs: run: sudo sysctl -w kernel.unprivileged_userns_clone=1 - name: Test - run: go test -tags="nomsgpack,remote,exclude_graphdriver_btrfs,containers_image_openpgp" -v -json -race -covermode atomic -coverprofile coverage.txt ./... 2>&1 | go tool -modfile=tools.mod go-junit-report -parser gojson -set-exit-code > junit.xml + id: test + run: | + go tool -modfile=tools.mod gotestsum \ + --jsonfile test-report.json \ + --format testname \ + --rerun-fails=3 \ + --rerun-fails-max-failures=10 \ + --packages="./..." \ + --post-run-command .github/scripts/test-summary.sh \ + -- -tags="nomsgpack,remote,exclude_graphdriver_btrfs,containers_image_openpgp" -race -covermode atomic -coverprofile=coverage.out ./... - - name: Display JUnit report + - name: Generate HTML test report if: ${{ !cancelled() }} - run: cat junit.xml + run: cat test-report.json | go tool -modfile=tools.mod go-test-report - - name: Upload junit report + - name: SonarQube Scan + uses: SonarSource/sonarqube-scan-action@59db25f34e16620e48ab4bb9e4a5dce155cb5432 # v8.0.0 if: ${{ !cancelled() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: - name: junit-report - path: junit.xml + args: > + -Dsonar.go.tests.reportPaths=test-report.json + -Dsonar.go.coverage.reportPaths=coverage.out - - name: Upload coverage to Codecov + - name: Upload HTML Test report if: ${{ !cancelled() }} - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 + id: upload + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - use_oidc: true - fail_ci_if_error: true + name: html-test-report + path: test_report.html + compression-level: 0 + archive: false + retention-days: 2 - - name: Upload test results to Codecov - if: ${{ !cancelled() }} - uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1.2.1 + - name: Find existing test results comment + if: github.event_name == 'pull_request' && !cancelled() + uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0 + id: fc with: - use_oidc: true - fail_ci_if_error: true + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: Test Results - - name: Run Basic Test Results Action - if: ${{ !cancelled() && github.event_name == 'pull_request' }} - uses: codecov/basic-test-results@c46ff461955b5cd6eb57cbe9ff22f3b77fc15824 # v1 + - name: Create or update test results comment + if: github.event_name == 'pull_request' && !cancelled() + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0 with: - github-token: ${{ secrets.GITHUB_TOKEN }} - file: junit.xml - disable-search: true \ No newline at end of file + comment-id: ${{ steps.fc.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body: | + ## Test Results + ${{ steps.test.outcome == 'success' && '✅ All tests passed!' || '❌ Some tests failed' }} | ${{ steps.test.outputs.tests_total }} tests in ${{ steps.test.outputs.elapsed }} + ${{ steps.test.outputs.has_flaky == 'true' && format('> ⚠️ {0} test(s) were flaky (failed then passed on rerun)', steps.test.outputs.flaky_count) || '' }} + ${{ steps.test.outputs.flaky_names }} + [View HTML Test Report](${{ steps.upload.outputs.artifact-url }}) + edit-mode: replace \ No newline at end of file diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml index 9d86e0d1..fc363c65 100644 --- a/.github/workflows/goreleaser.yml +++ b/.github/workflows/goreleaser.yml @@ -100,7 +100,7 @@ jobs: exit 1 fi - go tool -modfile=tools.mod gsa -o diff.txt "${{ steps.latest-release.outputs.artifact_path }}" "$built_path" + GOEXPERIMENT=jsonv2 go tool -modfile=tools.mod gsa -o diff.txt "${{ steps.latest-release.outputs.artifact_path }}" "$built_path" echo "diff<> $GITHUB_OUTPUT echo "$(cat diff.txt)" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT diff --git a/Makefile b/Makefile index ef405beb..b3a3ac67 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ .PHONY: run gen build test lint fmt docker docs +.DEFAULT_GOAL := build + export GOFLAGS=-tags=nomsgpack,remote,exclude_graphdriver_btrfs,containers_image_openpgp run: @@ -8,6 +10,7 @@ run: gen: go generate -v ./... +.PHONY: build build: goreleaser build --single-target --snapshot --clean --output . diff --git a/go.mod b/go.mod index dfb60ac8..bab3fc09 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,11 @@ go 1.26.0 require ( github.com/containers/podman/v5 v5.8.2 - github.com/docker/docker v28.5.2+incompatible github.com/gin-gonic/gin v1.12.0 github.com/google/go-cmp v0.7.0 github.com/lmittmann/tint v1.1.3 + github.com/moby/moby/api v1.54.2 + github.com/moby/moby/client v0.4.1 github.com/neilotoole/slogt v1.1.0 github.com/pkg/errors v0.9.1 github.com/samber/slog-gin v1.21.1 @@ -15,10 +16,10 @@ require ( github.com/spf13/pflag v1.0.10 github.com/spf13/viper v1.21.0 github.com/stretchr/testify v1.11.1 - github.com/testcontainers/testcontainers-go v0.41.0 - github.com/testcontainers/testcontainers-go/modules/dind v0.41.0 - github.com/testcontainers/testcontainers-go/modules/k3s v0.41.0 - github.com/testcontainers/testcontainers-go/modules/valkey v0.41.0 + github.com/testcontainers/testcontainers-go v0.42.0 + github.com/testcontainers/testcontainers-go/modules/dind v0.42.0 + github.com/testcontainers/testcontainers-go/modules/k3s v0.42.0 + github.com/testcontainers/testcontainers-go/modules/valkey v0.42.0 github.com/tniswong/go.rfcx v0.0.0-20181019234604-07783c52761f github.com/valkey-io/valkey-go v1.0.74 go.podman.io/image/v5 v5.39.2 @@ -62,8 +63,9 @@ require ( github.com/disiqueira/gotree/v3 v3.0.2 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker v28.5.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.4 // indirect - github.com/docker/go-connections v0.6.0 // indirect + github.com/docker/go-connections v0.7.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/ebitengine/purego v0.10.0 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect @@ -100,7 +102,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kevinburke/ssh_config v1.4.0 // indirect - github.com/klauspost/compress v1.18.2 // indirect + github.com/klauspost/compress v1.18.5 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/pgzip v1.2.6 // indirect github.com/kr/fs v0.1.0 // indirect @@ -118,7 +120,7 @@ require ( github.com/mistifyio/go-zfs/v3 v3.1.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/go-archive v0.2.0 // indirect - github.com/moby/patternmatcher v0.6.0 // indirect + github.com/moby/patternmatcher v0.6.1 // indirect github.com/moby/sys/capability v0.4.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect github.com/moby/sys/sequential v0.6.0 // indirect @@ -148,7 +150,7 @@ require ( github.com/rivo/uniseg v0.4.7 // indirect github.com/sagikazarmark/locafero v0.11.0 // indirect github.com/secure-systems-lab/go-securesystemslib v0.9.1 // indirect - github.com/shirou/gopsutil/v4 v4.26.2 // indirect + github.com/shirou/gopsutil/v4 v4.26.3 // indirect github.com/sigstore/fulcio v1.7.1 // indirect github.com/sigstore/protobuf-specs v0.4.1 // indirect github.com/sigstore/sigstore v1.9.5 // indirect @@ -186,7 +188,7 @@ require ( golang.org/x/crypto v0.48.0 // indirect golang.org/x/net v0.51.0 // indirect golang.org/x/oauth2 v0.34.0 // indirect - golang.org/x/sys v0.41.0 // indirect + golang.org/x/sys v0.42.0 // indirect golang.org/x/term v0.40.0 // indirect golang.org/x/text v0.34.0 // indirect golang.org/x/time v0.12.0 // indirect diff --git a/go.sum b/go.sum index 1d727003..2070439c 100644 --- a/go.sum +++ b/go.sum @@ -26,8 +26,6 @@ github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiD github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= -github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -67,8 +65,8 @@ github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GK github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= +github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/cyphar/filepath-securejoin v0.5.2 h1:w/T2bhKr4pgwG0SUGjU4S/Is9+zUknLh5ROTJLzWX8E= @@ -89,8 +87,8 @@ github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaft github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.9.4 h1:76ItO69/AP/V4yT9V4uuuItG0B1N8hvt0T0c0NN/DzI= github.com/docker/docker-credential-helpers v0.9.4/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= -github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= -github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= +github.com/docker/go-connections v0.7.0 h1:6SsRfJddP22WMrCkj19x9WKjEDTB+ahsdiGYf0mN39c= +github.com/docker/go-connections v0.7.0/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -207,8 +205,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kevinburke/ssh_config v1.4.0 h1:6xxtP5bZ2E4NF5tuQulISpTO2z8XbtH8cg1PWkxoFkQ= github.com/kevinburke/ssh_config v1.4.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= -github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= -github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= +github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= @@ -252,8 +250,12 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8= github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU= -github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= -github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg= +github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= +github.com/moby/moby/client v0.4.1 h1:DMQgisVoMkmMs7fp3ROSdiBnoAu8+vo3GggFl06M/wY= +github.com/moby/moby/client v0.4.1/go.mod h1:z52C9O2POPOsnxZAy//WtKcQ32P+jT/NGeXu/7nfjGQ= +github.com/moby/patternmatcher v0.6.1 h1:qlhtafmr6kgMIJjKJMDmMWq7WLkKIo23hsrpR3x084U= +github.com/moby/patternmatcher v0.6.1/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= @@ -351,8 +353,8 @@ github.com/secure-systems-lab/go-securesystemslib v0.9.1 h1:nZZaNz4DiERIQguNy0cL github.com/secure-systems-lab/go-securesystemslib v0.9.1/go.mod h1:np53YzT0zXGMv6x4iEWc9Z59uR+x+ndLwCLqPYpLXVU= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= -github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= +github.com/shirou/gopsutil/v4 v4.26.3 h1:2ESdQt90yU3oXF/CdOlRCJxrP+Am1aBYubTMTfxJ1qc= +github.com/shirou/gopsutil/v4 v4.26.3/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= github.com/sigstore/fulcio v1.7.1 h1:RcoW20Nz49IGeZyu3y9QYhyyV3ZKQ85T+FXPKkvE+aQ= github.com/sigstore/fulcio v1.7.1/go.mod h1:7lYY+hsd8Dt+IvKQRC+KEhWpCZ/GlmNvwIa5JhypMS8= github.com/sigstore/protobuf-specs v0.4.1 h1:5SsMqZbdkcO/DNHudaxuCUEjj6x29tS2Xby1BxGU7Zc= @@ -383,8 +385,9 @@ github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h 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/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= +github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -400,14 +403,14 @@ github.com/sylabs/sif/v2 v2.22.0 h1:Y+xXufp4RdgZe02SR3nWEg7S6q4tPWN237WHYzkDSKA= github.com/sylabs/sif/v2 v2.22.0/go.mod h1:W1XhWTmG1KcG7j5a3KSYdMcUIFvbs240w/MMVW627hs= github.com/tchap/go-patricia/v2 v2.3.3 h1:xfNEsODumaEcCcY3gI0hYPZ/PcpVv5ju6RMAhgwZDDc= github.com/tchap/go-patricia/v2 v2.3.3/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= -github.com/testcontainers/testcontainers-go v0.41.0 h1:mfpsD0D36YgkxGj2LrIyxuwQ9i2wCKAD+ESsYM1wais= -github.com/testcontainers/testcontainers-go v0.41.0/go.mod h1:pdFrEIfaPl24zmBjerWTTYaY0M6UHsqA1YSvsoU40MI= -github.com/testcontainers/testcontainers-go/modules/dind v0.41.0 h1:t5FnQv5nNkhIsbBQelG4PTSkpvwxTpc+1US5hsDODKA= -github.com/testcontainers/testcontainers-go/modules/dind v0.41.0/go.mod h1:T4V/KpM8kBewWW4wokugoKYMiL/JD56umT2ZKKxcdmo= -github.com/testcontainers/testcontainers-go/modules/k3s v0.41.0 h1:xvnllztzVajAMUmeb1BD6XQNacoY4gNEN6Gl1fhzUMI= -github.com/testcontainers/testcontainers-go/modules/k3s v0.41.0/go.mod h1:y9YF71J/D1tIoIY09dmtwEXPiHmuvntbK+MWuypq8OQ= -github.com/testcontainers/testcontainers-go/modules/valkey v0.41.0 h1:hGI7QKIwdAMqceNUJeKR81xwQaN8S/WRAVp0LCaxZdY= -github.com/testcontainers/testcontainers-go/modules/valkey v0.41.0/go.mod h1:0q8HCeidIk7f4ibsFVSimE0bbEA/9pBFcbO0Zre071g= +github.com/testcontainers/testcontainers-go v0.42.0 h1:He3IhTzTZOygSXLJPMX7n44XtK+qhjat1nI9cneBbUY= +github.com/testcontainers/testcontainers-go v0.42.0/go.mod h1:vZjdY1YmUA1qEForxOIOazfsrdyORJAbhi0bp8plN30= +github.com/testcontainers/testcontainers-go/modules/dind v0.42.0 h1:ohu4FVn0bJ8NioyDR0htQgEYsVr9eBULvvL1DSAYeps= +github.com/testcontainers/testcontainers-go/modules/dind v0.42.0/go.mod h1:Oc8Up3CirEOG3hvYkqiG2eGdiJU8aZ8Yg+NuEwsERRY= +github.com/testcontainers/testcontainers-go/modules/k3s v0.42.0 h1:bTVmcnYaSHesN6HXXxV/k0+BMkyfo3VBy4w4yRqOIgE= +github.com/testcontainers/testcontainers-go/modules/k3s v0.42.0/go.mod h1:2O8+V4WzMb/bjg/Sez+aYci9LpGUbT5cSz7ildfTIb8= +github.com/testcontainers/testcontainers-go/modules/valkey v0.42.0 h1:SL15Mh/Jmo9WLNgzv/DACihB/8NThu2En+/B11Jk+1M= +github.com/testcontainers/testcontainers-go/modules/valkey v0.42.0/go.mod h1:rKMKPmE5065l6Jk/HWu4D27cDysitXO8MQoWfwKMPg8= 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/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= @@ -450,12 +453,12 @@ go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0/go.mod h1:Izur+Wt8gClgMJqO/cZ8wdeeMryJ/xxiOVgFSSfpDTY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk= go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= -go.opentelemetry.io/otel/sdk v1.41.0 h1:YPIEXKmiAwkGl3Gu1huk1aYWwtpRLeskpV+wPisxBp8= -go.opentelemetry.io/otel/sdk v1.41.0/go.mod h1:ahFdU0G5y8IxglBf0QBJXgSe7agzjE4GiTJ6HT9ud90= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= @@ -551,8 +554,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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= @@ -636,6 +639,8 @@ k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZ k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= diff --git a/pkg/provider/docker/container_inspect.go b/pkg/provider/docker/container_inspect.go index 2d29a138..9696a2e7 100644 --- a/pkg/provider/docker/container_inspect.go +++ b/pkg/provider/docker/container_inspect.go @@ -5,26 +5,27 @@ import ( "fmt" "log/slog" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" "github.com/sablierapp/sablier/pkg/sablier" ) func (p *Provider) InstanceInspect(ctx context.Context, name string) (sablier.InstanceInfo, error) { - spec, err := p.Client.ContainerInspect(ctx, name) + spec, err := p.Client.ContainerInspect(ctx, name, client.ContainerInspectOptions{}) if err != nil { return sablier.InstanceInfo{}, fmt.Errorf("cannot inspect container: %w", err) } - p.l.DebugContext(ctx, "container inspected", slog.String("container", name), slog.String("status", spec.State.Status), slog.String("health", healthStatus(spec.State.Health))) + p.l.DebugContext(ctx, "container inspected", slog.String("container", name), slog.String("status", string(spec.Container.State.Status)), slog.String("health", healthStatus(spec.Container.State.Health))) // "created", "running", "paused", "restarting", "removing", "exited", or "dead" - switch spec.State.Status { + switch spec.Container.State.Status { case "created", "paused", "restarting", "removing": return sablier.NotReadyInstanceState(name, 0, p.desiredReplicas), nil case "running": - if spec.State.Health != nil { + if spec.Container.State.Health != nil { // // "starting", "healthy" or "unhealthy" - switch spec.State.Health.Status { + switch spec.Container.State.Health.Status { case "healthy": return sablier.ReadyInstanceState(name, p.desiredReplicas), nil case "unhealthy": @@ -36,14 +37,14 @@ func (p *Provider) InstanceInspect(ctx context.Context, name string) (sablier.In p.l.WarnContext(ctx, "container running without healthcheck, you should define a healthcheck on your container so that Sablier properly detects when the container is ready to handle requests.", slog.String("container", name)) return sablier.ReadyInstanceState(name, p.desiredReplicas), nil case "exited": - if spec.State.ExitCode != 0 { - return sablier.UnrecoverableInstanceState(name, fmt.Sprintf("container exited with code \"%d\"", spec.State.ExitCode), p.desiredReplicas), nil + if spec.Container.State.ExitCode != 0 { + return sablier.UnrecoverableInstanceState(name, fmt.Sprintf("container exited with code \"%d\"", spec.Container.State.ExitCode), p.desiredReplicas), nil } return sablier.NotReadyInstanceState(name, 0, p.desiredReplicas), nil case "dead": return sablier.UnrecoverableInstanceState(name, "container in \"dead\" state cannot be restarted", p.desiredReplicas), nil default: - return sablier.UnrecoverableInstanceState(name, fmt.Sprintf("container status \"%s\" not handled", spec.State.Status), p.desiredReplicas), nil + return sablier.UnrecoverableInstanceState(name, fmt.Sprintf("container status \"%s\" not handled", spec.Container.State.Status), p.desiredReplicas), nil } } @@ -52,5 +53,5 @@ func healthStatus(health *container.Health) string { return "no healthcheck defined" } - return health.Status + return string(health.Status) } diff --git a/pkg/provider/docker/container_inspect_test.go b/pkg/provider/docker/container_inspect_test.go index 0d7bbaea..55a01c6e 100644 --- a/pkg/provider/docker/container_inspect_test.go +++ b/pkg/provider/docker/container_inspect_test.go @@ -5,8 +5,9 @@ import ( "testing" "time" - "github.com/docker/docker/api/types/container" "github.com/google/go-cmp/cmp" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" "github.com/neilotoole/slogt" "github.com/sablierapp/sablier/pkg/provider/docker" "github.com/sablierapp/sablier/pkg/sablier" @@ -58,7 +59,8 @@ func TestDockerClassicProvider_GetState(t *testing.T) { return "", err } - return c.ID, dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) + return c.ID, err }, }, want: sablier.InstanceInfo{ @@ -88,7 +90,8 @@ func TestDockerClassicProvider_GetState(t *testing.T) { return "", err } - return c.ID, dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) + return c.ID, err }, }, want: sablier.InstanceInfo{ @@ -117,7 +120,7 @@ func TestDockerClassicProvider_GetState(t *testing.T) { return "", err } - err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) if err != nil { return "", err } @@ -154,7 +157,7 @@ func TestDockerClassicProvider_GetState(t *testing.T) { return "", err } - err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) if err != nil { return "", err } @@ -180,12 +183,12 @@ func TestDockerClassicProvider_GetState(t *testing.T) { return "", err } - err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) if err != nil { return "", err } - err = dind.client.ContainerPause(ctx, c.ID) + _, err = dind.client.ContainerPause(ctx, c.ID, client.ContainerPauseOptions{}) if err != nil { return "", err } @@ -211,13 +214,17 @@ func TestDockerClassicProvider_GetState(t *testing.T) { return "", err } - err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) if err != nil { return "", err } - waitC, _ := dind.client.ContainerWait(ctx, c.ID, container.WaitConditionNotRunning) - <-waitC + wait := dind.client.ContainerWait(ctx, c.ID, client.ContainerWaitOptions{Condition: container.WaitConditionNotRunning}) + select { + case err := <-wait.Error: + return "", err + case <-wait.Result: + } return c.ID, nil }, @@ -240,13 +247,17 @@ func TestDockerClassicProvider_GetState(t *testing.T) { return "", err } - err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) if err != nil { return "", err } - waitC, _ := dind.client.ContainerWait(ctx, c.ID, container.WaitConditionNotRunning) - <-waitC + wait := dind.client.ContainerWait(ctx, c.ID, client.ContainerWaitOptions{Condition: container.WaitConditionNotRunning}) + select { + case err := <-wait.Error: + return "", err + case <-wait.Result: + } return c.ID, nil }, diff --git a/pkg/provider/docker/container_list.go b/pkg/provider/docker/container_list.go index 2bcb6ea8..115c1787 100644 --- a/pkg/provider/docker/container_list.go +++ b/pkg/provider/docker/container_list.go @@ -6,29 +6,29 @@ import ( "log/slog" "strings" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" "github.com/sablierapp/sablier/pkg/provider" "github.com/sablierapp/sablier/pkg/sablier" ) func (p *Provider) InstanceList(ctx context.Context, options provider.InstanceListOptions) ([]sablier.InstanceConfiguration, error) { - args := filters.NewArgs() - args.Add("label", fmt.Sprintf("%s=true", "sablier.enable")) + filters := client.Filters{} + filters.Add("label", fmt.Sprintf("%s=true", "sablier.enable")) - p.l.DebugContext(ctx, "listing containers", slog.Group("options", slog.Bool("all", options.All), slog.Any("filters", args))) - containers, err := p.Client.ContainerList(ctx, container.ListOptions{ + p.l.DebugContext(ctx, "listing containers", slog.Group("options", slog.Bool("all", options.All), slog.Any("filters", filters))) + containers, err := p.Client.ContainerList(ctx, client.ContainerListOptions{ All: options.All, - Filters: args, + Filters: filters, }) if err != nil { return nil, fmt.Errorf("cannot list containers: %w", err) } - p.l.DebugContext(ctx, "containers listed", slog.Int("count", len(containers))) + p.l.DebugContext(ctx, "containers listed", slog.Int("count", len(containers.Items))) - instances := make([]sablier.InstanceConfiguration, 0, len(containers)) - for _, c := range containers { + instances := make([]sablier.InstanceConfiguration, 0, len(containers.Items)) + for _, c := range containers.Items { instance := containerToInstance(c) instances = append(instances, instance) } @@ -54,23 +54,23 @@ func containerToInstance(c container.Summary) sablier.InstanceConfiguration { } func (p *Provider) InstanceGroups(ctx context.Context) (map[string][]string, error) { - args := filters.NewArgs() - args.Add("label", fmt.Sprintf("%s=true", "sablier.enable")) + filters := client.Filters{} + filters.Add("label", fmt.Sprintf("%s=true", "sablier.enable")) - p.l.DebugContext(ctx, "listing containers", slog.Group("options", slog.Bool("all", true), slog.Any("filters", args))) - containers, err := p.Client.ContainerList(ctx, container.ListOptions{ + p.l.DebugContext(ctx, "listing containers", slog.Group("options", slog.Bool("all", true), slog.Any("filters", filters))) + containers, err := p.Client.ContainerList(ctx, client.ContainerListOptions{ All: true, - Filters: args, + Filters: filters, }) if err != nil { return nil, fmt.Errorf("cannot list containers: %w", err) } - p.l.DebugContext(ctx, "containers listed", slog.Int("count", len(containers))) + p.l.DebugContext(ctx, "containers listed", slog.Int("count", len(containers.Items))) groups := make(map[string][]string) - for _, c := range containers { + for _, c := range containers.Items { groupName := c.Labels["sablier.group"] if len(groupName) == 0 { groupName = "default" diff --git a/pkg/provider/docker/container_list_test.go b/pkg/provider/docker/container_list_test.go index 38be3e4d..3e393e41 100644 --- a/pkg/provider/docker/container_list_test.go +++ b/pkg/provider/docker/container_list_test.go @@ -5,6 +5,7 @@ import ( "strings" "testing" + "github.com/moby/moby/client" "github.com/neilotoole/slogt" "github.com/sablierapp/sablier/pkg/provider" "github.com/sablierapp/sablier/pkg/provider/docker" @@ -29,7 +30,7 @@ func TestDockerClassicProvider_InstanceList(t *testing.T) { }) assert.NilError(t, err) - i1, err := dind.client.ContainerInspect(ctx, c1.ID) + i1, err := dind.client.ContainerInspect(ctx, c1.ID, client.ContainerInspectOptions{}) assert.NilError(t, err) assert.NilError(t, err) @@ -42,7 +43,7 @@ func TestDockerClassicProvider_InstanceList(t *testing.T) { }) assert.NilError(t, err) - i2, err := dind.client.ContainerInspect(ctx, c2.ID) + i2, err := dind.client.ContainerInspect(ctx, c2.ID, client.ContainerInspectOptions{}) assert.NilError(t, err) got, err := p.InstanceList(ctx, provider.InstanceListOptions{ @@ -52,11 +53,11 @@ func TestDockerClassicProvider_InstanceList(t *testing.T) { want := []sablier.InstanceConfiguration{ { - Name: strings.TrimPrefix(i1.Name, "/"), + Name: strings.TrimPrefix(i1.Container.Name, "/"), Group: "default", }, { - Name: strings.TrimPrefix(i2.Name, "/"), + Name: strings.TrimPrefix(i2.Container.Name, "/"), Group: "my-group", }, } @@ -88,7 +89,7 @@ func TestDockerClassicProvider_GetGroups(t *testing.T) { }) assert.NilError(t, err) - i1, err := dind.client.ContainerInspect(ctx, c1.ID) + i1, err := dind.client.ContainerInspect(ctx, c1.ID, client.ContainerInspectOptions{}) assert.NilError(t, err) assert.NilError(t, err) @@ -101,15 +102,15 @@ func TestDockerClassicProvider_GetGroups(t *testing.T) { }) assert.NilError(t, err) - i2, err := dind.client.ContainerInspect(ctx, c2.ID) + i2, err := dind.client.ContainerInspect(ctx, c2.ID, client.ContainerInspectOptions{}) assert.NilError(t, err) got, err := p.InstanceGroups(ctx) assert.NilError(t, err) want := map[string][]string{ - "default": {strings.TrimPrefix(i1.Name, "/")}, - "my-group": {strings.TrimPrefix(i2.Name, "/")}, + "default": {strings.TrimPrefix(i1.Container.Name, "/")}, + "my-group": {strings.TrimPrefix(i2.Container.Name, "/")}, } assert.DeepEqual(t, got, want) diff --git a/pkg/provider/docker/container_start.go b/pkg/provider/docker/container_start.go index c19c573c..5d8d3bc4 100644 --- a/pkg/provider/docker/container_start.go +++ b/pkg/provider/docker/container_start.go @@ -5,7 +5,7 @@ import ( "fmt" "log/slog" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/client" ) func (p *Provider) InstanceStart(ctx context.Context, name string) error { @@ -17,8 +17,8 @@ func (p *Provider) InstanceStart(ctx context.Context, name string) error { func (p *Provider) dockerStart(ctx context.Context, name string) error { // TODO: InstanceStart should block until the container is ready. - p.l.DebugContext(ctx, "starting container", "name", name) - err := p.Client.ContainerStart(ctx, name, container.StartOptions{}) + p.l.DebugContext(ctx, "starting container", slog.String("name", name)) + _, err := p.Client.ContainerStart(ctx, name, client.ContainerStartOptions{}) if err != nil { p.l.ErrorContext(ctx, "cannot start container", slog.String("name", name), slog.Any("error", err)) return fmt.Errorf("cannot start container %s: %w", name, err) @@ -27,19 +27,19 @@ func (p *Provider) dockerStart(ctx context.Context, name string) error { } func (p *Provider) dockerUnpause(ctx context.Context, name string) error { - container, inspectErr := p.Client.ContainerInspect(ctx, name) + inspected, inspectErr := p.Client.ContainerInspect(ctx, name, client.ContainerInspectOptions{}) if inspectErr != nil { p.l.ErrorContext(ctx, "cannot inspect container before unpausing", slog.String("name", name), slog.Any("error", inspectErr)) return fmt.Errorf("cannot inspect container %s before unpausing: %w", name, inspectErr) } - if !container.State.Paused { + if !inspected.Container.State.Paused { p.l.DebugContext(ctx, "container is not paused, starting container", slog.String("name", name)) return p.dockerStart(ctx, name) } p.l.DebugContext(ctx, "unpausing container", slog.String("name", name)) - err := p.Client.ContainerUnpause(ctx, name) + _, err := p.Client.ContainerUnpause(ctx, name, client.ContainerUnpauseOptions{}) if err != nil { p.l.ErrorContext(ctx, "cannot unpause container", slog.String("name", name), slog.Any("error", err)) return fmt.Errorf("cannot unpause container %s: %w", name, err) diff --git a/pkg/provider/docker/container_start_test.go b/pkg/provider/docker/container_start_test.go index dda6acf6..9aad64b6 100644 --- a/pkg/provider/docker/container_start_test.go +++ b/pkg/provider/docker/container_start_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/client" "github.com/neilotoole/slogt" "github.com/sablierapp/sablier/pkg/provider/docker" "gotest.tools/v3/assert" @@ -97,12 +97,12 @@ func TestDockerClassicProvider_Unpause(t *testing.T) { return "", err } - err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) if err != nil { return "", err } - err = dind.client.ContainerStop(ctx, c.ID, container.StopOptions{}) + _, err = dind.client.ContainerStop(ctx, c.ID, client.ContainerStopOptions{}) if err != nil { return "", err } @@ -121,12 +121,12 @@ func TestDockerClassicProvider_Unpause(t *testing.T) { return "", err } - err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) if err != nil { return "", err } - err = dind.client.ContainerPause(ctx, c.ID) + _, err = dind.client.ContainerPause(ctx, c.ID, client.ContainerPauseOptions{}) if err != nil { return "", err } diff --git a/pkg/provider/docker/container_stop.go b/pkg/provider/docker/container_stop.go index 91f6cfd9..34a2c810 100644 --- a/pkg/provider/docker/container_stop.go +++ b/pkg/provider/docker/container_stop.go @@ -5,7 +5,8 @@ import ( "fmt" "log/slog" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" ) func (p *Provider) InstanceStop(ctx context.Context, name string) error { @@ -17,19 +18,21 @@ func (p *Provider) InstanceStop(ctx context.Context, name string) error { func (p *Provider) dockerStop(ctx context.Context, name string) error { p.l.DebugContext(ctx, "stopping container", slog.String("name", name)) - err := p.Client.ContainerStop(ctx, name, container.StopOptions{}) + _, err := p.Client.ContainerStop(ctx, name, client.ContainerStopOptions{}) if err != nil { p.l.ErrorContext(ctx, "cannot stop container", slog.String("name", name), slog.Any("error", err)) return fmt.Errorf("cannot stop container %s: %w", name, err) } p.l.DebugContext(ctx, "waiting for container to stop", slog.String("name", name)) - waitC, errC := p.Client.ContainerWait(ctx, name, container.WaitConditionNotRunning) + result := p.Client.ContainerWait(ctx, name, client.ContainerWaitOptions{ + Condition: container.WaitConditionNotRunning, + }) select { - case response := <-waitC: + case response := <-result.Result: p.l.DebugContext(ctx, "container stopped", slog.String("name", name), slog.Int64("exit_code", response.StatusCode)) return nil - case err := <-errC: + case err := <-result.Error: p.l.ErrorContext(ctx, "cannot wait for container to stop", slog.String("name", name), slog.Any("error", err)) return fmt.Errorf("cannot wait for container %s to stop: %w", name, err) case <-ctx.Done(): @@ -40,7 +43,7 @@ func (p *Provider) dockerStop(ctx context.Context, name string) error { func (p *Provider) dockerPause(ctx context.Context, name string) error { p.l.DebugContext(ctx, "pausing container", slog.String("name", name)) - err := p.Client.ContainerPause(ctx, name) + _, err := p.Client.ContainerPause(ctx, name, client.ContainerPauseOptions{}) if err != nil { p.l.ErrorContext(ctx, "cannot pause container", slog.String("name", name), slog.Any("error", err)) return fmt.Errorf("cannot pause container %s: %w", name, err) diff --git a/pkg/provider/docker/container_stop_test.go b/pkg/provider/docker/container_stop_test.go index 8e11100a..a9ecb1a1 100644 --- a/pkg/provider/docker/container_stop_test.go +++ b/pkg/provider/docker/container_stop_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/client" "github.com/neilotoole/slogt" "github.com/sablierapp/sablier/pkg/provider/docker" "gotest.tools/v3/assert" @@ -43,7 +43,7 @@ func TestDockerClassicProvider_Stop(t *testing.T) { return "", err } - err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) if err != nil { return "", err } @@ -106,7 +106,7 @@ func TestDockerClassicProvider_Pause(t *testing.T) { return "", err } - err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) if err != nil { return "", err } diff --git a/pkg/provider/docker/docker.go b/pkg/provider/docker/docker.go index 7ef3be2e..f09437ac 100644 --- a/pkg/provider/docker/docker.go +++ b/pkg/provider/docker/docker.go @@ -5,7 +5,7 @@ import ( "fmt" "log/slog" - "github.com/docker/docker/client" + "github.com/moby/moby/client" "github.com/sablierapp/sablier/pkg/sablier" ) @@ -22,7 +22,7 @@ type Provider struct { func New(ctx context.Context, cli *client.Client, logger *slog.Logger, strategy string) (*Provider, error) { logger = logger.With(slog.String("provider", "docker"), slog.String("strategy", strategy)) - serverVersion, err := cli.ServerVersion(ctx) + serverVersion, err := cli.ServerVersion(ctx, client.ServerVersionOptions{}) if err != nil { return nil, fmt.Errorf("cannot connect to docker host: %v", err) } diff --git a/pkg/provider/docker/events.go b/pkg/provider/docker/events.go index 422a7e17..7459b268 100644 --- a/pkg/provider/docker/events.go +++ b/pkg/provider/docker/events.go @@ -7,21 +7,21 @@ import ( "log/slog" "strings" - "github.com/docker/docker/api/types/events" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/api/types/events" + "github.com/moby/moby/client" ) func (p *Provider) NotifyInstanceStopped(ctx context.Context, instance chan<- string) { - msgs, errs := p.Client.Events(ctx, events.ListOptions{ - Filters: filters.NewArgs( - filters.Arg("scope", "local"), - filters.Arg("type", string(events.ContainerEventType)), - filters.Arg("event", "die"), - ), + filters := client.Filters{} + filters.Add("scope", "local") + filters.Add("type", string(events.ContainerEventType)) + filters.Add("event", "die") + result := p.Client.Events(ctx, client.EventsListOptions{ + Filters: filters, }) for { select { - case msg, ok := <-msgs: + case msg, ok := <-result.Messages: if !ok { p.l.ErrorContext(ctx, "event stream closed") close(instance) @@ -30,7 +30,7 @@ func (p *Provider) NotifyInstanceStopped(ctx context.Context, instance chan<- st // Send the container that has died to the channel p.l.DebugContext(ctx, "event received", "event", msg) instance <- strings.TrimPrefix(msg.Actor.Attributes["name"], "/") - case err, ok := <-errs: + case err, ok := <-result.Err: if !ok { p.l.ErrorContext(ctx, "event stream closed") close(instance) diff --git a/pkg/provider/docker/events_test.go b/pkg/provider/docker/events_test.go index bd0634a4..6ccd628e 100644 --- a/pkg/provider/docker/events_test.go +++ b/pkg/provider/docker/events_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/client" "github.com/neilotoole/slogt" "github.com/sablierapp/sablier/pkg/provider/docker" "gotest.tools/v3/assert" @@ -25,10 +25,10 @@ func TestDockerClassicProvider_NotifyInstanceStopped(t *testing.T) { c, err := dind.CreateMimic(ctx, MimicOptions{}) assert.NilError(t, err) - inspected, err := dind.client.ContainerInspect(ctx, c.ID) + inspected, err := dind.client.ContainerInspect(ctx, c.ID, client.ContainerInspectOptions{}) assert.NilError(t, err) - err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{}) + _, err = dind.client.ContainerStart(ctx, c.ID, client.ContainerStartOptions{}) assert.NilError(t, err) <-time.After(1 * time.Second) @@ -36,11 +36,11 @@ func TestDockerClassicProvider_NotifyInstanceStopped(t *testing.T) { waitC := make(chan string) go p.NotifyInstanceStopped(ctx, waitC) - err = dind.client.ContainerStop(ctx, c.ID, container.StopOptions{}) + _, err = dind.client.ContainerStop(ctx, c.ID, client.ContainerStopOptions{}) assert.NilError(t, err) name := <-waitC // Docker container name is prefixed with a slash, but we don't use it - assert.Equal(t, "/"+name, inspected.Name) + assert.Equal(t, "/"+name, inspected.Container.Name) } diff --git a/pkg/provider/docker/testcontainers_test.go b/pkg/provider/docker/testcontainers_test.go index f84b76e2..51bdacf7 100644 --- a/pkg/provider/docker/testcontainers_test.go +++ b/pkg/provider/docker/testcontainers_test.go @@ -2,12 +2,13 @@ package docker_test import ( "context" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/client" + "testing" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/modules/dind" "gotest.tools/v3/assert" - "testing" ) type dindContainer struct { @@ -23,18 +24,21 @@ type MimicOptions struct { Labels map[string]string } -func (d *dindContainer) CreateMimic(ctx context.Context, opts MimicOptions) (container.CreateResponse, error) { +func (d *dindContainer) CreateMimic(ctx context.Context, opts MimicOptions) (client.ContainerCreateResult, error) { if len(opts.Cmd) == 0 { opts.Cmd = []string{"/mimic", "-running", "-running-after=1s", "-healthy=false"} } d.t.Log("Creating mimic container with options", opts) - return d.client.ContainerCreate(ctx, &container.Config{ - Entrypoint: opts.Cmd, - Image: "sablierapp/mimic:v0.3.1", - Labels: opts.Labels, - Healthcheck: opts.Healthcheck, - }, &container.HostConfig{RestartPolicy: opts.RestartPolicy}, nil, nil, "") + return d.client.ContainerCreate(ctx, client.ContainerCreateOptions{ + Config: &container.Config{ + Entrypoint: opts.Cmd, + Image: "sablierapp/mimic:v0.3.1", + Labels: opts.Labels, + Healthcheck: opts.Healthcheck, + }, + HostConfig: &container.HostConfig{RestartPolicy: opts.RestartPolicy}}, + ) } func setupDinD(t *testing.T) *dindContainer { @@ -47,7 +51,7 @@ func setupDinD(t *testing.T) *dindContainer { host, err := c.Host(ctx) assert.NilError(t, err) - dindCli, err := client.NewClientWithOpts(client.WithHost(host), client.WithAPIVersionNegotiation()) + dindCli, err := client.New(client.WithHost(host)) assert.NilError(t, err) provider, err := testcontainers.ProviderDocker.GetProvider() diff --git a/pkg/provider/dockerswarm/docker_swarm.go b/pkg/provider/dockerswarm/docker_swarm.go index 4089f51f..564c3aad 100644 --- a/pkg/provider/dockerswarm/docker_swarm.go +++ b/pkg/provider/dockerswarm/docker_swarm.go @@ -7,10 +7,8 @@ import ( "log/slog" "strings" - "github.com/docker/docker/api/types/swarm" + "github.com/moby/moby/client" "github.com/sablierapp/sablier/pkg/sablier" - - "github.com/docker/docker/client" ) // Interface guard @@ -26,7 +24,7 @@ type Provider struct { func New(ctx context.Context, cli *client.Client, logger *slog.Logger) (*Provider, error) { logger = logger.With(slog.String("provider", "swarm")) - serverVersion, err := cli.ServerVersion(ctx) + serverVersion, err := cli.ServerVersion(ctx, client.ServerVersionOptions{}) if err != nil { return nil, fmt.Errorf("cannot connect to docker host: %w", err) } @@ -57,7 +55,10 @@ func (p *Provider) ServiceUpdateReplicas(ctx context.Context, name string, repli p.l.DebugContext(ctx, "scaling service", "name", name, "current_replicas", service.Spec.Mode.Replicated.Replicas, "desired_replicas", p.desiredReplicas) service.Spec.Mode.Replicated.Replicas = &replicas - response, err := p.Client.ServiceUpdate(ctx, service.ID, service.Version, service.Spec, swarm.ServiceUpdateOptions{}) + response, err := p.Client.ServiceUpdate(ctx, service.ID, client.ServiceUpdateOptions{ + Version: service.Version, + Spec: service.Spec, + }) if err != nil { return fmt.Errorf("cannot update service: %w", err) } diff --git a/pkg/provider/dockerswarm/events.go b/pkg/provider/dockerswarm/events.go index e2dd2bb7..29b5eb21 100644 --- a/pkg/provider/dockerswarm/events.go +++ b/pkg/provider/dockerswarm/events.go @@ -6,22 +6,21 @@ import ( "io" "log/slog" - "github.com/docker/docker/api/types/events" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/client" ) func (p *Provider) NotifyInstanceStopped(ctx context.Context, instance chan<- string) { - msgs, errs := p.Client.Events(ctx, events.ListOptions{ - Filters: filters.NewArgs( - filters.Arg("scope", "swarm"), - filters.Arg("type", "service"), - ), + filters := client.Filters{} + filters.Add("scope", "swarm") + filters.Add("type", "service") + result := p.Client.Events(ctx, client.EventsListOptions{ + Filters: filters, }) go func() { for { select { - case msg, ok := <-msgs: + case msg, ok := <-result.Messages: if !ok { p.l.ErrorContext(ctx, "event stream closed") return @@ -32,7 +31,7 @@ func (p *Provider) NotifyInstanceStopped(ctx context.Context, instance chan<- st } else if msg.Action == "remove" { instance <- msg.Actor.Attributes["name"] } - case err, ok := <-errs: + case err, ok := <-result.Err: if !ok { p.l.ErrorContext(ctx, "event stream closed") return diff --git a/pkg/provider/dockerswarm/events_test.go b/pkg/provider/dockerswarm/events_test.go index 8f952932..48453290 100644 --- a/pkg/provider/dockerswarm/events_test.go +++ b/pkg/provider/dockerswarm/events_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/docker/docker/api/types/swarm" + "github.com/moby/moby/client" "github.com/neilotoole/slogt" "github.com/sablierapp/sablier/pkg/provider/dockerswarm" "gotest.tools/v3/assert" @@ -29,13 +29,14 @@ func TestDockerSwarmProvider_NotifyInstanceStopped(t *testing.T) { go p.NotifyInstanceStopped(ctx, waitC) t.Run("service is scaled to 0 replicas", func(t *testing.T) { - service, _, err := dind.client.ServiceInspectWithRaw(ctx, c.ID, swarm.ServiceInspectOptions{}) + inspectResult, err := dind.client.ServiceInspect(ctx, c.ID, client.ServiceInspectOptions{}) assert.NilError(t, err) + service := inspectResult.Service replicas := uint64(0) service.Spec.Mode.Replicated.Replicas = &replicas - _, err = p.Client.ServiceUpdate(ctx, service.ID, service.Version, service.Spec, swarm.ServiceUpdateOptions{}) + _, err = p.Client.ServiceUpdate(ctx, service.ID, client.ServiceUpdateOptions{Version: service.Version, Spec: service.Spec}) assert.NilError(t, err) name := <-waitC @@ -45,10 +46,11 @@ func TestDockerSwarmProvider_NotifyInstanceStopped(t *testing.T) { }) t.Run("service is removed", func(t *testing.T) { - service, _, err := dind.client.ServiceInspectWithRaw(ctx, c.ID, swarm.ServiceInspectOptions{}) + inspectResult, err := dind.client.ServiceInspect(ctx, c.ID, client.ServiceInspectOptions{}) assert.NilError(t, err) + service := inspectResult.Service - err = p.Client.ServiceRemove(ctx, service.ID) + _, err = p.Client.ServiceRemove(ctx, service.ID, client.ServiceRemoveOptions{}) assert.NilError(t, err) name := <-waitC diff --git a/pkg/provider/dockerswarm/service_inspect.go b/pkg/provider/dockerswarm/service_inspect.go index 7d154105..c06069b5 100644 --- a/pkg/provider/dockerswarm/service_inspect.go +++ b/pkg/provider/dockerswarm/service_inspect.go @@ -6,8 +6,8 @@ import ( "fmt" "log/slog" - "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/api/types/swarm" + "github.com/moby/moby/api/types/swarm" + "github.com/moby/moby/client" "github.com/sablierapp/sablier/pkg/sablier" ) @@ -29,24 +29,26 @@ func (p *Provider) InstanceInspect(ctx context.Context, name string) (sablier.In } func (p *Provider) getServiceByName(name string, ctx context.Context) (*swarm.Service, error) { - opts := swarm.ServiceListOptions{ - Filters: filters.NewArgs(), + filters := client.Filters{} + filters.Add("name", name) + + opts := client.ServiceListOptions{ + Filters: filters, // If set to true, the list will include the swarm.ServiceStatus field to all returned services. Status: true, } - opts.Filters.Add("name", name) services, err := p.Client.ServiceList(ctx, opts) if err != nil { return nil, fmt.Errorf("error listing services: %w", err) } - if len(services) == 0 { + if len(services.Items) == 0 { return nil, fmt.Errorf("service with name %s was not found", name) } var svc *swarm.Service = nil - for _, service := range services { + for _, service := range services.Items { // Exact match if service.Spec.Name == name { svc = &service diff --git a/pkg/provider/dockerswarm/service_inspect_test.go b/pkg/provider/dockerswarm/service_inspect_test.go index d949d1c0..a8ef42a7 100644 --- a/pkg/provider/dockerswarm/service_inspect_test.go +++ b/pkg/provider/dockerswarm/service_inspect_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/swarm" "github.com/google/go-cmp/cmp" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" "github.com/neilotoole/slogt" "github.com/sablierapp/sablier/pkg/provider/dockerswarm" "github.com/sablierapp/sablier/pkg/sablier" @@ -41,10 +41,11 @@ func TestDockerSwarmProvider_GetState(t *testing.T) { return "", err } - service, _, err := dind.client.ServiceInspectWithRaw(ctx, s.ID, swarm.ServiceInspectOptions{}) + inspectResult, err := dind.client.ServiceInspect(ctx, s.ID, client.ServiceInspectOptions{}) if err != nil { return "", err } + service := inspectResult.Service <-time.After(5 * time.Second) @@ -77,10 +78,11 @@ func TestDockerSwarmProvider_GetState(t *testing.T) { return "", err } - service, _, err := dind.client.ServiceInspectWithRaw(ctx, s.ID, swarm.ServiceInspectOptions{}) + inspectResult, err := dind.client.ServiceInspect(ctx, s.ID, client.ServiceInspectOptions{}) if err != nil { return "", err } + service := inspectResult.Service return service.Spec.Name, nil }, @@ -101,14 +103,15 @@ func TestDockerSwarmProvider_GetState(t *testing.T) { return "", err } - service, _, err := dind.client.ServiceInspectWithRaw(ctx, s.ID, swarm.ServiceInspectOptions{}) + inspectResult, err := dind.client.ServiceInspect(ctx, s.ID, client.ServiceInspectOptions{}) if err != nil { return "", err } + service := inspectResult.Service replicas := uint64(0) service.Spec.Mode.Replicated.Replicas = &replicas - _, err = dind.client.ServiceUpdate(ctx, s.ID, service.Version, service.Spec, swarm.ServiceUpdateOptions{}) + _, err = dind.client.ServiceUpdate(ctx, s.ID, client.ServiceUpdateOptions{Version: service.Version, Spec: service.Spec}) if err != nil { return "", err } diff --git a/pkg/provider/dockerswarm/service_list.go b/pkg/provider/dockerswarm/service_list.go index 4f101c9e..c3c23871 100644 --- a/pkg/provider/dockerswarm/service_list.go +++ b/pkg/provider/dockerswarm/service_list.go @@ -5,30 +5,30 @@ import ( "fmt" "log/slog" - "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/api/types/swarm" + "github.com/moby/moby/api/types/swarm" + "github.com/moby/moby/client" "github.com/sablierapp/sablier/pkg/provider" "github.com/sablierapp/sablier/pkg/sablier" ) func (p *Provider) InstanceList(ctx context.Context, _ provider.InstanceListOptions) ([]sablier.InstanceConfiguration, error) { - args := filters.NewArgs() - args.Add("label", fmt.Sprintf("%s=true", "sablier.enable")) - args.Add("mode", "replicated") + filters := client.Filters{} + filters.Add("label", fmt.Sprintf("%s=true", "sablier.enable")) + filters.Add("mode", "replicated") - p.l.DebugContext(ctx, "listing services", slog.Group("options", slog.Bool("status", true), slog.Any("filters", args))) - services, err := p.Client.ServiceList(ctx, swarm.ServiceListOptions{ + p.l.DebugContext(ctx, "listing services", slog.Group("options", slog.Bool("status", true), slog.Any("filters", filters))) + services, err := p.Client.ServiceList(ctx, client.ServiceListOptions{ Status: true, - Filters: args, + Filters: filters, }) if err != nil { return nil, fmt.Errorf("cannot list services: %w", err) } - p.l.DebugContext(ctx, "services listed", slog.Int("count", len(services)), slog.Any("services", services)) + p.l.DebugContext(ctx, "services listed", slog.Int("count", len(services.Items)), slog.Any("services", services)) - instances := make([]sablier.InstanceConfiguration, 0, len(services)) - for _, s := range services { + instances := make([]sablier.InstanceConfiguration, 0, len(services.Items)) + for _, s := range services.Items { instance := p.serviceToInstance(s) instances = append(instances, instance) } @@ -54,23 +54,22 @@ func (p *Provider) serviceToInstance(s swarm.Service) (i sablier.InstanceConfigu } func (p *Provider) InstanceGroups(ctx context.Context) (map[string][]string, error) { - f := filters.NewArgs() - f.Add("label", fmt.Sprintf("%s=true", "sablier.enable")) - - p.l.DebugContext(ctx, "listing services", slog.Group("options", slog.Bool("status", true), slog.Any("filters", f))) - services, err := p.Client.ServiceList(ctx, swarm.ServiceListOptions{ + filters := client.Filters{} + filters.Add("label", fmt.Sprintf("%s=true", "sablier.enable")) + p.l.DebugContext(ctx, "listing services", slog.Group("options", slog.Bool("status", true), slog.Any("filters", filters))) + services, err := p.Client.ServiceList(ctx, client.ServiceListOptions{ Status: true, - Filters: f, + Filters: filters, }) if err != nil { return nil, fmt.Errorf("cannot list services: %w", err) } - p.l.DebugContext(ctx, "services listed", slog.Int("count", len(services))) + p.l.DebugContext(ctx, "services listed", slog.Int("count", len(services.Items))) groups := make(map[string][]string) - for _, service := range services { + for _, service := range services.Items { groupName := service.Spec.Labels["sablier.group"] if len(groupName) == 0 { groupName = "default" diff --git a/pkg/provider/dockerswarm/service_list_test.go b/pkg/provider/dockerswarm/service_list_test.go index 3a3b1cfb..d9d75d26 100644 --- a/pkg/provider/dockerswarm/service_list_test.go +++ b/pkg/provider/dockerswarm/service_list_test.go @@ -1,7 +1,7 @@ package dockerswarm_test import ( - "github.com/docker/docker/api/types/swarm" + "github.com/moby/moby/client" "github.com/sablierapp/sablier/pkg/sablier" "sort" @@ -31,8 +31,9 @@ func TestDockerClassicProvider_InstanceList(t *testing.T) { }) assert.NilError(t, err) - i1, _, err := dind.client.ServiceInspectWithRaw(ctx, s1.ID, swarm.ServiceInspectOptions{}) + i1Result, err := dind.client.ServiceInspect(ctx, s1.ID, client.ServiceInspectOptions{}) assert.NilError(t, err) + i1 := i1Result.Service s2, err := dind.CreateMimic(ctx, MimicOptions{ Labels: map[string]string{ @@ -42,8 +43,9 @@ func TestDockerClassicProvider_InstanceList(t *testing.T) { }) assert.NilError(t, err) - i2, _, err := dind.client.ServiceInspectWithRaw(ctx, s2.ID, swarm.ServiceInspectOptions{}) + i2Result, err := dind.client.ServiceInspect(ctx, s2.ID, client.ServiceInspectOptions{}) assert.NilError(t, err) + i2 := i2Result.Service got, err := p.InstanceList(ctx, provider.InstanceListOptions{ All: true, @@ -88,8 +90,9 @@ func TestDockerClassicProvider_GetGroups(t *testing.T) { }) assert.NilError(t, err) - i1, _, err := dind.client.ServiceInspectWithRaw(ctx, s1.ID, swarm.ServiceInspectOptions{}) + i1Result, err := dind.client.ServiceInspect(ctx, s1.ID, client.ServiceInspectOptions{}) assert.NilError(t, err) + i1 := i1Result.Service s2, err := dind.CreateMimic(ctx, MimicOptions{ Labels: map[string]string{ @@ -99,8 +102,9 @@ func TestDockerClassicProvider_GetGroups(t *testing.T) { }) assert.NilError(t, err) - i2, _, err := dind.client.ServiceInspectWithRaw(ctx, s2.ID, swarm.ServiceInspectOptions{}) + i2Result, err := dind.client.ServiceInspect(ctx, s2.ID, client.ServiceInspectOptions{}) assert.NilError(t, err) + i2 := i2Result.Service got, err := p.InstanceGroups(ctx) assert.NilError(t, err) diff --git a/pkg/provider/dockerswarm/service_start_test.go b/pkg/provider/dockerswarm/service_start_test.go index be2e3e74..06fc073b 100644 --- a/pkg/provider/dockerswarm/service_start_test.go +++ b/pkg/provider/dockerswarm/service_start_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/swarm" "github.com/google/go-cmp/cmp" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" "github.com/neilotoole/slogt" "github.com/sablierapp/sablier/pkg/provider/dockerswarm" "github.com/sablierapp/sablier/pkg/sablier" @@ -41,10 +41,11 @@ func TestDockerSwarmProvider_Start(t *testing.T) { return "", err } - service, _, err := dind.client.ServiceInspectWithRaw(ctx, s.ID, swarm.ServiceInspectOptions{}) + inspectResult, err := dind.client.ServiceInspect(ctx, s.ID, client.ServiceInspectOptions{}) if err != nil { return "", err } + service := inspectResult.Service return service.Spec.Name, err }, @@ -75,10 +76,11 @@ func TestDockerSwarmProvider_Start(t *testing.T) { return "", err } - service, _, err := dind.client.ServiceInspectWithRaw(ctx, s.ID, swarm.ServiceInspectOptions{}) + inspectResult, err := dind.client.ServiceInspect(ctx, s.ID, client.ServiceInspectOptions{}) if err != nil { return "", err } + service := inspectResult.Service return service.Spec.Name, nil }, @@ -100,14 +102,15 @@ func TestDockerSwarmProvider_Start(t *testing.T) { return "", err } - service, _, err := dind.client.ServiceInspectWithRaw(ctx, s.ID, swarm.ServiceInspectOptions{}) + inspectResult, err := dind.client.ServiceInspect(ctx, s.ID, client.ServiceInspectOptions{}) if err != nil { return "", err } + service := inspectResult.Service replicas := uint64(0) service.Spec.Mode.Replicated.Replicas = &replicas - _, err = dind.client.ServiceUpdate(ctx, s.ID, service.Version, service.Spec, swarm.ServiceUpdateOptions{}) + _, err = dind.client.ServiceUpdate(ctx, s.ID, client.ServiceUpdateOptions{Version: service.Version, Spec: service.Spec}) if err != nil { return "", err } @@ -140,9 +143,9 @@ func TestDockerSwarmProvider_Start(t *testing.T) { return } - service, _, err := c.client.ServiceInspectWithRaw(ctx, name, swarm.ServiceInspectOptions{}) + service, err := c.client.ServiceInspect(ctx, name, client.ServiceInspectOptions{}) assert.NilError(t, err) - assert.Equal(t, *service.Spec.Mode.Replicated.Replicas, uint64(1)) + assert.Equal(t, *service.Service.Spec.Mode.Replicated.Replicas, uint64(1)) }) } } diff --git a/pkg/provider/dockerswarm/service_stop_test.go b/pkg/provider/dockerswarm/service_stop_test.go index 901bb9bb..606940be 100644 --- a/pkg/provider/dockerswarm/service_stop_test.go +++ b/pkg/provider/dockerswarm/service_stop_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/swarm" "github.com/google/go-cmp/cmp" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" "github.com/neilotoole/slogt" "github.com/sablierapp/sablier/pkg/provider/dockerswarm" "github.com/sablierapp/sablier/pkg/sablier" @@ -41,10 +41,11 @@ func TestDockerSwarmProvider_Stop(t *testing.T) { return "", err } - service, _, err := dind.client.ServiceInspectWithRaw(ctx, s.ID, swarm.ServiceInspectOptions{}) + inspectResult, err := dind.client.ServiceInspect(ctx, s.ID, client.ServiceInspectOptions{}) if err != nil { return "", err } + service := inspectResult.Service return service.Spec.Name, err }, @@ -75,10 +76,11 @@ func TestDockerSwarmProvider_Stop(t *testing.T) { return "", err } - service, _, err := dind.client.ServiceInspectWithRaw(ctx, s.ID, swarm.ServiceInspectOptions{}) + inspectResult, err := dind.client.ServiceInspect(ctx, s.ID, client.ServiceInspectOptions{}) if err != nil { return "", err } + service := inspectResult.Service return service.Spec.Name, nil }, @@ -108,9 +110,9 @@ func TestDockerSwarmProvider_Stop(t *testing.T) { return } - service, _, err := c.client.ServiceInspectWithRaw(ctx, name, swarm.ServiceInspectOptions{}) + service, err := c.client.ServiceInspect(ctx, name, client.ServiceInspectOptions{}) assert.NilError(t, err) - assert.Equal(t, *service.Spec.Mode.Replicated.Replicas, uint64(0)) + assert.Equal(t, *service.Service.Spec.Mode.Replicated.Replicas, uint64(0)) }) } } diff --git a/pkg/provider/dockerswarm/testcontainers_test.go b/pkg/provider/dockerswarm/testcontainers_test.go index 9c9582bf..6d070ee6 100644 --- a/pkg/provider/dockerswarm/testcontainers_test.go +++ b/pkg/provider/dockerswarm/testcontainers_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/swarm" - "github.com/docker/docker/client" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/swarm" + "github.com/moby/moby/client" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/modules/dind" "gotest.tools/v3/assert" @@ -25,29 +25,31 @@ type MimicOptions struct { Labels map[string]string } -func (d *dindContainer) CreateMimic(ctx context.Context, opts MimicOptions) (swarm.ServiceCreateResponse, error) { +func (d *dindContainer) CreateMimic(ctx context.Context, opts MimicOptions) (client.ServiceCreateResult, error) { if len(opts.Cmd) == 0 { opts.Cmd = []string{"/mimic", "-running", "-running-after=1s", "-healthy=false"} } d.t.Log("Creating mimic service with options", opts) var replicas uint64 = 1 - return d.client.ServiceCreate(ctx, swarm.ServiceSpec{ - Mode: swarm.ServiceMode{ - Replicated: &swarm.ReplicatedService{Replicas: &replicas}, - }, - TaskTemplate: swarm.TaskSpec{ - RestartPolicy: opts.RestartPolicy, - ContainerSpec: &swarm.ContainerSpec{ - Image: "sablierapp/mimic:v0.3.1", - Healthcheck: opts.Healthcheck, - Command: opts.Cmd, + return d.client.ServiceCreate(ctx, client.ServiceCreateOptions{ + Spec: swarm.ServiceSpec{ + Mode: swarm.ServiceMode{ + Replicated: &swarm.ReplicatedService{Replicas: &replicas}, + }, + TaskTemplate: swarm.TaskSpec{ + RestartPolicy: opts.RestartPolicy, + ContainerSpec: &swarm.ContainerSpec{ + Image: "sablierapp/mimic:v0.3.1", + Healthcheck: opts.Healthcheck, + Command: opts.Cmd, + }, + }, + Annotations: swarm.Annotations{ + Labels: opts.Labels, }, }, - Annotations: swarm.Annotations{ - Labels: opts.Labels, - }, - }, swarm.ServiceCreateOptions{}) + }) } func setupDinD(t *testing.T) *dindContainer { @@ -60,7 +62,7 @@ func setupDinD(t *testing.T) *dindContainer { host, err := c.Host(ctx) assert.NilError(t, err) - dindCli, err := client.NewClientWithOpts(client.WithHost(host), client.WithAPIVersionNegotiation()) + dindCli, err := client.New(client.WithHost(host)) assert.NilError(t, err) provider, err := testcontainers.ProviderDocker.GetProvider() @@ -73,7 +75,7 @@ func setupDinD(t *testing.T) *dindContainer { // assert.NilError(t, err) // Initialize the swarm - _, err = dindCli.SwarmInit(ctx, swarm.InitRequest{ + _, err = dindCli.SwarmInit(ctx, client.SwarmInitOptions{ ListenAddr: "0.0.0.0", }) assert.NilError(t, err) diff --git a/pkg/provider/podman/testcontainers_test.go b/pkg/provider/podman/testcontainers_test.go index 615addf8..48b4452b 100644 --- a/pkg/provider/podman/testcontainers_test.go +++ b/pkg/provider/podman/testcontainers_test.go @@ -48,7 +48,7 @@ func (d *pindContainer) CreateMimic(ctx context.Context, opts MimicOptions) (ent func setupPinD(t *testing.T) *pindContainer { t.Helper() ctx := t.Context() - c, err := pind.Run(ctx, "quay.io/podman/stable:v5.5.2") + c, err := pind.Run(ctx, "quay.io/podman/stable:v5.8.2") assert.NilError(t, err) testcontainers.CleanupContainer(t, c) diff --git a/pkg/sabliercmd/provider.go b/pkg/sabliercmd/provider.go index 2fca35f0..82ca3c8b 100644 --- a/pkg/sabliercmd/provider.go +++ b/pkg/sabliercmd/provider.go @@ -6,7 +6,7 @@ import ( "log/slog" "github.com/containers/podman/v5/pkg/bindings" - "github.com/docker/docker/client" + "github.com/moby/moby/client" "github.com/sablierapp/sablier/pkg/config" "github.com/sablierapp/sablier/pkg/provider/docker" "github.com/sablierapp/sablier/pkg/provider/dockerswarm" @@ -24,13 +24,13 @@ func setupProvider(ctx context.Context, logger *slog.Logger, config config.Provi switch config.Name { case "swarm", "docker_swarm": - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + cli, err := client.New(client.FromEnv) if err != nil { return nil, fmt.Errorf("cannot create docker swarm client: %v", err) } return dockerswarm.New(ctx, cli, logger) case "docker": - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + cli, err := client.New(client.FromEnv) if err != nil { return nil, fmt.Errorf("cannot create docker client: %v", err) } diff --git a/pkg/testcontainers/pind/pind.go b/pkg/testcontainers/pind/pind.go index e9630490..768e6c25 100644 --- a/pkg/testcontainers/pind/pind.go +++ b/pkg/testcontainers/pind/pind.go @@ -4,12 +4,13 @@ import ( "context" "errors" "fmt" - "github.com/testcontainers/testcontainers-go/wait" "os" "path/filepath" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/api/types/container" + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/wait" ) // Container represents the Podman in Docker container type used in the module @@ -79,6 +80,9 @@ func (c *Container) LoadImage(ctx context.Context, image string) (err error) { if err != nil { return fmt.Errorf("create temporary images file: %w", err) } + if err = imagesTar.Close(); err != nil { + return fmt.Errorf("close temporary images file: %w", err) + } defer func() { err = errors.Join(err, os.Remove(imagesTar.Name())) }() diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 00000000..36bd44b0 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,5 @@ +sonar.organization=sablierapp +sonar.projectKey=sablierapp_sablier +sonar.coverage.exclusions=**/*_test.go +sonar.exclusions=**/*_test.go +sonar.go.coverage.reportPaths=coverage.txt \ No newline at end of file diff --git a/tools.mod b/tools.mod index 2011d5c5..4fefba8a 100644 --- a/tools.mod +++ b/tools.mod @@ -4,20 +4,22 @@ go 1.26.0 tool ( github.com/Zxilly/go-size-analyzer/cmd/gsa - github.com/jstemmer/go-junit-report/v2 + github.com/vakenbolt/go-test-report go.uber.org/mock/mockgen + gotest.tools/gotestsum ) require ( - github.com/Zxilly/go-size-analyzer v1.11.0 // indirect - github.com/ZxillyFork/gore v0.0.0-20260213142603-6d34e9fbcd04 // indirect + github.com/Zxilly/go-size-analyzer v1.12.6 // indirect + github.com/ZxillyFork/gore v0.0.0-20260412044020-eb86d5eb93fc // indirect github.com/ZxillyFork/gosym v0.0.0-20240510024817-deed2b882525 // indirect github.com/ZxillyFork/trie v0.0.0-20240512061834-f75150731646 // indirect github.com/ZxillyFork/wazero v0.0.0-20260213135451-912d95480a5c // indirect - github.com/alecthomas/kong v1.14.0 // indirect + github.com/alecthomas/kong v1.15.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/bitfield/gotestdox v0.2.2 // indirect github.com/blacktop/go-dwarf v1.0.14 // indirect - github.com/blacktop/go-macho v1.1.259 // indirect + github.com/blacktop/go-macho v1.1.271 // indirect github.com/charmbracelet/bubbles v1.0.0 // indirect github.com/charmbracelet/bubbletea v1.3.10 // indirect github.com/charmbracelet/colorprofile v0.4.2 // indirect @@ -27,14 +29,20 @@ require ( github.com/charmbracelet/x/term v0.2.2 // indirect github.com/clipperhouse/displaywidth v0.10.0 // indirect github.com/clipperhouse/uax29/v2 v2.6.0 // indirect + github.com/dnephin/pflag v1.0.7 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect - github.com/go-delve/delve v1.26.0 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/go-delve/delve v1.26.2 // indirect github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e // indirect - github.com/jedib0t/go-pretty/v6 v6.7.8 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jedib0t/go-pretty/v6 v6.7.10 // indirect github.com/jstemmer/go-junit-report/v2 v2.1.0 // indirect github.com/knadh/profiler v0.2.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.19 // indirect @@ -45,17 +53,22 @@ require ( github.com/nikolaydubina/treemap v1.2.5 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect - github.com/puzpuzpuz/xsync/v4 v4.4.0 // indirect + github.com/puzpuzpuz/xsync/v4 v4.5.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect - github.com/samber/lo v1.52.0 // indirect + github.com/samber/lo v1.53.0 // indirect + github.com/spf13/cobra v1.10.2 // indirect + github.com/spf13/pflag v1.0.9 // indirect + github.com/vakenbolt/go-test-report v0.9.3 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.uber.org/mock v0.6.0 // indirect - golang.org/x/arch v0.24.0 // indirect + golang.org/x/arch v0.26.0 // indirect golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a // indirect - golang.org/x/mod v0.33.0 // indirect - golang.org/x/net v0.50.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.41.0 // indirect - golang.org/x/text v0.34.0 // indirect - golang.org/x/tools v0.42.0 // indirect + golang.org/x/mod v0.34.0 // indirect + golang.org/x/net v0.53.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.43.0 // indirect + golang.org/x/term v0.42.0 // indirect + golang.org/x/text v0.36.0 // indirect + golang.org/x/tools v0.43.0 // indirect + gotest.tools/gotestsum v1.13.0 // indirect ) diff --git a/tools.sum b/tools.sum index dcef4fe4..dfa624c7 100644 --- a/tools.sum +++ b/tools.sum @@ -1,21 +1,53 @@ -github.com/Zxilly/go-size-analyzer v1.11.0 h1:BKmUtxkr91OiZKCC4ZYeRlhxD9MKphILkL07Kq6qCwA= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Zxilly/go-size-analyzer v1.11.0/go.mod h1:vLM1cN5B2X4Unx9Vy42zEQuRhNLSWw81yzHa7eLUzyQ= -github.com/ZxillyFork/gore v0.0.0-20260213142603-6d34e9fbcd04 h1:4LX8qn3rjSfUT/ZB1EhCM7YWUM8HVVTQ21jeKYBAuaI= +github.com/Zxilly/go-size-analyzer v1.12.6 h1:Ab8BWcjtPlpnJDK/rL9hCXlZ3LyCu6qjdIFzh7F9Q7g= +github.com/Zxilly/go-size-analyzer v1.12.6/go.mod h1:ooNs4NuBQq2QA1KBMikXcd80pvJhw1vvffyeI6JMVWk= github.com/ZxillyFork/gore v0.0.0-20260213142603-6d34e9fbcd04/go.mod h1:uVJZqbYu5UZOYhtan1UAZmHvA2Erqu26xyXmGd3iMJo= +github.com/ZxillyFork/gore v0.0.0-20260412044020-eb86d5eb93fc h1:Y2WGJCe0Q4i/0rGD7FDuIdaxJAyshtRzJGnQPzt0c8Y= +github.com/ZxillyFork/gore v0.0.0-20260412044020-eb86d5eb93fc/go.mod h1:I0Y7VIJq/56APMh8okdsvzhQBpuow+qTatIJ4KxEBCg= github.com/ZxillyFork/gosym v0.0.0-20240510024817-deed2b882525 h1:JtN7QBnRxeyMvDJjVdfjhGHL/msqqapHMG5jPVYh32A= github.com/ZxillyFork/gosym v0.0.0-20240510024817-deed2b882525/go.mod h1:AC2xDL/KBa60pBB/m0zRCDCGvzLrMkmW/aY0q+uThFE= github.com/ZxillyFork/trie v0.0.0-20240512061834-f75150731646 h1:Mkm17zXN+CiAXdV9/7mdCUGuEzlUNu73mB6En++kUkE= github.com/ZxillyFork/trie v0.0.0-20240512061834-f75150731646/go.mod h1:wbU6+GbSHDwVSMpzFyOVrX/WdFHXH4j7j8Rg8rbyo+4= github.com/ZxillyFork/wazero v0.0.0-20260213135451-912d95480a5c h1:r0eP8znpjJiKZtqOYHKYKm69YPIog9TRCMvqPxYClSg= github.com/ZxillyFork/wazero v0.0.0-20260213135451-912d95480a5c/go.mod h1:Rw5frKNwhtjt+nzSkqdoc1rK3FzZ572CrRpoqCFqD84= -github.com/alecthomas/kong v1.14.0 h1:gFgEUZWu2ZmZ+UhyZ1bDhuutbKN1nTtJTwh19Wsn21s= github.com/alecthomas/kong v1.14.0/go.mod h1:wrlbXem1CWqUV5Vbmss5ISYhsVPkBb1Yo7YKJghju2I= +github.com/alecthomas/kong v1.15.0 h1:BVJstKbpO73zKpmIu+m/aLRrNmWwxXPIGTNin9VmLVI= +github.com/alecthomas/kong v1.15.0/go.mod h1:wrlbXem1CWqUV5Vbmss5ISYhsVPkBb1Yo7YKJghju2I= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 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/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitfield/gotestdox v0.2.2 h1:x6RcPAbBbErKLnapz1QeAlf3ospg8efBsedU93CDsnE= +github.com/bitfield/gotestdox v0.2.2/go.mod h1:D+gwtS0urjBrzguAkTM2wodsTQYFHdpx8eqRJ3N+9pY= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blacktop/go-dwarf v1.0.14 h1:OjmzfSgg/qAKckn2tWFebcgKgJ7HOqCj7bS+CiE1lrY= github.com/blacktop/go-dwarf v1.0.14/go.mod h1:4W2FKgSFYcZLDwnR7k+apv5i3nrau4NGl9N6VQ9DSTo= -github.com/blacktop/go-macho v1.1.259 h1:SGavv9QY1qKSuTq6lBG6T/243Vq4SFSb1InYyVO1w5I= github.com/blacktop/go-macho v1.1.259/go.mod h1:Hc5E2Lvt/U1VT+jOxr1O5l/LNFJeMYK4eAmDfazTiGc= +github.com/blacktop/go-macho v1.1.271 h1:KpC13blu4m1LVUv3WPU3a73u1xNFapDeA4UJp/J0aG4= +github.com/blacktop/go-macho v1.1.271/go.mod h1:Hc5E2Lvt/U1VT+jOxr1O5l/LNFJeMYK4eAmDfazTiGc= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc= github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= @@ -30,27 +62,121 @@ github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMx github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/clipperhouse/displaywidth v0.10.0 h1:GhBG8WuerxjFQQYeuZAeVTuyxuX+UraiZGD4HJQ3Y8g= github.com/clipperhouse/displaywidth v0.10.0/go.mod h1:XqJajYsaiEwkxOj4bowCTMcT1SgvHo9flfF3jQasdbs= github.com/clipperhouse/uax29/v2 v2.6.0 h1:z0cDbUV+aPASdFb2/ndFnS9ts/WNXgTNNGFoKXuhpos= github.com/clipperhouse/uax29/v2 v2.6.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= +github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= -github.com/go-delve/delve v1.26.0 h1:YZT1kXD76mxba4/wr+tyUa/tSmy7qzoDsmxutT42PIs= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-delve/delve v1.26.0/go.mod h1:8BgFFOXTi1y1M+d/4ax1LdFw0mlqezQiTZQpbpwgBxo= -github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e h1:Lf/gRkoycfOBPa42vU2bbgPurFong6zXeFtPoxholzU= +github.com/go-delve/delve v1.26.2 h1:YmqVunuA/MLzv6IcW/UnS5aBkAdfB/DBuH9LQpb51JE= +github.com/go-delve/delve v1.26.2/go.mod h1:Ua/k2AAu4cLrUXGSRVH1b2Nzq2aCK188b9EYlAojlz4= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e/go.mod h1:uNVvRXArCGbZ508SxYYTC5v1JWoz2voff5pm25jU1Ok= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/jedib0t/go-pretty/v6 v6.7.8 h1:BVYrDy5DPBA3Qn9ICT+PokP9cvCv1KaHv2i+Hc8sr5o= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jedib0t/go-pretty/v6 v6.7.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= -github.com/jstemmer/go-junit-report/v2 v2.1.0 h1:X3+hPYlSczH9IMIpSC9CQSZA0L+BipYafciZUWHEmsc= +github.com/jedib0t/go-pretty/v6 v6.7.10 h1:B/2qW2Bkv2L6n14PP8o1kx75kWzHOQ3YTluWzg9icac= +github.com/jedib0t/go-pretty/v6 v6.7.10/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report/v2 v2.1.0/go.mod h1:mgHVr7VUo5Tn8OLVr1cKnLuEy0M92wdRntM99h7RkgQ= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/knadh/profiler v0.2.0 h1:jaY0xlQs8iaWxKdvGHOftaZnX7d8l7yrCGQPSecwnng= github.com/knadh/profiler v0.2.0/go.mod h1:LqNkAu++MfFkbEDA63AmRaIf6UkGrLXyZ5VQQdekZiI= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= @@ -58,6 +184,18 @@ github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+Ei github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= @@ -66,40 +204,238 @@ github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nikolaydubina/treemap v1.2.5 h1:oSC5z/qnsGLbkU2IihSrh2pS7uDjUq7ipGj8aw8bfII= github.com/nikolaydubina/treemap v1.2.5/go.mod h1:8+wLGh917AyeJqBN1D5KM26tv6W/XfvsY+nfJd04/u8= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 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/puzpuzpuz/xsync/v4 v4.4.0 h1:vlSN6/CkEY0pY8KaB0yqo/pCLZvp9nhdbBdjipT4gWo= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/puzpuzpuz/xsync/v4 v4.4.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo= +github.com/puzpuzpuz/xsync/v4 v4.5.0 h1:vOSWu6b57/emh+L/Cw0BeQfvxa/cogFywXHeGUxQxAg= +github.com/puzpuzpuz/xsync/v4 v4.5.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= +github.com/samber/lo v1.53.0 h1:t975lj2py4kJPQ6haz1QMgtId2gtmfktACxIXArw3HM= +github.com/samber/lo v1.53.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +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/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +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/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/vakenbolt/go-test-report v0.9.3 h1:KPJIZJhr3CKdk82+6KD/LnLF89lvW8aklyRqOjlPJRQ= +github.com/vakenbolt/go-test-report v0.9.3/go.mod h1:sSBCeKCZsuw8Ph983JpYkuEe4fWteYI3YdAtZr9FNds= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= -golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.24.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= +golang.org/x/arch v0.26.0 h1:jZ6dpec5haP/fUv1kLCbuJy6dnRrfX6iVK08lZBFpk4= +golang.org/x/arch v0.26.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a h1:ovFr6Z0MNmU7nH8VaX5xqw+05ST2uO1exVfZPVqRC5o= golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= -golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= +golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/gotestsum v1.13.0 h1:+Lh454O9mu9AMG1APV4o0y7oDYKyik/3kBOiCqiEpRo= +gotest.tools/gotestsum v1.13.0/go.mod h1:7f0NS5hFb0dWr4NtcsAsF0y1kzjEFfAil0HiBQJE03Q= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=