mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
Remove refactored source files
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
name: CI
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
run-test:
|
||||
timeout-minutes: 15
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
|
||||
with:
|
||||
go-version: 1.24
|
||||
check-latest: true
|
||||
|
||||
- name: Build and Test
|
||||
run: |
|
||||
go mod tidy
|
||||
go build
|
||||
go test -coverprofile=coverage.txt -v ./...
|
||||
|
||||
- name: Upload Coverage
|
||||
if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || github.event_name == 'push'
|
||||
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
build-container-test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- name: Setup QEMU
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
|
||||
|
||||
- name: Build Container Image
|
||||
run: |
|
||||
docker buildx build --platform linux/amd64 --platform linux/arm64 --load \
|
||||
-t build-container-test:latest .
|
||||
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
FROM --platform=$BUILDPLATFORM golang:1.24-bullseye@sha256:3c669c8fed069d80d199073b806243c4bf79ad117b797b96f18177ad9c521cff AS build
|
||||
# Original: golang:1.24-bullseye
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
|
||||
RUN go mod download
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN make
|
||||
|
||||
FROM debian:11-slim@sha256:e4b93db6aad977a95aa103917f3de8a2b16ead91cf255c3ccdb300c5d20f3015
|
||||
# Original: debian:11-slim
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
LABEL org.opencontainers.image.source=https://github.com/safedep/pmg
|
||||
LABEL org.opencontainers.image.description="Package Manager Guard to protect against malicious open source packages"
|
||||
LABEL org.opencontainers.image.licenses=Apache-2.0
|
||||
|
||||
COPY --from=build /build/bin/pmg /usr/local/bin/pmg
|
||||
|
||||
ENTRYPOINT ["pmg"]
|
||||
@@ -10,7 +10,6 @@ require (
|
||||
github.com/fatih/color v1.18.0
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.7
|
||||
github.com/safedep/dry v0.0.0-20250514080944-bb77f30c7175
|
||||
github.com/safedep/vet v1.10.1
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
google.golang.org/grpc v1.71.1
|
||||
@@ -19,79 +18,53 @@ require (
|
||||
require (
|
||||
4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
|
||||
4d63.com/gochecknoglobals v0.2.2 // indirect
|
||||
ariga.io/atlas v0.32.0 // indirect
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250307204501-0409229c3780.1 // indirect
|
||||
entgo.io/ent v0.14.4 // indirect
|
||||
github.com/4meepo/tagalign v1.4.2 // indirect
|
||||
github.com/Abirdcfly/dupword v0.1.3 // indirect
|
||||
github.com/Antonboom/errname v1.0.0 // indirect
|
||||
github.com/Antonboom/nilnil v1.0.1 // indirect
|
||||
github.com/Antonboom/testifylint v1.5.2 // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect
|
||||
github.com/CloudyKit/jet/v6 v6.3.1 // indirect
|
||||
github.com/Crocmagnon/fatcontext v0.7.1 // indirect
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
|
||||
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 // indirect
|
||||
github.com/Joker/jade v1.1.3 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.1 // indirect
|
||||
github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect
|
||||
github.com/Shopify/goreferrer v0.0.0-20240724165105-aceaa0259138 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/alecthomas/go-check-sumtype v0.3.1 // indirect
|
||||
github.com/alexkohler/nakedret/v2 v2.0.5 // indirect
|
||||
github.com/alexkohler/prealloc v1.0.0 // indirect
|
||||
github.com/alingse/asasalint v0.0.11 // indirect
|
||||
github.com/alingse/nilnesserr v0.1.2 // indirect
|
||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/ashanbrown/forbidigo v1.6.0 // indirect
|
||||
github.com/ashanbrown/makezero v1.2.0 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bkielbasa/cyclop v1.2.3 // indirect
|
||||
github.com/blizzy78/varnamelen v0.8.0 // indirect
|
||||
github.com/bmatcuk/doublestar v1.3.4 // indirect
|
||||
github.com/bombsimon/wsl/v4 v4.5.0 // indirect
|
||||
github.com/breml/bidichk v0.3.2 // indirect
|
||||
github.com/breml/errchkjson v0.4.0 // indirect
|
||||
github.com/butuzov/ireturn v0.3.1 // indirect
|
||||
github.com/butuzov/mirror v1.3.0 // indirect
|
||||
github.com/bytedance/sonic v1.13.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
||||
github.com/catenacyber/perfsprint v0.8.2 // indirect
|
||||
github.com/ccojocar/zxcvbn-go v1.0.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/charithe/durationcheck v0.0.10 // indirect
|
||||
github.com/chavacava/garif v0.1.0 // indirect
|
||||
github.com/ckaznocha/intrange v0.3.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||
github.com/curioswitch/go-reassign v0.3.0 // indirect
|
||||
github.com/daixiang0/gci v0.13.5 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/deepmap/oapi-codegen v1.16.3 // indirect
|
||||
github.com/denis-tingaikin/go-header v0.5.0 // indirect
|
||||
github.com/dlclark/regexp2 v1.11.4 // indirect
|
||||
github.com/ettle/strcase v0.2.0 // indirect
|
||||
github.com/fatih/structs v1.1.0 // indirect
|
||||
github.com/fatih/structtag v1.2.0 // indirect
|
||||
github.com/firefart/nonamedreturns v1.0.5 // indirect
|
||||
github.com/flosch/pongo2/v4 v4.0.2 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/fzipp/gocyclo v0.6.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
|
||||
github.com/ghostiam/protogetter v0.3.9 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/gin-gonic/gin v1.10.0 // indirect
|
||||
github.com/gkampitakis/go-snaps v0.5.11 // indirect
|
||||
github.com/go-critic/go-critic v0.12.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/inflect v0.21.2 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.26.0 // indirect
|
||||
github.com/go-test/deep v1.1.1 // indirect
|
||||
github.com/go-toolsmith/astcast v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astcopy v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astequal v1.2.0 // indirect
|
||||
@@ -102,9 +75,7 @@ require (
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/gofrs/flock v0.12.1 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect
|
||||
github.com/golangci/go-printf-func-name v0.1.0 // indirect
|
||||
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect
|
||||
@@ -113,14 +84,11 @@ require (
|
||||
github.com/golangci/plugin-module-register v0.1.1 // indirect
|
||||
github.com/golangci/revgrep v0.8.0 // indirect
|
||||
github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect
|
||||
github.com/gomarkdown/markdown v0.0.0-20250311123330-531bef5e742b // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/go-github/v70 v70.0.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/osv-scanner v1.9.2 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20250418163039-24c5476c6587 // indirect
|
||||
github.com/gordonklaus/ineffassign v0.1.0 // indirect
|
||||
github.com/gorilla/css v1.0.1 // indirect
|
||||
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
|
||||
github.com/gostaticanalysis/comment v1.5.0 // indirect
|
||||
github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
|
||||
@@ -129,42 +97,26 @@ require (
|
||||
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.23.0 // indirect
|
||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/iris-contrib/schema v0.0.6 // indirect
|
||||
github.com/jgautheron/goconst v1.7.1 // indirect
|
||||
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
|
||||
github.com/jjti/go-spancheck v0.6.4 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/julz/importas v0.2.0 // indirect
|
||||
github.com/karamaru-alpha/copyloopvar v1.2.1 // indirect
|
||||
github.com/kataras/blocks v0.0.11 // indirect
|
||||
github.com/kataras/golog v0.1.13 // indirect
|
||||
github.com/kataras/iris/v12 v12.2.11 // indirect
|
||||
github.com/kataras/pio v0.0.14 // indirect
|
||||
github.com/kataras/sitemap v0.0.6 // indirect
|
||||
github.com/kataras/tunnel v0.0.4 // indirect
|
||||
github.com/kisielk/errcheck v1.9.0 // indirect
|
||||
github.com/kkHAIKE/contextcheck v1.1.6 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||
github.com/kulti/thelper v0.6.3 // indirect
|
||||
github.com/kunwardeep/paralleltest v1.0.10 // indirect
|
||||
github.com/labstack/echo/v4 v4.13.3 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/lasiar/canonicalheader v1.1.2 // indirect
|
||||
github.com/ldez/exptostd v0.4.2 // indirect
|
||||
github.com/ldez/gomoddirectives v0.6.1 // indirect
|
||||
github.com/ldez/grignotin v0.9.0 // indirect
|
||||
github.com/ldez/tagliatelle v0.7.1 // indirect
|
||||
github.com/ldez/usetesting v0.4.2 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/leonklingele/grouper v1.1.2 // indirect
|
||||
github.com/macabu/inamedparam v0.1.3 // indirect
|
||||
github.com/mailgun/raymond/v2 v2.0.48 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/maratori/testableexamples v1.0.0 // indirect
|
||||
github.com/maratori/testpackage v1.1.1 // indirect
|
||||
github.com/matoous/godox v1.1.0 // indirect
|
||||
@@ -172,11 +124,7 @@ require (
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mgechev/revive v1.7.0 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/moricho/tparallel v0.3.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/nakabonne/nestif v0.3.1 // indirect
|
||||
@@ -184,7 +132,6 @@ require (
|
||||
github.com/nishanths/predeclared v0.2.2 // indirect
|
||||
github.com/nunnatsa/ginkgolinter v0.19.1 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/package-url/packageurl-go v0.1.3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/polyfloyd/go-errorlint v1.7.1 // indirect
|
||||
@@ -200,16 +147,13 @@ require (
|
||||
github.com/raeperd/recvcheck v0.2.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/ryancurrah/gomodguard v1.3.5 // indirect
|
||||
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
|
||||
github.com/sagikazarmark/locafero v0.9.0 // indirect
|
||||
github.com/sanity-io/litter v1.5.8 // indirect
|
||||
github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect
|
||||
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
|
||||
github.com/sashamelentyev/usestdlibvars v1.28.0 // indirect
|
||||
github.com/schollz/closestmatch v2.1.0+incompatible // indirect
|
||||
github.com/securego/gosec/v2 v2.22.2 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/sivchari/containedctx v1.0.3 // indirect
|
||||
@@ -226,30 +170,19 @@ require (
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/tdakkota/asciicheck v0.4.1 // indirect
|
||||
github.com/tdewolff/minify/v2 v2.23.1 // indirect
|
||||
github.com/tdewolff/parse/v2 v2.7.23 // indirect
|
||||
github.com/tetafro/godot v1.5.0 // indirect
|
||||
github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 // indirect
|
||||
github.com/timonwong/loggercheck v0.10.1 // indirect
|
||||
github.com/tomarrell/wrapcheck/v2 v2.10.0 // indirect
|
||||
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/ultraware/funlen v0.2.0 // indirect
|
||||
github.com/ultraware/whitespace v0.2.0 // indirect
|
||||
github.com/uudashr/gocognit v1.2.0 // indirect
|
||||
github.com/uudashr/iface v1.3.1 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/xen0n/gosmopolitan v1.2.2 // indirect
|
||||
github.com/yagipy/maintidx v1.0.0 // indirect
|
||||
github.com/yeya24/promlinter v0.3.0 // indirect
|
||||
github.com/ykadowak/zerologlint v0.1.5 // indirect
|
||||
github.com/yosssi/ace v0.0.5 // indirect
|
||||
github.com/zclconf/go-cty v1.16.2 // indirect
|
||||
github.com/zclconf/go-cty-yaml v1.1.0 // indirect
|
||||
gitlab.com/bosi/decorder v0.4.2 // indirect
|
||||
go-simpler.org/musttag v0.13.0 // indirect
|
||||
go-simpler.org/sloglint v0.9.0 // indirect
|
||||
@@ -261,8 +194,6 @@ require (
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/arch v0.16.0 // indirect
|
||||
golang.org/x/crypto v0.37.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
@@ -271,11 +202,9 @@ require (
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/term v0.31.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/tools v0.32.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
4d63.com/gocheckcompilerdirectives v1.3.0/go.mod h1:ofsJ4zx2QAuIP/NO/NAh1ig6R1Fb18/GI7RVMwz7kAY=
|
||||
4d63.com/gochecknoglobals v0.2.2 h1:H1vdnwnMaZdQW/N+NrkT1SZMTBmcwHe9Vq8lJcYYTtU=
|
||||
4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=
|
||||
ariga.io/atlas v0.32.0 h1:y+77nueMrExLiKlz1CcPKh/nU7VSlWfBbwCShsJyvCw=
|
||||
ariga.io/atlas v0.32.0/go.mod h1:Oe1xWPuu5q9LzyrWfbZmEZxFYeu4BHTyzfjeW2aZp/w=
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250307204501-0409229c3780.1 h1:zgJPqo17m28+Lf5BW4xv3PvU20BnrmTcGYrog22lLIU=
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250307204501-0409229c3780.1/go.mod h1:avRlCjnFzl98VPaeCtJ24RrV/wwHFzB8sWXhj26+n/U=
|
||||
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20250418165058-162f6b0cc319.2 h1:txDywYkqsXvtA/sDSMcwMjC8XTHnqlyc+3aIFMzRVeQ=
|
||||
@@ -11,8 +9,6 @@ buf.build/gen/go/safedep/api/grpc/go v1.5.1-20250418165058-162f6b0cc319.2/go.mod
|
||||
buf.build/gen/go/safedep/api/protocolbuffers/go v1.36.6-20250418165058-162f6b0cc319.1 h1:vJeI1IQuxGZd9r5RHNiLTJ+aPQfy0g7h3Gqa9/Ql7kA=
|
||||
buf.build/gen/go/safedep/api/protocolbuffers/go v1.36.6-20250418165058-162f6b0cc319.1/go.mod h1:uR95GqsnNCRn6cTyRBte6uMJMm0rEBRxTGpakKCNL9I=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
entgo.io/ent v0.14.4 h1:/DhDraSLXIkBhyiVoJeSshr4ZYi7femzhj6/TckzZuI=
|
||||
entgo.io/ent v0.14.4/go.mod h1:aDPE/OziPEu8+OWbzy4UlvWmD2/kbRuWfK2A40hcxJM=
|
||||
github.com/4meepo/tagalign v1.4.2 h1:0hcLHPGMjDyM1gHG58cS73aQF8J4TdVR96TZViorO9E=
|
||||
github.com/4meepo/tagalign v1.4.2/go.mod h1:+p4aMyFM+ra7nb41CnFG6aSDXqRxU/w1VQqScKqDARI=
|
||||
github.com/Abirdcfly/dupword v0.1.3 h1:9Pa1NuAsZvpFPi9Pqkd93I7LIYRURj+A//dFd5tgBeE=
|
||||
@@ -26,35 +22,16 @@ github.com/Antonboom/testifylint v1.5.2/go.mod h1:vxy8VJ0bc6NavlYqjZfmp6EfqXMtBg
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c=
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
||||
github.com/CloudyKit/jet/v6 v6.3.1 h1:6IAo5Cx21xrHVaR8zzXN5gJatKV/wO7Nf6bfCnCSbUw=
|
||||
github.com/CloudyKit/jet/v6 v6.3.1/go.mod h1:lf8ksdNsxZt7/yH/3n4vJQWA9RUq4wpaHtArHhGVMOw=
|
||||
github.com/Crocmagnon/fatcontext v0.7.1 h1:SC/VIbRRZQeQWj/TcQBS6JmrXcfA+BU4OGSVUt54PjM=
|
||||
github.com/Crocmagnon/fatcontext v0.7.1/go.mod h1:1wMvv3NXEBJucFGfwOJBxSVWcoIO6emV215SMkW9MFU=
|
||||
github.com/CycloneDX/cyclonedx-go v0.9.2 h1:688QHn2X/5nRezKe2ueIVCt+NRqf7fl3AVQk+vaFcIo=
|
||||
github.com/CycloneDX/cyclonedx-go v0.9.2/go.mod h1:vcK6pKgO1WanCdd61qx4bFnSsDJQ6SbM2ZuMIgq86Jg=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
||||
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 h1:Sz1JIXEcSfhz7fUi7xHnhpIE0thVASYjvosApmHuD2k=
|
||||
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1/go.mod h1:n/LSCXNuIYqVfBlVXyHfMQkZDdp1/mmxfSjADd3z1Zg=
|
||||
github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc=
|
||||
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
|
||||
github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk=
|
||||
github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM=
|
||||
github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
|
||||
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/OpenPeeDeeP/depguard/v2 v2.2.1 h1:vckeWVESWp6Qog7UZSARNqfu/cZqvki8zsuj3piCMx4=
|
||||
github.com/OpenPeeDeeP/depguard/v2 v2.2.1/go.mod h1:q4DKzC4UcVaAvcfd41CZh0PWpGgzrVxUYBlgKNGquUo=
|
||||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||
github.com/Shopify/goreferrer v0.0.0-20240724165105-aceaa0259138 h1:gjbp60h8IZQbN/TpDaYJedWbbD1h1aDPEwWnYWaDaUY=
|
||||
github.com/Shopify/goreferrer v0.0.0-20240724165105-aceaa0259138/go.mod h1:NYezi6wtnJtBm5btoprXc5SvAdqH0XTXWnUup0MptAI=
|
||||
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
||||
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/go-check-sumtype v0.3.1 h1:u9aUvbGINJxLVXiFvHUlPEaD7VDULsrxJb4Aq31NLkU=
|
||||
@@ -69,18 +46,10 @@ github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQ
|
||||
github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
|
||||
github.com/alingse/nilnesserr v0.1.2 h1:Yf8Iwm3z2hUUrP4muWfW83DF4nE3r1xZ26fGWUKCZlo=
|
||||
github.com/alingse/nilnesserr v0.1.2/go.mod h1:1xJPrXonEtX7wyTq8Dytns5P2hNzoWymVUIaKm4HNFg=
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8gerOIVIY=
|
||||
github.com/ashanbrown/forbidigo v1.6.0/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU=
|
||||
github.com/ashanbrown/makezero v1.2.0 h1:/2Lp1bypdmK9wDIq7uWBlDF1iMUpIIS4A+pF6C9IEUU=
|
||||
github.com/ashanbrown/makezero v1.2.0/go.mod h1:dxlPhHbDMC6N6xICzFBSK+4njQDdK8euNO0qjQMtGY4=
|
||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
@@ -88,9 +57,6 @@ github.com/bkielbasa/cyclop v1.2.3 h1:faIVMIGDIANuGPWH031CZJTi2ymOQBULs9H21HSMa5
|
||||
github.com/bkielbasa/cyclop v1.2.3/go.mod h1:kHTwA9Q0uZqOADdupvcFJQtp/ksSnytRMe8ztxG8Fuo=
|
||||
github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M=
|
||||
github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=
|
||||
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
||||
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
|
||||
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
|
||||
github.com/bombsimon/wsl/v4 v4.5.0 h1:iZRsEvDdyhd2La0FVi5k6tYehpOR/R7qIUjmKk7N74A=
|
||||
github.com/bombsimon/wsl/v4 v4.5.0/go.mod h1:NOQ3aLF4nD7N5YPXMruR6ZXDOAqLoM0GEpLwTdvmOSc=
|
||||
github.com/breml/bidichk v0.3.2 h1:xV4flJ9V5xWTqxL+/PMFF6dtJPvZLPsyixAoPe8BGJs=
|
||||
@@ -101,11 +67,6 @@ github.com/butuzov/ireturn v0.3.1 h1:mFgbEI6m+9W8oP/oDdfA34dLisRFCj2G6o/yiI1yZrY
|
||||
github.com/butuzov/ireturn v0.3.1/go.mod h1:ZfRp+E7eJLC0NQmk1Nrm1LOrn/gQlOykv+cVPdiXH5M=
|
||||
github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc=
|
||||
github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI=
|
||||
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
||||
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
|
||||
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/catenacyber/perfsprint v0.8.2 h1:+o9zVmCSVa7M4MvabsWvESEhpsMkhfE7k0sHNGL95yw=
|
||||
github.com/catenacyber/perfsprint v0.8.2/go.mod h1:q//VWC2fWbcdSLEY1R3l8n0zQCDPdE4IjZwyY1HMunM=
|
||||
github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg=
|
||||
@@ -120,22 +81,16 @@ github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+U
|
||||
github.com/ckaznocha/intrange v0.3.0 h1:VqnxtK32pxgkhJgYQEeOArVidIPg+ahLP7WBOXZd5ZY=
|
||||
github.com/ckaznocha/intrange v0.3.0/go.mod h1:+I/o2d2A1FBHgGELbGxzIcyd3/9l9DuwjM8FsbSS3Lo=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/curioswitch/go-reassign v0.3.0 h1:dh3kpQHuADL3cobV/sSGETA8DOv457dwl+fbBAhrQPs=
|
||||
github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88=
|
||||
github.com/daixiang0/gci v0.13.5 h1:kThgmH1yBmZSBCh1EJVxQ7JsHpm5Oms0AMed/0LaH4c=
|
||||
github.com/daixiang0/gci v0.13.5/go.mod h1:12etP2OniiIdP4q+kjUGrC/rUagga7ODbqsom5Eo5Yk=
|
||||
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deepmap/oapi-codegen v1.16.3 h1:GT9G86SbQtT1r8ZB+4Cybi9VGdu1P5ieNvNdEoCSbrA=
|
||||
github.com/deepmap/oapi-codegen v1.16.3/go.mod h1:JD6ErqeX0nYnhdciLc61Konj3NBASREMlkHOgHn8WAM=
|
||||
github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8=
|
||||
github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY=
|
||||
github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
|
||||
@@ -148,34 +103,18 @@ github.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q=
|
||||
github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
|
||||
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
|
||||
github.com/firefart/nonamedreturns v1.0.5 h1:tM+Me2ZaXs8tfdDw3X6DOX++wMCOqzYUho6tUTYIdRA=
|
||||
github.com/firefart/nonamedreturns v1.0.5/go.mod h1:gHJjDqhGM4WyPt639SOZs+G89Ko7QKH5R5BhnO6xJhw=
|
||||
github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw=
|
||||
github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
|
||||
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
|
||||
github.com/ghostiam/protogetter v0.3.9 h1:j+zlLLWzqLay22Cz/aYwTHKQ88GE2DQ6GkWSYFOI4lQ=
|
||||
github.com/ghostiam/protogetter v0.3.9/go.mod h1:WZ0nw9pfzsgxuRsPOFQomgDVSWtDLJRfQJEhsGbmQMA=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/gkampitakis/ciinfo v0.3.1 h1:lzjbemlGI4Q+XimPg64ss89x8Mf3xihJqy/0Mgagapo=
|
||||
github.com/gkampitakis/ciinfo v0.3.1/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
|
||||
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
|
||||
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
|
||||
github.com/gkampitakis/go-snaps v0.5.11 h1:LFG0ggUKR+KEiiaOvFCmLgJ5NO2zf93AxxddkBn3LdQ=
|
||||
github.com/gkampitakis/go-snaps v0.5.11/go.mod h1:PcKmy8q5Se7p48ywpogN5Td13reipz1Iivah4wrTIvY=
|
||||
github.com/go-critic/go-critic v0.12.0 h1:iLosHZuye812wnkEz1Xu3aBwn5ocCPfc9yqmFG9pa6w=
|
||||
github.com/go-critic/go-critic v0.12.0/go.mod h1:DpE0P6OVc6JzVYzmM5gq5jMU31zLr4am5mB/VfFK64w=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
@@ -185,23 +124,11 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/inflect v0.21.2 h1:0gClGlGcxifcJR56zwvhaOulnNgnhc4qTAkob5ObnSM=
|
||||
github.com/go-openapi/inflect v0.21.2/go.mod h1:INezMuUu7SJQc2AyR3WO0DqqYUJSj8Kb4hBd7WtjlAw=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
|
||||
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
|
||||
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
|
||||
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8=
|
||||
github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=
|
||||
github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s=
|
||||
@@ -227,10 +154,6 @@ github.com/go-xmlfmt/xmlfmt v1.1.3 h1:t8Ey3Uy7jDSEisW2K3somuMKIpzktkWptA0iFCnRUW
|
||||
github.com/go-xmlfmt/xmlfmt v1.1.3/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.15.13 h1:Xd87Yddmr2rC1SLLTm2MNDcTjeO/GYo0JGiww6gSTDg=
|
||||
github.com/goccy/go-yaml v1.15.13/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
|
||||
github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
@@ -241,8 +164,6 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 h1:WUvBfQL6EW/40l6OmeSBYQJNSif4O11+bmWEz+C7FYw=
|
||||
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32/go.mod h1:NUw9Zr2Sy7+HxzdjIULge71wI6yEg1lWQr7Evcu8K0E=
|
||||
github.com/golangci/go-printf-func-name v0.1.0 h1:dVokQP+NMTO7jwO4bwsRwLWeudOVUPPyAKJuzv8pEJU=
|
||||
@@ -259,8 +180,6 @@ github.com/golangci/revgrep v0.8.0 h1:EZBctwbVd0aMeRnNUsFogoyayvKHyxlV3CdUA46FX2
|
||||
github.com/golangci/revgrep v0.8.0/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k=
|
||||
github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed h1:IURFTjxeTfNFP0hTEi1YKjB/ub8zkpaOqFFMApi2EAs=
|
||||
github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed/go.mod h1:XLXN8bNw4CGRPaqgl3bv/lhz7bsGPh4/xSaMTbo2vkQ=
|
||||
github.com/gomarkdown/markdown v0.0.0-20250311123330-531bef5e742b h1:EY/KpStFl60qA17CptGXhwfZ+k1sFNJIUNR8DdbcuUk=
|
||||
github.com/gomarkdown/markdown v0.0.0-20250311123330-531bef5e742b/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
@@ -273,19 +192,12 @@ github.com/google/go-github/v70 v70.0.0 h1:/tqCp5KPrcvqCc7vIvYyFYTiCGrYvaWoYMGHS
|
||||
github.com/google/go-github/v70 v70.0.0/go.mod h1:xBUZgo8MI3lUL/hwxl3hlceJW1U8MVnXP3zUyI+rhQY=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/osv-scanner v1.9.2 h1:N5Arl9SA75afbjmX8mKURgOIaKyuK3NUjCaxDlj1KHI=
|
||||
github.com/google/osv-scanner v1.9.2/go.mod h1:ZTL8Dp9z/7Jr9kkQSOGqo8z6Csqt83qMIr58aZVx+pM=
|
||||
github.com/google/pprof v0.0.0-20250418163039-24c5476c6587 h1:b/8HpQhvKLSNzH5oTXN2WkNcMl6YB5K3FRbb+i+Ml34=
|
||||
github.com/google/pprof v0.0.0-20250418163039-24c5476c6587/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s=
|
||||
github.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=
|
||||
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
||||
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=
|
||||
github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
|
||||
github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
|
||||
@@ -310,18 +222,10 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe
|
||||
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/hcl/v2 v2.23.0 h1:Fphj1/gCylPxHutVSEOf2fBOh1VE4AuLV7+kbJf3qos=
|
||||
github.com/hashicorp/hcl/v2 v2.23.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
|
||||
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/iris-contrib/httpexpect/v2 v2.15.2 h1:T9THsdP1woyAqKHwjkEsbCnMefsAFvk8iJJKokcJ3Go=
|
||||
github.com/iris-contrib/httpexpect/v2 v2.15.2/go.mod h1:JLDgIqnFy5loDSUv1OA2j0mb6p/rDhiCqigP22Uq9xE=
|
||||
github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw=
|
||||
github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.7 h1:m+LbHpm0aIAPLzLbMfn8dc3Ht8MW7lsSO4MPItz/Uuo=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.7/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU=
|
||||
github.com/jgautheron/goconst v1.7.1 h1:VpdAG7Ca7yvvJk5n8dMwQhfEZJh95kl/Hl9S1OI5Jkk=
|
||||
@@ -330,27 +234,10 @@ github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjz
|
||||
github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
|
||||
github.com/jjti/go-spancheck v0.6.4 h1:Tl7gQpYf4/TMU7AT84MN83/6PutY21Nb9fuQjFTpRRc=
|
||||
github.com/jjti/go-spancheck v0.6.4/go.mod h1:yAEYdKJ2lRkDA8g7X+oKUHXOWVAXSBJRv04OhF+QUjk=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
|
||||
github.com/julz/importas v0.2.0 h1:y+MJN/UdL63QbFJHws9BVC5RpA2iq0kpjrFajTGivjQ=
|
||||
github.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx3xiJY=
|
||||
github.com/karamaru-alpha/copyloopvar v1.2.1 h1:wmZaZYIjnJ0b5UoKDjUHrikcV0zuPyyxI4SVplLd2CI=
|
||||
github.com/karamaru-alpha/copyloopvar v1.2.1/go.mod h1:nFmMlFNlClC2BPvNaHMdkirmTJxVCY0lhxBtlfOypMM=
|
||||
github.com/kataras/blocks v0.0.11 h1:JJdYW0AUaJKLx5kEWs/oRVCvKVXo+6CAAeaVAiJf7wE=
|
||||
github.com/kataras/blocks v0.0.11/go.mod h1:b4UySrJySEOq6drKH9U3bOpMI+dRH148mayYfS3RFb8=
|
||||
github.com/kataras/golog v0.1.13 h1:bGbPglTdCutekqwOUf8L1jq3tZ5ADG9gfPBd5p5SzKA=
|
||||
github.com/kataras/golog v0.1.13/go.mod h1:oQmzBTCv/35TetBosjJl/k+LPdlJEblaTupkNwJlwj8=
|
||||
github.com/kataras/iris/v12 v12.2.11 h1:sGgo43rMPfzDft8rjVhPs6L3qDJy3TbBrMD/zGL1pzk=
|
||||
github.com/kataras/iris/v12 v12.2.11/go.mod h1:uMAeX8OqG9vqdhyrIPv8Lajo/wXTtAF43wchP9WHt2w=
|
||||
github.com/kataras/pio v0.0.14 h1:VGBHOmhwrMMrZeuRqoSfOrFwG+v1JxQge8N50DhmRYQ=
|
||||
github.com/kataras/pio v0.0.14/go.mod h1:ZIlcw5+5Zyb/kOlU7X4uosZ8dbnXmA4GcGKt1XyyTY0=
|
||||
github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY=
|
||||
github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4=
|
||||
github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA=
|
||||
github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/errcheck v1.9.0 h1:9xt1zI9EBfcYBvdU1nVrzMzzUPUtPKs9bVSIM3TAb3M=
|
||||
github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8=
|
||||
@@ -359,10 +246,6 @@ github.com/kkHAIKE/contextcheck v1.1.6 h1:7HIyRcnyzxL9Lz06NGhiKvenXq7Zw6Q0UQu/tt
|
||||
github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
@@ -375,10 +258,6 @@ github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs=
|
||||
github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I=
|
||||
github.com/kunwardeep/paralleltest v1.0.10 h1:wrodoaKYzS2mdNVnc4/w31YaXFtsc21PCTdvWJ/lDDs=
|
||||
github.com/kunwardeep/paralleltest v1.0.10/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY=
|
||||
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
|
||||
github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||
github.com/lasiar/canonicalheader v1.1.2 h1:vZ5uqwvDbyJCnMhmFYimgMZnJMjwljN5VGY0VKbMXb4=
|
||||
github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI=
|
||||
github.com/ldez/exptostd v0.4.2 h1:l5pOzHBz8mFOlbcifTxzfyYbgEmoUqjxLFHZkjlbHXs=
|
||||
@@ -391,22 +270,14 @@ github.com/ldez/tagliatelle v0.7.1 h1:bTgKjjc2sQcsgPiT902+aadvMjCeMHrY7ly2XKFORI
|
||||
github.com/ldez/tagliatelle v0.7.1/go.mod h1:3zjxUpsNB2aEZScWiZTHrAXOl1x25t3cRmzfK1mlo2I=
|
||||
github.com/ldez/usetesting v0.4.2 h1:J2WwbrFGk3wx4cZwSMiCQQ00kjGR0+tuuyW0Lqm4lwA=
|
||||
github.com/ldez/usetesting v0.4.2/go.mod h1:eEs46T3PpQ+9RgN9VjpY6qWdiw2/QmfiDeWmdZdrjIQ=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY=
|
||||
github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA=
|
||||
github.com/macabu/inamedparam v0.1.3 h1:2tk/phHkMlEL/1GNe/Yf6kkR/hkcUdAEY3L0hjYV1Mk=
|
||||
github.com/macabu/inamedparam v0.1.3/go.mod h1:93FLICAIk/quk7eaPPQvbzihUdn/QkGDwIZEoLtpH6I=
|
||||
github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw=
|
||||
github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18=
|
||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||
github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI=
|
||||
github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE=
|
||||
github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04=
|
||||
github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc=
|
||||
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
|
||||
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
|
||||
github.com/matoous/godox v1.1.0 h1:W5mqwbyWrwZv6OQ5Z1a/DHGMOvXYCBP3+Ht7KMoJhq4=
|
||||
github.com/matoous/godox v1.1.0/go.mod h1:jgE/3fUXiTurkdHOLT5WEkThTSuE7yxHv5iWPa80afs=
|
||||
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
|
||||
@@ -418,28 +289,16 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A=
|
||||
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mgechev/revive v1.7.0 h1:JyeQ4yO5K8aZhIKf5rec56u0376h8AlKNQEmjfkjKlY=
|
||||
github.com/mgechev/revive v1.7.0/go.mod h1:qZnwcNhoguE58dfi96IJeSTPeZQejNeoMQLUZGi4SW4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI=
|
||||
github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U=
|
||||
github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhKRf3Swg=
|
||||
github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=
|
||||
github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
|
||||
@@ -460,16 +319,9 @@ github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJ
|
||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
||||
github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||
github.com/owenrumney/go-sarif/v2 v2.3.3 h1:ubWDJcF5i3L/EIOER+ZyQ03IfplbSU1BLOE26uKQIIU=
|
||||
github.com/owenrumney/go-sarif/v2 v2.3.3/go.mod h1:MSqMMx9WqlBSY7pXoOZWgEsVB4FDNfhcaXDA1j6Sr+w=
|
||||
github.com/package-url/packageurl-go v0.1.3 h1:4juMED3hHiz0set3Vq3KeQ75KD1avthoXLtmE3I0PLs=
|
||||
github.com/package-url/packageurl-go v0.1.3/go.mod h1:nKAWB8E6uk1MHqiS/lQb9pYBGH2+mdJ2PJc2s50dQY0=
|
||||
github.com/pandatix/go-cvss v0.6.2 h1:TFiHlzUkT67s6UkelHmK6s1INKVUG7nlKYiWWDTITGI=
|
||||
github.com/pandatix/go-cvss v0.6.2/go.mod h1:jDXYlQBZrc8nvrMUVVvTG8PhmuShOnKrxP53nOFkt8Q=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@@ -503,22 +355,15 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryancurrah/gomodguard v1.3.5 h1:cShyguSwUEeC0jS7ylOiG/idnd1TpJ1LfHGpV3oJmPU=
|
||||
github.com/ryancurrah/gomodguard v1.3.5/go.mod h1:MXlEPQRxgfPQa62O8wzK3Ozbkv9Rkqr+wKjSxTdsNJE=
|
||||
github.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU=
|
||||
github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ=
|
||||
github.com/safedep/dry v0.0.0-20250512123505-23dcce9fe1af h1:3Pomh9zoEIwvzWLBAc5ikJ8kPT53O2APD06HmrlE6A4=
|
||||
github.com/safedep/dry v0.0.0-20250512123505-23dcce9fe1af/go.mod h1:Mdqx/Q2DhAcN38XiUNTGCC5MktofYDQW9Az7YWGEF0s=
|
||||
github.com/safedep/dry v0.0.0-20250514080944-bb77f30c7175 h1:TxAI6m/v01CL+kwIYE3RZsuxu01pbuGy3wOi3WyBT1E=
|
||||
github.com/safedep/dry v0.0.0-20250514080944-bb77f30c7175/go.mod h1:Mdqx/Q2DhAcN38XiUNTGCC5MktofYDQW9Az7YWGEF0s=
|
||||
github.com/safedep/vet v1.10.1 h1:L8yG3X/t3I9fDVICc0DZ+zGweoLhDeyFIK6ubcNiXUc=
|
||||
github.com/safedep/vet v1.10.1/go.mod h1:DN+59m5kB1QSOpdstCk9rfLTMCPtT/ZLMP5rwuix/j8=
|
||||
github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k=
|
||||
github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk=
|
||||
github.com/sanity-io/litter v1.5.8 h1:uM/2lKrWdGbRXDrIq08Lh9XtVYoeGtcQxk9rtQ7+rYg=
|
||||
github.com/sanity-io/litter v1.5.8/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U=
|
||||
github.com/sanposhiho/wastedassign/v2 v2.1.0 h1:crurBF7fJKIORrV85u9UUpePDYGWnwvv3+A96WvwXT0=
|
||||
github.com/sanposhiho/wastedassign/v2 v2.1.0/go.mod h1:+oSmSC+9bQ+VUAxA66nBb0Z7N8CK7mscKTDYC6aIek4=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 h1:PKK9DyHxif4LZo+uQSgXNqs0jj5+xZwwfKHgph2lxBw=
|
||||
@@ -527,16 +372,11 @@ github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tM
|
||||
github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=
|
||||
github.com/sashamelentyev/usestdlibvars v1.28.0 h1:jZnudE2zKCtYlGzLVreNp5pmCdOxXUzwsMDBkR21cyQ=
|
||||
github.com/sashamelentyev/usestdlibvars v1.28.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8=
|
||||
github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk=
|
||||
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
|
||||
github.com/securego/gosec/v2 v2.22.2 h1:IXbuI7cJninj0nRpZSLCUlotsj8jGusohfONMrHoF6g=
|
||||
github.com/securego/gosec/v2 v2.22.2/go.mod h1:UEBGA+dSKb+VqM6TdehR7lnQtIIMorYJ4/9CW1KVQBE=
|
||||
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/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE=
|
||||
@@ -560,7 +400,6 @@ github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
|
||||
github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||
github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0=
|
||||
github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
|
||||
github.com/stbenjam/no-sprintf-host-port v0.2.0 h1:i8pxvGrt1+4G0czLr/WnmyH7zbZ8Bg8etvARQ1rpyl4=
|
||||
@@ -571,7 +410,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
@@ -579,7 +417,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
@@ -587,26 +424,12 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/tdakkota/asciicheck v0.4.1 h1:bm0tbcmi0jezRA2b5kg4ozmMuGAFotKI3RZfrhfovg8=
|
||||
github.com/tdakkota/asciicheck v0.4.1/go.mod h1:0k7M3rCfRXb0Z6bwgvkEIMleKH3kXNz9UqJ9Xuqopr8=
|
||||
github.com/tdewolff/minify/v2 v2.23.1 h1:r6sKQrumHzskWZRdhiRa+pZhn7CdBMojACNP9fuKpXQ=
|
||||
github.com/tdewolff/minify/v2 v2.23.1/go.mod h1:RkUGjklq6uIsBoOdzY3ll35HKKQ2aFqLQhnanBHhDyU=
|
||||
github.com/tdewolff/parse/v2 v2.7.23 h1:sCW2PNTCM1yVldh5YK/8wrpRI9rSbloUZWjAydlN2IA=
|
||||
github.com/tdewolff/parse/v2 v2.7.23/go.mod h1:I7TXO37t3aSG9SlPUBefAhgIF8nt7yYUwVGgETIoBcA=
|
||||
github.com/tdewolff/test v1.0.11 h1:FdLbwQVHxqG16SlkGveC0JVyrJN62COWTRyUFzfbtBE=
|
||||
github.com/tdewolff/test v1.0.11/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
|
||||
github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA=
|
||||
github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=
|
||||
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag=
|
||||
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
|
||||
github.com/tetafro/godot v1.5.0 h1:aNwfVI4I3+gdxjMgYPus9eHmoBeJIbnajOyqZYStzuw=
|
||||
github.com/tetafro/godot v1.5.0/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 h1:y4mJRFlM6fUyPhoXuFg/Yu02fg/nIPFMOY8tOqppoFg=
|
||||
github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460=
|
||||
github.com/timonwong/loggercheck v0.10.1 h1:uVZYClxQFpw55eh+PIoqM7uAOHMrhVcDoWDery9R8Lg=
|
||||
@@ -615,10 +438,6 @@ github.com/tomarrell/wrapcheck/v2 v2.10.0 h1:SzRCryzy4IrAH7bVGG4cK40tNUhmVmMDuJu
|
||||
github.com/tomarrell/wrapcheck/v2 v2.10.0/go.mod h1:g9vNIyhb5/9TQgumxQyOEqDHsmGYcGsVMOx/xGkqdMo=
|
||||
github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw=
|
||||
github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/ultraware/funlen v0.2.0 h1:gCHmCn+d2/1SemTdYMiKLAHFYxTYz7z9VIDRaTGyLkI=
|
||||
github.com/ultraware/funlen v0.2.0/go.mod h1:ZE0q4TsJ8T1SQcjmkhN/w+MceuatI6pBFSxxyteHIJA=
|
||||
github.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSWoFa+g=
|
||||
@@ -627,38 +446,14 @@ github.com/uudashr/gocognit v1.2.0 h1:3BU9aMr1xbhPlvJLSydKwdLN3tEUUrzPSSM8S4hDYR
|
||||
github.com/uudashr/gocognit v1.2.0/go.mod h1:k/DdKPI6XBZO1q7HgoV2juESI2/Ofj9AcHPZhBBdrTU=
|
||||
github.com/uudashr/iface v1.3.1 h1:bA51vmVx1UIhiIsQFSNq6GZ6VPTk3WNMZgRiCe9R29U=
|
||||
github.com/uudashr/iface v1.3.1/go.mod h1:4QvspiRd3JLPAEXBQ9AiZpLbJlrWWgRChOKDJEuQTdg=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU=
|
||||
github.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM=
|
||||
github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk=
|
||||
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY=
|
||||
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
|
||||
github.com/yeya24/promlinter v0.3.0 h1:JVDbMp08lVCP7Y6NP3qHroGAO6z2yGKQtS5JsjqtoFs=
|
||||
github.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+YcPQN+mW4=
|
||||
github.com/ykadowak/zerologlint v0.1.5 h1:Gy/fMz1dFQN9JZTPjv1hxEk+sRWm05row04Yoolgdiw=
|
||||
github.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg=
|
||||
github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA=
|
||||
github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0=
|
||||
github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
|
||||
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M=
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@@ -666,12 +461,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zclconf/go-cty v1.16.2 h1:LAJSwc3v81IRBZyUVQDUdZ7hs3SYs9jv0eZJDWHD/70=
|
||||
github.com/zclconf/go-cty v1.16.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
|
||||
github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0=
|
||||
github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs=
|
||||
gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo=
|
||||
gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8=
|
||||
go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ=
|
||||
@@ -706,16 +495,12 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8
|
||||
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/arch v0.16.0 h1:foMtLTdyOmIniqWCHjY6+JxuC54XP1fDwx4N0ASyW+U=
|
||||
golang.org/x/arch v0.16.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
@@ -731,7 +516,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
@@ -745,7 +529,6 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/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-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -781,7 +564,6 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -826,8 +608,6 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -846,7 +626,6 @@ golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0t
|
||||
golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
|
||||
@@ -878,11 +657,8 @@ google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9x
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@@ -897,10 +673,7 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI=
|
||||
honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=
|
||||
moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs=
|
||||
moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE=
|
||||
mvdan.cc/gofumpt v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU=
|
||||
mvdan.cc/gofumpt v0.7.0/go.mod h1:txVFJy/Sc/mvaycET54pV8SW8gWxTlUuGHVEcncmNUo=
|
||||
mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8XzX0u72NttUGVFjO3U=
|
||||
mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
|
||||
"github.com/safedep/dry/log"
|
||||
"github.com/safedep/dry/packageregistry"
|
||||
)
|
||||
|
||||
type dependencyResolverConfig struct {
|
||||
IncludeDevDependencies bool
|
||||
IncludeTransitiveDependencies bool
|
||||
TransitiveDepth int
|
||||
FailFast bool
|
||||
}
|
||||
|
||||
type dependencyResolver struct {
|
||||
client packageregistry.Client
|
||||
config dependencyResolverConfig
|
||||
}
|
||||
|
||||
func newDependencyResolver(client packageregistry.Client, config dependencyResolverConfig) *dependencyResolver {
|
||||
return &dependencyResolver{
|
||||
client: client,
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *dependencyResolver) resolveDependencies(ctx context.Context,
|
||||
packageVersion *packagev1.PackageVersion) ([]*packagev1.PackageVersion, error) {
|
||||
pd, err := r.client.PackageDiscovery()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get package discovery: %w", err)
|
||||
}
|
||||
|
||||
// Track visited packages to avoid cycles
|
||||
visitedPackages := make(map[string]bool)
|
||||
|
||||
// Result collection
|
||||
dependencies := make([]*packagev1.PackageVersion, 0)
|
||||
|
||||
// Start recursive resolution
|
||||
err = r.resolvePackageDependenciesRecursive(ctx, pd, packageVersion, 0, visitedPackages, &dependencies)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve dependencies: %w", err)
|
||||
}
|
||||
|
||||
return dependencies, nil
|
||||
}
|
||||
|
||||
// resolvePackageDependenciesRecursive resolves dependencies for a package version recursively
|
||||
func (r *dependencyResolver) resolvePackageDependenciesRecursive(
|
||||
ctx context.Context,
|
||||
pd packageregistry.PackageDiscovery,
|
||||
packageVersion *packagev1.PackageVersion,
|
||||
depth int,
|
||||
visitedPackages map[string]bool,
|
||||
result *[]*packagev1.PackageVersion) error {
|
||||
|
||||
// Check for context cancellation
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
ff := func(err error) error {
|
||||
if r.config.FailFast {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Warnf("error resolving package dependencies: %w", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check depth limit
|
||||
if depth > r.config.TransitiveDepth {
|
||||
return ff(fmt.Errorf("exceeded maximum transitive depth of %d", r.config.TransitiveDepth))
|
||||
}
|
||||
|
||||
// Skip if already visited
|
||||
packageKey := r.packageKey(packageVersion)
|
||||
if visitedPackages[packageKey] {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Mark the current package as visited
|
||||
visitedPackages[packageKey] = true
|
||||
|
||||
log.Debugf("resolving dependencies for %s@%s", packageVersion.Package.Name, packageVersion.Version)
|
||||
|
||||
// Get dependencies for the current package
|
||||
dependencyList, err := pd.GetPackageDependencies(packageVersion.Package.Name, packageVersion.Version)
|
||||
if err != nil {
|
||||
return ff(fmt.Errorf("failed to get package dependencies: %w", err))
|
||||
}
|
||||
|
||||
// Collect all dependencies (and optionally dev dependencies)
|
||||
dependencies := dependencyList.Dependencies
|
||||
if r.config.IncludeDevDependencies {
|
||||
dependencies = append(dependencies, dependencyList.DevDependencies...)
|
||||
}
|
||||
|
||||
// Create package version objects for all dependencies
|
||||
resolvedDependencies := make([]*packagev1.PackageVersion, 0, len(dependencies))
|
||||
for _, dependency := range dependencies {
|
||||
depPackageVersion := &packagev1.PackageVersion{
|
||||
Package: &packagev1.Package{
|
||||
Ecosystem: packagev1.Ecosystem_ECOSYSTEM_NPM,
|
||||
Name: dependency.Name,
|
||||
},
|
||||
Version: npmCleanVersion(dependency.VersionSpec),
|
||||
}
|
||||
|
||||
// Check if this dependency is already in the result to avoid duplicates
|
||||
depKey := r.packageKey(depPackageVersion)
|
||||
if !visitedPackages[depKey] {
|
||||
resolvedDependencies = append(resolvedDependencies, depPackageVersion)
|
||||
*result = append(*result, depPackageVersion)
|
||||
visitedPackages[depKey] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Process transitive dependencies if enabled
|
||||
if r.config.IncludeTransitiveDependencies {
|
||||
for _, dependency := range resolvedDependencies {
|
||||
err := r.resolvePackageDependenciesRecursive(ctx, pd, dependency, depth+1, visitedPackages, result)
|
||||
if err != nil {
|
||||
return ff(fmt.Errorf("failed to resolve transitive dependency: %w", err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *dependencyResolver) packageKey(pkg *packagev1.PackageVersion) string {
|
||||
return fmt.Sprintf("%s@%s", pkg.Package.Name, pkg.Version)
|
||||
}
|
||||
@@ -66,104 +66,14 @@ func (r *npmDependencyResolver) ResolveLatestVersion(ctx context.Context,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// TODO: Refactor this into a generic dependency resolver that depends on
|
||||
// package registry client
|
||||
func (r *npmDependencyResolver) ResolveDependencies(ctx context.Context,
|
||||
packageVersion *packagev1.PackageVersion) ([]*packagev1.PackageVersion, error) {
|
||||
pd, err := r.registry.PackageDiscovery()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get package discovery: %w", err)
|
||||
}
|
||||
resolver := newDependencyResolver(r.registry, dependencyResolverConfig{
|
||||
IncludeDevDependencies: r.config.IncludeDevDependencies,
|
||||
IncludeTransitiveDependencies: r.config.IncludeTransitiveDependencies,
|
||||
TransitiveDepth: r.config.TransitiveDepth,
|
||||
FailFast: r.config.FailFast,
|
||||
})
|
||||
|
||||
// Track visited packages to avoid cycles
|
||||
visitedPackages := make(map[string]bool)
|
||||
|
||||
// Result collection
|
||||
dependencies := make([]*packagev1.PackageVersion, 0)
|
||||
|
||||
// Start recursive resolution
|
||||
err = r.resolvePackageDependenciesRecursive(ctx, pd, packageVersion, 0, visitedPackages, &dependencies)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve dependencies: %w", err)
|
||||
}
|
||||
|
||||
return dependencies, nil
|
||||
}
|
||||
|
||||
// resolvePackageDependenciesRecursive resolves dependencies for a package version recursively
|
||||
func (r *npmDependencyResolver) resolvePackageDependenciesRecursive(
|
||||
ctx context.Context,
|
||||
pd packageregistry.PackageDiscovery,
|
||||
packageVersion *packagev1.PackageVersion,
|
||||
depth int,
|
||||
visitedPackages map[string]bool,
|
||||
result *[]*packagev1.PackageVersion) error {
|
||||
|
||||
ff := func(err error) error {
|
||||
if r.config.FailFast {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Warnf("error resolving package dependencies: %w", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check depth limit
|
||||
if depth > r.config.TransitiveDepth {
|
||||
return ff(fmt.Errorf("exceeded maximum transitive depth of %d", r.config.TransitiveDepth))
|
||||
}
|
||||
|
||||
// Skip if already visited
|
||||
packageKey := r.packageKey(packageVersion)
|
||||
if visitedPackages[packageKey] {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Mark as visited
|
||||
visitedPackages[packageKey] = true
|
||||
|
||||
log.Debugf("resolving dependencies for %s@%s", packageVersion.Package.Name, packageVersion.Version)
|
||||
|
||||
// Get dependencies for the current package
|
||||
dependencyList, err := pd.GetPackageDependencies(packageVersion.Package.Name, packageVersion.Version)
|
||||
if err != nil {
|
||||
return ff(fmt.Errorf("failed to get package dependencies: %w", err))
|
||||
}
|
||||
|
||||
// Collect all dependencies (and optionally dev dependencies)
|
||||
dependencies := dependencyList.Dependencies
|
||||
if r.config.IncludeDevDependencies {
|
||||
dependencies = append(dependencies, dependencyList.DevDependencies...)
|
||||
}
|
||||
|
||||
// Create package version objects for all dependencies
|
||||
resolvedDependencies := make([]*packagev1.PackageVersion, 0, len(dependencies))
|
||||
for _, dependency := range dependencies {
|
||||
resolvedDependencies = append(resolvedDependencies, &packagev1.PackageVersion{
|
||||
Package: &packagev1.Package{
|
||||
Ecosystem: packagev1.Ecosystem_ECOSYSTEM_NPM,
|
||||
Name: dependency.Name,
|
||||
},
|
||||
Version: npmCleanVersion(dependency.VersionSpec),
|
||||
})
|
||||
}
|
||||
|
||||
// Add all resolved dependencies to the result
|
||||
*result = append(*result, resolvedDependencies...)
|
||||
|
||||
// Process transitive dependencies if enabled
|
||||
if r.config.IncludeTransitiveDependencies {
|
||||
for _, dependency := range resolvedDependencies {
|
||||
err := r.resolvePackageDependenciesRecursive(ctx, pd, dependency, depth+1, visitedPackages, result)
|
||||
if err != nil {
|
||||
return ff(fmt.Errorf("failed to resolve transitive dependency: %w", err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *npmDependencyResolver) packageKey(pkg *packagev1.PackageVersion) string {
|
||||
return fmt.Sprintf("%s@%s", pkg.Package.Name, pkg.Version)
|
||||
return resolver.resolveDependencies(ctx, packageVersion)
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ func TestNpmDependencyResolver_ResolveDependencies(t *testing.T) {
|
||||
transitiveDepth: 5,
|
||||
assertFn: func(t *testing.T, dependencies []*packagev1.PackageVersion, err error) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(dependencies))
|
||||
require.Greater(t, len(dependencies), 5, "Express should have more than 5 dependencies")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
package analyser
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"buf.build/gen/go/safedep/api/grpc/go/safedep/services/malysis/v1/malysisv1grpc"
|
||||
malysisv1pb "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/malysis/v1"
|
||||
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
|
||||
malysisv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/services/malysis/v1"
|
||||
"github.com/safedep/dry/log"
|
||||
"github.com/safedep/pmg/internal/ui"
|
||||
"github.com/safedep/pmg/pkg/models"
|
||||
vetUtils "github.com/safedep/vet/pkg/common/utils"
|
||||
)
|
||||
|
||||
type PackageAnalyser struct {
|
||||
MaliciousPkgs map[string]string
|
||||
Client malysisv1grpc.MalwareAnalysisServiceClient
|
||||
Ctx context.Context
|
||||
MaliciousPkgsMutex sync.Mutex
|
||||
ProgressTracker ui.ProgressTracker
|
||||
Ecosystem packagev1.Ecosystem
|
||||
}
|
||||
|
||||
func New(client malysisv1grpc.MalwareAnalysisServiceClient, ctx context.Context, ecosystem packagev1.Ecosystem) *PackageAnalyser {
|
||||
return &PackageAnalyser{
|
||||
MaliciousPkgs: make(map[string]string),
|
||||
Client: client,
|
||||
Ctx: ctx,
|
||||
MaliciousPkgsMutex: sync.Mutex{},
|
||||
Ecosystem: ecosystem,
|
||||
}
|
||||
}
|
||||
|
||||
func (ap *PackageAnalyser) Handler() vetUtils.WorkQueueFn[models.Package] {
|
||||
return func(q *vetUtils.WorkQueue[models.Package], item models.Package) error {
|
||||
reportResp, err := QueryPackageAnalysis(ap.Ctx, ap.Client,
|
||||
ap.Ecosystem, item.Name, item.Version)
|
||||
if err != nil {
|
||||
log.Debugf("Failed to analyze %s@%s: %v", item.Name, item.Version, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
report := reportResp.GetReport()
|
||||
if report == nil {
|
||||
log.Debugf("Empty report received for %s", item.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
inference := report.GetInference()
|
||||
if inference == nil {
|
||||
log.Debugf("No inference data for %s", item.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Infof("Inference for %s: isMalware=%v", item.Name, inference.GetIsMalware())
|
||||
|
||||
if inference.GetIsMalware() {
|
||||
ap.MaliciousPkgsMutex.Lock()
|
||||
ap.MaliciousPkgs[fmt.Sprintf("%s@%s", item.Name, item.Version)] = inference.GetSummary()
|
||||
ap.MaliciousPkgsMutex.Unlock()
|
||||
}
|
||||
|
||||
ui.IncrementProgress(ap.ProgressTracker, 1)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func QueryPackageAnalysis(ctx context.Context, client malysisv1grpc.MalwareAnalysisServiceClient, ecosystem packagev1.Ecosystem, name string,
|
||||
version string) (*malysisv1.QueryPackageAnalysisResponse, error) {
|
||||
resp, err := client.QueryPackageAnalysis(ctx, &malysisv1.QueryPackageAnalysisRequest{
|
||||
Target: &malysisv1pb.PackageAnalysisTarget{
|
||||
PackageVersion: &packagev1.PackageVersion{
|
||||
Package: &packagev1.Package{
|
||||
Ecosystem: ecosystem,
|
||||
Name: name,
|
||||
},
|
||||
Version: version,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to analyze %s@%s: %w", name, version, err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package analyser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"buf.build/gen/go/safedep/api/grpc/go/safedep/services/malysis/v1/malysisv1grpc"
|
||||
"github.com/safedep/pmg/pkg/common"
|
||||
)
|
||||
|
||||
func GetMalwareAnalysisClient() (malysisv1grpc.MalwareAnalysisServiceClient, error) {
|
||||
cc, err := common.NewCloudClientConnection()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create gRPC client: %v", err)
|
||||
}
|
||||
return malysisv1grpc.NewMalwareAnalysisServiceClient(cc), nil
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/safedep/dry/crypto"
|
||||
"github.com/safedep/pmg/pkg/common/utils"
|
||||
"github.com/safedep/pmg/pkg/models"
|
||||
)
|
||||
|
||||
// ExtractorOptions holds configuration for running an extractor script
|
||||
type ExtractorOptions struct {
|
||||
ScriptContent string // The script content
|
||||
ScriptType string // File extension like "js", "py", etc.
|
||||
Interpreter string // What interpreter to use (e.g., "node", "python")
|
||||
PackageName string // Name of the package to analyze
|
||||
Args []string // Additional arguments to pass to the script
|
||||
Env map[string]string // Environment variables to pass to the script
|
||||
}
|
||||
|
||||
func FlattenDependencyTree(node *models.DependencyNode) []string {
|
||||
result := make([]string, 0)
|
||||
seen := make(map[string]bool)
|
||||
|
||||
var flatten func(*models.DependencyNode)
|
||||
flatten = func(n *models.DependencyNode) {
|
||||
key := fmt.Sprintf("%s@%s", n.Name, n.Version)
|
||||
if seen[key] {
|
||||
return
|
||||
}
|
||||
seen[key] = true
|
||||
|
||||
result = append(result, fmt.Sprintf("%s@%s", n.Name, n.Version))
|
||||
|
||||
for _, dep := range n.Dependencies {
|
||||
flatten(dep)
|
||||
}
|
||||
}
|
||||
|
||||
flatten(node)
|
||||
return result
|
||||
}
|
||||
|
||||
// RunExtractor extracts an embedded script to a temp file and executes it
|
||||
func RunPkgExtractor(opts ExtractorOptions) (string, error) {
|
||||
interpreterPath, err := utils.GetExecutablePath(opts.Interpreter)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Create a temporary file for the embedded script
|
||||
scriptFile, err := os.CreateTemp("", fmt.Sprintf("registry-extractor-*.%s", opts.ScriptType))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create temporary script file: %s", err.Error())
|
||||
}
|
||||
defer os.Remove(scriptFile.Name())
|
||||
|
||||
// Write the embedded script to the temporary file
|
||||
if _, err = scriptFile.WriteString(opts.ScriptContent); err != nil {
|
||||
return "", fmt.Errorf("failed to write script to temporary file: %s", err.Error())
|
||||
}
|
||||
|
||||
if err = scriptFile.Close(); err != nil {
|
||||
return "", fmt.Errorf("failed to close temporary script file: %s", err.Error())
|
||||
}
|
||||
|
||||
// Create a file with random name which will contain the output
|
||||
randomFileName, err := crypto.RandomString(12, "abcdefghijklmnopqrstuvwxyz0123456789")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to generate random string: %s", err.Error())
|
||||
}
|
||||
outputFile := filepath.Join(os.TempDir(), randomFileName+".txt")
|
||||
|
||||
// Build the command with all arguments
|
||||
cmdArgs := append([]string{scriptFile.Name(), opts.PackageName, outputFile}, opts.Args...)
|
||||
var env []string
|
||||
for key, value := range opts.Env {
|
||||
env = append(env, fmt.Sprintf("%s=%s", key, value))
|
||||
}
|
||||
if err = utils.ExecCmd(interpreterPath, cmdArgs, env); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return outputFile, nil
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
drygrpc "github.com/safedep/dry/adapters/grpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func NewCloudClientConnection() (*grpc.ClientConn, error) {
|
||||
cc, err := newGrpcClient(http.Header{}, "", "pmg-pkg-scan", "community-api.safedep.io", "443")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create gRPC client: %v", err)
|
||||
}
|
||||
return cc, nil
|
||||
}
|
||||
|
||||
func newGrpcClient(headers http.Header, token, clientName, host, port string) (*grpc.ClientConn, error) {
|
||||
cc, err := drygrpc.GrpcClient(clientName, host, port, token, headers, []grpc.DialOption{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cc, nil
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func ExecCmd(name string, args, env []string) error {
|
||||
cmd := exec.Command(name, args...)
|
||||
cmd.Env = append(os.Environ(), env...)
|
||||
|
||||
// Connect to standard streams
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdin = os.Stdin
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ApiKey() string {
|
||||
return os.Getenv("SAFEDEP_API_KEY")
|
||||
}
|
||||
|
||||
func TenantDomain() string {
|
||||
return os.Getenv("SAFEDEP_TENANT_ID")
|
||||
}
|
||||
|
||||
func NpmAuthToken() string {
|
||||
return os.Getenv("NPM_AUTH_TOKEN")
|
||||
}
|
||||
|
||||
func ValidateEnvVars() error {
|
||||
apiKey := ApiKey()
|
||||
tenantId := TenantDomain()
|
||||
var missingVars []string
|
||||
|
||||
if apiKey == "" {
|
||||
missingVars = append(missingVars, "SAFEDEP_API_KEY")
|
||||
}
|
||||
if tenantId == "" {
|
||||
missingVars = append(missingVars, "SAFEDEP_TENANT_ID")
|
||||
}
|
||||
|
||||
if len(missingVars) > 0 {
|
||||
return fmt.Errorf(`
|
||||
SafeDep configuration incomplete
|
||||
|
||||
Missing environment variables:
|
||||
%s
|
||||
|
||||
To enable package scanning:
|
||||
1. Export these variables in your terminal:
|
||||
export %s=your_api_key
|
||||
export %s=your_tenant_id
|
||||
2. Or add them to your shell profile file
|
||||
|
||||
For more information, visit: https://docs.safedep.io/cloud/quickstart
|
||||
`, strings.Join(missingVars, "\n "), missingVars[0], missingVars[len(missingVars)-1])
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func GetExecutablePath(name string) (string, error) {
|
||||
path, err := exec.LookPath(name)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("interpreter '%s' not found in PATH: %s", name, err.Error())
|
||||
}
|
||||
return path, nil
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
headerBulletRegex = regexp.MustCompile(`(?m)^(#{1,6}\s+|[-*]\s{1,}|\d+\.\s+|>\s+)`)
|
||||
inlineCodeRegex = regexp.MustCompile("`{1,3}([^`]*)`{1,3}")
|
||||
horizontalRuleRegex = regexp.MustCompile(`(?m)^\s*(-{3,}|\*{3,}|\_{3,})\s*$`)
|
||||
boldItalicRegex = regexp.MustCompile(`(?:\*\*\*|___)(.*?)(?:\*\*\*|___)`)
|
||||
boldRegex = regexp.MustCompile(`(?:\*\*|__)(.*?)(?:\*\*|__)`)
|
||||
italicRegex = regexp.MustCompile(`(?:\*|_)(.*?)(?:\*|_)`)
|
||||
strikethroughRegex = regexp.MustCompile(`~~([^~]+)~~`)
|
||||
inlineLinkRegex = regexp.MustCompile(`\[([^\]]+)\]\((\S+?)\)`)
|
||||
imageRegex = regexp.MustCompile(`!\[([^\]]*)\]\((\S+?)\)`)
|
||||
extraSpacesRegex = regexp.MustCompile(`\s+`)
|
||||
)
|
||||
|
||||
func removeMarkdown(text string) string {
|
||||
// Remove bold italic (***bolditalic*** or ___bolditalic___)
|
||||
text = boldItalicRegex.ReplaceAllString(text, "$1")
|
||||
|
||||
// Remove bold (**bold** or __bold__)
|
||||
text = boldRegex.ReplaceAllString(text, "$1")
|
||||
|
||||
// Remove italic (*italic* or _italic_)
|
||||
text = italicRegex.ReplaceAllString(text, "$1")
|
||||
|
||||
// Remove strikethrough (~~text~~)
|
||||
text = strikethroughRegex.ReplaceAllString(text, "$1")
|
||||
|
||||
// Remove inline code (`code`)
|
||||
text = inlineCodeRegex.ReplaceAllString(text, "$1")
|
||||
|
||||
// Remove links [text](url)
|
||||
text = inlineLinkRegex.ReplaceAllString(text, "$1")
|
||||
|
||||
// Remove images 
|
||||
text = imageRegex.ReplaceAllString(text, "$1")
|
||||
|
||||
// Remove horizontal rules
|
||||
text = horizontalRuleRegex.ReplaceAllString(text, "")
|
||||
|
||||
// Remove headers, blockquotes, bullets (e.g., ### Heading, > Quote, - Item)
|
||||
text = headerBulletRegex.ReplaceAllString(text, "")
|
||||
|
||||
// Normalize extra spaces
|
||||
text = extraSpacesRegex.ReplaceAllString(text, " ")
|
||||
|
||||
// Trim leading/trailing whitespace
|
||||
return strings.TrimSpace(text)
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParseNpmInstallArgs parses npm install command arguments and returns
|
||||
// separated flags and packages. It expects args to include the full command
|
||||
// including "npm" and "install" at the start
|
||||
func ParseNpmInstallArgs(args []string) ([]string, []string) {
|
||||
var flags []string
|
||||
var packages []string
|
||||
|
||||
for _, arg := range args {
|
||||
if strings.HasPrefix(arg, "-") {
|
||||
flags = append(flags, arg)
|
||||
} else {
|
||||
packages = append(packages, arg)
|
||||
}
|
||||
}
|
||||
return flags, packages
|
||||
}
|
||||
|
||||
func CleanVersion(version string) string {
|
||||
version = strings.TrimPrefix(version, "^")
|
||||
version = strings.TrimPrefix(version, "~")
|
||||
if version == "*" {
|
||||
return "latest"
|
||||
}
|
||||
return version
|
||||
}
|
||||
|
||||
func ParsePackageInfo(input string) (packageName, version string, err error) {
|
||||
if input == "" {
|
||||
return "", "", fmt.Errorf("package info cannot be empty")
|
||||
}
|
||||
input = strings.TrimSpace(input)
|
||||
|
||||
if strings.HasPrefix(input, "@") {
|
||||
lastAtIndex := strings.LastIndex(input, "@")
|
||||
if lastAtIndex > 0 {
|
||||
packageName = strings.TrimSpace(input[:lastAtIndex])
|
||||
version = strings.TrimSpace(input[lastAtIndex+1:])
|
||||
return packageName, version, nil
|
||||
}
|
||||
// If no version specifier, return the whole input as package name
|
||||
return strings.TrimSpace(input), "", nil
|
||||
}
|
||||
|
||||
pkg := strings.Split(input, "@")
|
||||
if len(pkg) == 2 {
|
||||
packageName = strings.TrimSpace(pkg[0])
|
||||
version = strings.TrimSpace(pkg[1])
|
||||
return packageName, version, nil
|
||||
}
|
||||
|
||||
if len(pkg) == 1 {
|
||||
packageName = strings.TrimSpace(pkg[0])
|
||||
return packageName, "", nil
|
||||
}
|
||||
|
||||
return "", "", fmt.Errorf("invalid format: expected 'package' OR 'package@version', got '%s'", input)
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/safedep/dry/log"
|
||||
)
|
||||
|
||||
func ConfirmInstallation(maliciousPkgs map[string]string) bool {
|
||||
|
||||
fmt.Printf("\n%s\n", colors.Red("⚠️ WARNING: %d potentially malicious packages detected!", len(maliciousPkgs)))
|
||||
fmt.Println(colors.Yellow("The following packages have been flagged:"))
|
||||
|
||||
for name, reason := range maliciousPkgs {
|
||||
fmt.Printf("%s %s: %s\n",
|
||||
colors.Cyan("•"), // bullet point
|
||||
colors.Yellow(name),
|
||||
removeMarkdown(reason),
|
||||
)
|
||||
}
|
||||
|
||||
fmt.Print("\n", colors.Green("Do you want to continue with installation? (y/N): "))
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
response, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
log.Errorf("Failed to read user input: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
response = strings.ToLower(strings.TrimSpace(response))
|
||||
return response == "y" || response == "yes"
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package utils
|
||||
|
||||
import "github.com/fatih/color"
|
||||
|
||||
type TerminalColors struct {
|
||||
Red func(format string, a ...interface{}) string
|
||||
Yellow func(format string, a ...interface{}) string
|
||||
Cyan func(format string, a ...interface{}) string
|
||||
Green func(format string, a ...interface{}) string
|
||||
}
|
||||
|
||||
var colors = TerminalColors{
|
||||
Red: color.New(color.FgRed, color.Bold).SprintfFunc(),
|
||||
Yellow: color.New(color.FgYellow).SprintfFunc(),
|
||||
Cyan: color.New(color.FgCyan).SprintfFunc(),
|
||||
Green: color.New(color.FgGreen).SprintfFunc(),
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package utils
|
||||
|
||||
func IsInstallCommand(pkgManager, cmd string) bool {
|
||||
validActions := map[string]map[string]bool{
|
||||
"npm": {
|
||||
"install": true,
|
||||
"i": true,
|
||||
"add": true,
|
||||
},
|
||||
"pnpm": {
|
||||
"add": true,
|
||||
"install": true,
|
||||
"i": true,
|
||||
},
|
||||
}
|
||||
|
||||
if actions, exists := validActions[pkgManager]; exists {
|
||||
return actions[cmd]
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -1,212 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCleanVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
version string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "caret version",
|
||||
version: "^1.2.3",
|
||||
expected: "1.2.3",
|
||||
},
|
||||
{
|
||||
name: "tilde version",
|
||||
version: "~1.2.3",
|
||||
expected: "1.2.3",
|
||||
},
|
||||
{
|
||||
name: "exact version",
|
||||
version: "1.2.3",
|
||||
expected: "1.2.3",
|
||||
},
|
||||
{
|
||||
name: "asterisk version",
|
||||
version: "*",
|
||||
expected: "latest",
|
||||
},
|
||||
{
|
||||
name: "empty version",
|
||||
version: "",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "both caret and tilde",
|
||||
version: "^~1.2.3",
|
||||
expected: "1.2.3",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := CleanVersion(tt.version)
|
||||
if result != tt.expected {
|
||||
t.Errorf("CleanVersion(%q) = %q, want %q", tt.version, result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsePackageInfo(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
wantPackage string
|
||||
wantVersion string
|
||||
wantErr bool
|
||||
errorContains string
|
||||
}{
|
||||
{
|
||||
name: "simple package",
|
||||
input: "express",
|
||||
wantPackage: "express",
|
||||
wantVersion: "",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "package with version",
|
||||
input: "express@4.17.1",
|
||||
wantPackage: "express",
|
||||
wantVersion: "4.17.1",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "scoped package",
|
||||
input: "@angular/core",
|
||||
wantPackage: "@angular/core",
|
||||
wantVersion: "",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "scoped package with version",
|
||||
input: "@angular/core@12.0.0",
|
||||
wantPackage: "@angular/core",
|
||||
wantVersion: "12.0.0",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "package with caret version",
|
||||
input: "react@^17.0.2",
|
||||
wantPackage: "react",
|
||||
wantVersion: "^17.0.2",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "package with tilde version",
|
||||
input: "lodash@~4.17.21",
|
||||
wantPackage: "lodash",
|
||||
wantVersion: "~4.17.21",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "empty input",
|
||||
input: "",
|
||||
wantPackage: "",
|
||||
wantVersion: "",
|
||||
wantErr: true,
|
||||
errorContains: "package info cannot be empty",
|
||||
},
|
||||
{
|
||||
name: "invalid format with multiple @",
|
||||
input: "pkg@1.0.0@2.0.0",
|
||||
wantPackage: "",
|
||||
wantVersion: "",
|
||||
wantErr: true,
|
||||
errorContains: "invalid format",
|
||||
},
|
||||
{
|
||||
name: "package with spaces",
|
||||
input: " express@4.17.1 ",
|
||||
wantPackage: "express",
|
||||
wantVersion: "4.17.1",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "scoped package with spaces",
|
||||
input: " @types/node@14.14.31 ",
|
||||
wantPackage: "@types/node",
|
||||
wantVersion: "14.14.31",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
packageName, version, err := ParsePackageInfo(tt.input)
|
||||
|
||||
// Check error
|
||||
if tt.wantErr {
|
||||
if err == nil {
|
||||
t.Errorf("ParsePackageInfo(%q) expected error, got nil", tt.input)
|
||||
return
|
||||
}
|
||||
if tt.errorContains != "" && !strings.Contains(err.Error(), tt.errorContains) {
|
||||
t.Errorf("ParsePackageInfo(%q) error = %v, want error containing %q", tt.input, err, tt.errorContains)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("ParsePackageInfo(%q) unexpected error: %v", tt.input, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Check package name
|
||||
if packageName != tt.wantPackage {
|
||||
t.Errorf("ParsePackageInfo(%q) package = %q, want %q", tt.input, packageName, tt.wantPackage)
|
||||
}
|
||||
|
||||
// Check version
|
||||
if version != tt.wantVersion {
|
||||
t.Errorf("ParsePackageInfo(%q) version = %q, want %q", tt.input, version, tt.wantVersion)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveMarkdown(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
// Bold
|
||||
{"This is **bold** text", "This is bold text"},
|
||||
{"This is __bold__ text", "This is bold text"},
|
||||
|
||||
// Italic
|
||||
{"This is *italic* text", "This is italic text"},
|
||||
{"This is _italic_ text", "This is italic text"},
|
||||
|
||||
// Code
|
||||
{"This is `code` inline", "This is code inline"},
|
||||
|
||||
// Link
|
||||
{"Click [here](https://example.com)", "Click here"},
|
||||
|
||||
// Headings
|
||||
{"# Heading 1", "Heading 1"},
|
||||
{"### Subheading", "Subheading"},
|
||||
|
||||
// Combined formatting
|
||||
{"__*bold and italic*__", "bold and italic"},
|
||||
{"This is **bold** and `code`", "This is bold and code"},
|
||||
|
||||
// No markdown
|
||||
{"Just plain text", "Just plain text"},
|
||||
|
||||
// Complex mixed
|
||||
{"### Title\nSome **bold** text and a [link](http://url.com).", "Title Some bold text and a link."},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
result := removeMarkdown(tt.input)
|
||||
if result != tt.expected {
|
||||
t.Errorf("removeMarkdown(%q) = %q; want %q", tt.input, result, tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Package struct {
|
||||
Name string
|
||||
Version string
|
||||
}
|
||||
|
||||
func (p Package) Id() string {
|
||||
return fmt.Sprintf("%s@%s", p.Name, p.Version)
|
||||
}
|
||||
|
||||
type PackageInfo struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Dependencies map[string]string `json:"dependencies"`
|
||||
}
|
||||
|
||||
type DependencyNode struct {
|
||||
Name string
|
||||
Version string
|
||||
Dependencies map[string]*DependencyNode
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/safedep/pmg/pkg/models"
|
||||
)
|
||||
|
||||
// RegistryClient defines the interface for making requests to a registry
|
||||
type RegistryClient interface {
|
||||
// FetchPackageInfo fetches metadata for a specific package version
|
||||
FetchPackageInfo(ctx context.Context, pkg models.Package) (*models.PackageInfo, error)
|
||||
// GetLatestVersion fetches the latest version for a package
|
||||
GetLatestVersion(ctx context.Context, packageName string) (string, error)
|
||||
}
|
||||
|
||||
// HttpRegistryClient is a basic HTTP client for registry APIs
|
||||
type HttpRegistryClient struct {
|
||||
httpClient *http.Client
|
||||
urlFormat string
|
||||
parser func([]byte) (*models.PackageInfo, error)
|
||||
}
|
||||
|
||||
// NewHttpRegistryClient creates a new HTTP registry client
|
||||
func NewHttpRegistryClient(
|
||||
timeout time.Duration,
|
||||
urlFormat string,
|
||||
parser func([]byte) (*models.PackageInfo, error),
|
||||
) *HttpRegistryClient {
|
||||
return &HttpRegistryClient{
|
||||
httpClient: &http.Client{Timeout: timeout},
|
||||
urlFormat: urlFormat,
|
||||
parser: parser,
|
||||
}
|
||||
}
|
||||
|
||||
// FetchPackageInfo fetches package metadata from the registry
|
||||
func (c *HttpRegistryClient) FetchPackageInfo(ctx context.Context, pkg models.Package) (*models.PackageInfo, error) {
|
||||
url := fmt.Sprintf(c.urlFormat, pkg.Name, pkg.Version)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("making request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("registry returned status: %s", resp.Status)
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading response body: %w", err)
|
||||
}
|
||||
|
||||
return c.parser(body)
|
||||
}
|
||||
|
||||
// GetLatestVersion fetches the latest version for an NPM package
|
||||
func (c *HttpRegistryClient) GetLatestVersion(ctx context.Context, packageName string) (string, error) {
|
||||
// For NPM, we can get latest version by querying the base package URL
|
||||
url := fmt.Sprintf("https://registry.npmjs.org/%s", packageName)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("creating request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("making request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("registry returned status: %s", resp.Status)
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("reading response body: %w", err)
|
||||
}
|
||||
|
||||
// Parse the response to get the latest version
|
||||
var pkgData struct {
|
||||
DistTags struct {
|
||||
Latest string `json:"latest"`
|
||||
} `json:"dist-tags"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(body, &pkgData); err != nil {
|
||||
return "", fmt.Errorf("parsing package info: %w", err)
|
||||
}
|
||||
|
||||
if pkgData.DistTags.Latest == "" {
|
||||
return "", fmt.Errorf("no latest version found for package %s", packageName)
|
||||
}
|
||||
|
||||
return pkgData.DistTags.Latest, nil
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RegistryType represents different package registries
|
||||
type RegistryType string
|
||||
|
||||
const (
|
||||
RegistryNPM RegistryType = "npm"
|
||||
RegistryPNPM RegistryType = "pnpm"
|
||||
RegistryPyPI RegistryType = "pypi"
|
||||
RegistryGo RegistryType = "go"
|
||||
)
|
||||
|
||||
// FetcherFactory creates appropriate fetchers based on registry type
|
||||
type FetcherFactory struct {
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
// NewFetcherFactory creates a new factory for registry fetchers
|
||||
func NewFetcherFactory(timeout time.Duration) *FetcherFactory {
|
||||
return &FetcherFactory{
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateFetcher returns a fetcher for the specified registry type
|
||||
func (ff *FetcherFactory) CreateFetcher(registryType RegistryType) (Fetcher, error) {
|
||||
switch registryType {
|
||||
case RegistryNPM, RegistryPNPM:
|
||||
return NewNpmFetcher(ff.timeout), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported registry type: %s", registryType)
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
// Package registry provides interfaces and implementations for fetching dependencies
|
||||
// from various package registries (npm, pypi, go, etc.)
|
||||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/safedep/pmg/internal/ui"
|
||||
"github.com/safedep/pmg/pkg/models"
|
||||
)
|
||||
|
||||
// Fetcher defines the interface for registry dependency fetchers
|
||||
type Fetcher interface {
|
||||
// GetDependencyTree returns the complete dependency tree for a package
|
||||
GetDependencyTree(ctx context.Context, pkg models.Package) (*models.DependencyNode, error)
|
||||
|
||||
// GetFlattenedDependencies returns a list of all dependencies as package@version strings
|
||||
GetFlattenedDependencies(ctx context.Context, packageName, version string) ([]string, error)
|
||||
}
|
||||
|
||||
// BaseFetcher implements common functionality for all registry fetchers
|
||||
type BaseFetcher struct {
|
||||
visitedMu sync.RWMutex
|
||||
visited map[string]bool
|
||||
client RegistryClient
|
||||
progressTracker ui.ProgressTracker
|
||||
fetchedDeps int32
|
||||
}
|
||||
|
||||
// NewBaseFetcher creates a new BaseFetcher with the specified registry client
|
||||
func NewBaseFetcher(client RegistryClient) *BaseFetcher {
|
||||
return &BaseFetcher{
|
||||
visited: make(map[string]bool),
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (bf *BaseFetcher) SetProgressTracker(tracker ui.ProgressTracker) {
|
||||
bf.progressTracker = tracker
|
||||
atomic.StoreInt32(&bf.fetchedDeps, 0)
|
||||
}
|
||||
|
||||
// isVisited checks if a package has already been visited
|
||||
func (bf *BaseFetcher) isVisited(key string) bool {
|
||||
bf.visitedMu.RLock()
|
||||
defer bf.visitedMu.RUnlock()
|
||||
return bf.visited[key]
|
||||
}
|
||||
|
||||
// markVisited marks a package as visited
|
||||
func (bf *BaseFetcher) markVisited(key string) {
|
||||
bf.visitedMu.Lock()
|
||||
defer bf.visitedMu.Unlock()
|
||||
bf.visited[key] = true
|
||||
}
|
||||
|
||||
// cacheKey generates a unique key for a package
|
||||
func cacheKey(pkg models.Package) string {
|
||||
return fmt.Sprintf("%s@%s", pkg.Name, pkg.Version)
|
||||
}
|
||||
|
||||
// flattenDependencyTree recursively converts a dependency tree to a flat list of strings
|
||||
func flattenDependencyTree(node *models.DependencyNode, result *[]string) {
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
|
||||
depString := fmt.Sprintf("%s@%s", node.Name, node.Version)
|
||||
*result = append(*result, depString)
|
||||
|
||||
for _, dep := range node.Dependencies {
|
||||
flattenDependencyTree(dep, result)
|
||||
}
|
||||
}
|
||||
|
||||
// resetVisited resets the visited packages map
|
||||
func (bf *BaseFetcher) resetVisited() {
|
||||
bf.visitedMu.Lock()
|
||||
defer bf.visitedMu.Unlock()
|
||||
bf.visited = make(map[string]bool)
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/safedep/dry/log"
|
||||
"github.com/safedep/pmg/internal/ui"
|
||||
"github.com/safedep/pmg/pkg/common/utils"
|
||||
"github.com/safedep/pmg/pkg/models"
|
||||
)
|
||||
|
||||
// NpmFetcher fetches dependencies from NPM registry
|
||||
type NpmFetcher struct {
|
||||
*BaseFetcher
|
||||
}
|
||||
|
||||
func (nf *NpmFetcher) incrementProgress() {
|
||||
if nf.progressTracker != nil {
|
||||
atomic.AddInt32(&nf.fetchedDeps, 1)
|
||||
// Update progress message to show number of packages fetched
|
||||
ui.SetPinnedMessageOnProgressWriter(fmt.Sprintf("Fetched %d packages", atomic.LoadInt32(&nf.fetchedDeps)))
|
||||
}
|
||||
}
|
||||
|
||||
// NewNpmFetcher creates a new NPM registry fetcher
|
||||
func NewNpmFetcher(timeout time.Duration) *NpmFetcher {
|
||||
client := NewHttpRegistryClient(
|
||||
timeout,
|
||||
"https://registry.npmjs.org/%s/%s",
|
||||
parseNpmPackageInfo,
|
||||
)
|
||||
return &NpmFetcher{
|
||||
BaseFetcher: NewBaseFetcher(client),
|
||||
}
|
||||
}
|
||||
|
||||
// parseNpmPackageInfo parses NPM package information from JSON
|
||||
func parseNpmPackageInfo(data []byte) (*models.PackageInfo, error) {
|
||||
var packageInfo models.PackageInfo
|
||||
if err := json.Unmarshal(data, &packageInfo); err != nil {
|
||||
return nil, fmt.Errorf("parsing package info: %w", err)
|
||||
}
|
||||
return &packageInfo, nil
|
||||
}
|
||||
|
||||
// GetDependencyTree fetches the complete dependency tree for an NPM package
|
||||
func (nf *NpmFetcher) GetDependencyTree(ctx context.Context, pkg models.Package) (*models.DependencyNode, error) {
|
||||
return nf.fetchDependenciesConcurrent(ctx, pkg)
|
||||
}
|
||||
|
||||
// GetFlattenedDependencies returns a flat list of all dependencies as strings
|
||||
func (nf *NpmFetcher) GetFlattenedDependencies(ctx context.Context, packageName, version string) ([]string, error) {
|
||||
// Reset the visited map to ensure we get a complete tree
|
||||
nf.resetVisited()
|
||||
|
||||
// Get the complete dependency tree
|
||||
tree, err := nf.GetDependencyTree(ctx, models.Package{
|
||||
Name: packageName,
|
||||
Version: version,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch dependency tree: %w", err)
|
||||
}
|
||||
|
||||
// Convert tree to flat list
|
||||
var dependencies []string
|
||||
flattenDependencyTree(tree, &dependencies)
|
||||
|
||||
// Remove duplicates if needed
|
||||
uniqueDeps := make(map[string]bool)
|
||||
var result []string
|
||||
|
||||
for _, dep := range dependencies {
|
||||
if !uniqueDeps[dep] {
|
||||
uniqueDeps[dep] = true
|
||||
result = append(result, dep)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// fetchDependenciesConcurrent recursively fetches package dependencies concurrently
|
||||
func (nf *NpmFetcher) fetchDependenciesConcurrent(ctx context.Context, pkg models.Package) (*models.DependencyNode, error) {
|
||||
key := cacheKey(pkg)
|
||||
if nf.isVisited(key) {
|
||||
return &models.DependencyNode{
|
||||
Name: pkg.Name,
|
||||
Version: pkg.Version,
|
||||
}, nil
|
||||
}
|
||||
nf.markVisited(key)
|
||||
|
||||
packageInfo, err := nf.client.FetchPackageInfo(ctx, pkg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch package info for %s: %w", pkg.Name, err)
|
||||
}
|
||||
|
||||
nf.incrementProgress()
|
||||
|
||||
dependencies := packageInfo.Dependencies
|
||||
node := &models.DependencyNode{
|
||||
Name: pkg.Name,
|
||||
Version: pkg.Version,
|
||||
Dependencies: make(map[string]*models.DependencyNode),
|
||||
}
|
||||
|
||||
if len(dependencies) == 0 {
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// Process dependencies concurrently
|
||||
type result struct {
|
||||
name string
|
||||
node *models.DependencyNode
|
||||
err error
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
resultChan := make(chan result, len(dependencies))
|
||||
|
||||
for depName, depVersion := range dependencies {
|
||||
// Check if context is canceled
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
// Continue processing
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go func(name, version string) {
|
||||
defer wg.Done()
|
||||
version = utils.CleanVersion(version)
|
||||
depNode, err := nf.fetchDependenciesConcurrent(ctx, models.Package{Name: name, Version: version})
|
||||
resultChan <- result{name, depNode, err}
|
||||
}(depName, depVersion)
|
||||
}
|
||||
|
||||
// Wait for all goroutines to complete in a separate goroutine
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(resultChan)
|
||||
}()
|
||||
|
||||
// Collect results
|
||||
for res := range resultChan {
|
||||
if res.err != nil {
|
||||
log.Warnf("Failed to fetch dependency %s: %v", res.name, res.err)
|
||||
continue
|
||||
}
|
||||
node.Dependencies[res.name] = res.node
|
||||
}
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func (nf *NpmFetcher) ResolveVersion(ctx context.Context, packageName, version string) (string, error) {
|
||||
if version != "" {
|
||||
return version, nil
|
||||
}
|
||||
|
||||
latestVersion, err := nf.client.GetLatestVersion(ctx, packageName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get latest version for %s: %w", packageName, err)
|
||||
}
|
||||
|
||||
return latestVersion, nil
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package wrapper
|
||||
|
||||
import "errors"
|
||||
|
||||
const (
|
||||
ErrPackageInstallationDeny = "PACKAGE_INSTALLATION_DENIED"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrPackageInstall = errors.New(ErrPackageInstallationDeny)
|
||||
)
|
||||
@@ -1,182 +0,0 @@
|
||||
package wrapper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
|
||||
"github.com/fatih/color"
|
||||
"github.com/safedep/dry/log"
|
||||
"github.com/safedep/pmg/internal/ui"
|
||||
"github.com/safedep/pmg/pkg/analyser"
|
||||
"github.com/safedep/pmg/pkg/common/utils"
|
||||
"github.com/safedep/pmg/pkg/models"
|
||||
"github.com/safedep/pmg/pkg/registry"
|
||||
vetUtils "github.com/safedep/vet/pkg/common/utils"
|
||||
)
|
||||
|
||||
type PackageManagerWrapper struct {
|
||||
RegistryType registry.RegistryType
|
||||
Flags []string
|
||||
Action string
|
||||
PackageNames []string
|
||||
currentPackage string
|
||||
PackagesToInstall []string
|
||||
}
|
||||
|
||||
func NewPackageManagerWrapper(registryType registry.RegistryType, flags []string, packageNames []string, action string) *PackageManagerWrapper {
|
||||
return &PackageManagerWrapper{
|
||||
RegistryType: registryType,
|
||||
PackageNames: packageNames,
|
||||
Flags: flags,
|
||||
Action: action,
|
||||
}
|
||||
}
|
||||
|
||||
func (pmw *PackageManagerWrapper) Wrap() error {
|
||||
if len(pmw.PackageNames) == 0 {
|
||||
return fmt.Errorf("no packages specified")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
// Scan all packages first
|
||||
for _, pkg := range pmw.PackageNames {
|
||||
ui.StartProgressWriter()
|
||||
var DefaultProgressTotal = 1
|
||||
pmw.currentPackage = pkg
|
||||
progressTracker := ui.TrackProgress(fmt.Sprintf("Scanning %s", pkg), DefaultProgressTotal)
|
||||
|
||||
if err := pmw.scanAndInstall(ctx, progressTracker); err != nil {
|
||||
if errors.Is(err, ErrPackageInstall) {
|
||||
log.Warnf("Skipping package %s due to ErrPackageInstall: %v", pkg, err)
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
pmw.PackagesToInstall = append(pmw.PackagesToInstall, pkg)
|
||||
|
||||
ui.StopProgressWriter()
|
||||
}
|
||||
|
||||
if len(pmw.PackagesToInstall) == 0 {
|
||||
log.Infof("No packages were installed due to security concerns")
|
||||
return nil
|
||||
}
|
||||
// Execute installation after all scans complete
|
||||
if err := pmw.executeInstallation(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Successfully installed all packages")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pmw *PackageManagerWrapper) scanAndInstall(ctx context.Context, progressTracker ui.ProgressTracker) error {
|
||||
factory := registry.NewFetcherFactory(10 * time.Second)
|
||||
fetcher, err := factory.CreateFetcher(pmw.RegistryType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name, version, err := utils.ParsePackageInfo(pmw.currentPackage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if version == "" {
|
||||
version, err = pmw.resolveLatestVersion(ctx, fetcher, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pmw.currentPackage = fmt.Sprintf("%s@%s", name, version)
|
||||
}
|
||||
|
||||
// Get dependencies with progress tracking
|
||||
npmFetcher := fetcher.(*registry.NpmFetcher)
|
||||
npmFetcher.SetProgressTracker(progressTracker)
|
||||
|
||||
deps, err := npmFetcher.GetFlattenedDependencies(ctx, name, version)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set progress for analysis phase
|
||||
ui.IncrementTrackerTotal(progressTracker, int64(len(deps)))
|
||||
if err := pmw.analyzeDependencies(ctx, deps, progressTracker); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pmw *PackageManagerWrapper) resolveLatestVersion(ctx context.Context, fetcher registry.Fetcher, name string) (string, error) {
|
||||
log.Infof("No version specified for %s, fetching latest version...", name)
|
||||
version, err := fetcher.(*registry.NpmFetcher).ResolveVersion(ctx, name, "")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
log.Infof("Latest version of %s is %s", name, version)
|
||||
return version, nil
|
||||
}
|
||||
|
||||
func (pmw *PackageManagerWrapper) analyzeDependencies(ctx context.Context, deps []string, progressTracker ui.ProgressTracker) error {
|
||||
client, err := analyser.GetMalwareAnalysisClient()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error while creating a malware analysis client: %w", err)
|
||||
}
|
||||
|
||||
pkgAnalyser := analyser.New(client, ctx, packagev1.Ecosystem_ECOSYSTEM_NPM)
|
||||
pkgAnalyser.ProgressTracker = progressTracker
|
||||
handler := pkgAnalyser.Handler()
|
||||
|
||||
queue := vetUtils.NewWorkQueue[models.Package](100, 10, handler)
|
||||
queue.Start()
|
||||
defer queue.Stop()
|
||||
|
||||
for _, dep := range deps {
|
||||
name, version, err := utils.ParsePackageInfo(dep)
|
||||
if err != nil {
|
||||
log.Errorf("Error while parsing info of package %s", name)
|
||||
continue
|
||||
}
|
||||
queue.Add(models.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
})
|
||||
}
|
||||
|
||||
queue.Wait()
|
||||
ui.MarkTrackerAsDone(progressTracker)
|
||||
ui.StopProgressWriter()
|
||||
|
||||
if len(pkgAnalyser.MaliciousPkgs) > 0 {
|
||||
if !utils.ConfirmInstallation(pkgAnalyser.MaliciousPkgs) {
|
||||
log.Infof("Installation canceled due to security concerns")
|
||||
return ErrPackageInstall
|
||||
}
|
||||
yellow := color.New(color.FgYellow, color.Bold).SprintfFunc()
|
||||
log.Warnf(yellow("Continuing installation despite security warnings..."))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pmw *PackageManagerWrapper) executeInstallation() error {
|
||||
execPath, err := utils.GetExecutablePath(string(pmw.RegistryType))
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s not found: %w", pmw.RegistryType, err)
|
||||
}
|
||||
|
||||
cmdArgs := []string{pmw.Action}
|
||||
cmdArgs = append(cmdArgs, pmw.Flags...)
|
||||
cmdArgs = append(cmdArgs, pmw.PackagesToInstall...)
|
||||
if err = utils.ExecCmd(execPath, cmdArgs, []string{}); err != nil {
|
||||
return fmt.Errorf("failed to execute %s command: %w", pmw.RegistryType, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user