From 9df5f220e81c4ee705a2af3616104f47ae536813 Mon Sep 17 00:00:00 2001 From: Or Toren Date: Wed, 3 Dec 2025 11:00:27 +0200 Subject: [PATCH 1/7] static-sca-proj changes --- go.mod | 36 +++++----- go.sum | 68 +++++++++---------- scanpullrequest/scanpullrequest.go | 103 ++++++++++++----------------- scanrepository/scanrepository.go | 8 +-- utils/consts.go | 9 ++- utils/params.go | 42 +++++------- utils/params_test.go | 5 +- utils/scandetails.go | 23 +++---- utils/utils.go | 5 +- 9 files changed, 135 insertions(+), 164 deletions(-) diff --git a/go.mod b/go.mod index 183234ac2..04326aec9 100644 --- a/go.mod +++ b/go.mod @@ -1,24 +1,23 @@ module github.com/jfrog/frogbot/v2 -go 1.24.6 +go 1.25.4 require ( - github.com/CycloneDX/cyclonedx-go v0.9.3 github.com/go-git/go-git/v5 v5.16.3 github.com/golang/mock v1.6.0 github.com/google/go-github/v45 v45.2.0 - github.com/jfrog/build-info-go v1.12.0 + github.com/jfrog/build-info-go v1.12.4 github.com/jfrog/froggit-go v1.20.4 github.com/jfrog/gofrog v1.7.6 github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251021143342-49bab7f38cec - github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251023084247-a56afca52451 + github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0 github.com/jfrog/jfrog-cli-security v1.21.9 - github.com/jfrog/jfrog-client-go v1.55.1-0.20251023073119-78f187c9afbf + github.com/jfrog/jfrog-client-go v1.55.1-0.20251202154341-6ef0c0e3e9ce github.com/owenrumney/go-sarif/v3 v3.2.3 github.com/stretchr/testify v1.11.1 - github.com/urfave/cli/v2 v2.27.4 + github.com/urfave/cli/v2 v2.27.7 github.com/xeipuuv/gojsonschema v1.2.0 - golang.org/x/exp v0.0.0-20250911091902-df9299821621 + golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -26,6 +25,7 @@ require ( require ( dario.cat/mergo v1.0.2 // indirect github.com/BurntSushi/toml v1.5.0 // indirect + github.com/CycloneDX/cyclonedx-go v0.9.3 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/andybalholm/brotli v1.2.0 // indirect @@ -39,7 +39,7 @@ require ( github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/fatih/color v1.16.0 // indirect - github.com/forPelevin/gomoji v1.4.0 // indirect + github.com/forPelevin/gomoji v1.4.1 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/gfleury/go-bitbucket-v1 v0.0.0-20230825095122-9bc1711434ab // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect @@ -106,16 +106,16 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect + github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.43.0 // indirect - golang.org/x/mod v0.28.0 // indirect - golang.org/x/net v0.45.0 // indirect + golang.org/x/crypto v0.45.0 // indirect + golang.org/x/mod v0.29.0 // indirect + golang.org/x/net v0.47.0 // indirect golang.org/x/oauth2 v0.31.0 // indirect - golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/term v0.36.0 // indirect - golang.org/x/text v0.30.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect + golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.12.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 // indirect google.golang.org/grpc v1.67.3 // indirect @@ -124,7 +124,7 @@ require ( gopkg.in/warnings.v0 v0.1.2 // indirect ) -// replace github.com/jfrog/jfrog-cli-security => github.com/jfrog/jfrog-cli-security dev +replace github.com/jfrog/jfrog-cli-security => github.com/jfrog/jfrog-cli-security v1.23.0 // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev @@ -132,6 +132,6 @@ require ( // replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev -// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go dev +//replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go master // replace github.com/jfrog/froggit-go => github.com/jfrog/froggit-go master diff --git a/go.sum b/go.sum index 382edcfc0..841c58966 100644 --- a/go.sum +++ b/go.sum @@ -59,8 +59,8 @@ github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FM github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/forPelevin/gomoji v1.4.0 h1:RwrT+GimxEtFnGqq4ep1upwR54J5FP84aVAYJA+p8BQ= -github.com/forPelevin/gomoji v1.4.0/go.mod h1:mM6GtmCgpoQP2usDArc6GjbXrti5+FffolyQfGgPboQ= +github.com/forPelevin/gomoji v1.4.1 h1:7U+Bl8o6RV/dOQz7coQFWj/jX6Ram6/cWFOuFDEPEUo= +github.com/forPelevin/gomoji v1.4.1/go.mod h1:mM6GtmCgpoQP2usDArc6GjbXrti5+FffolyQfGgPboQ= 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= @@ -128,8 +128,8 @@ github.com/jedib0t/go-pretty/v6 v6.6.8 h1:JnnzQeRz2bACBobIaa/r+nqjvws4yEhcmaZ4n1 github.com/jedib0t/go-pretty/v6 v6.6.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5eI= github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw= -github.com/jfrog/build-info-go v1.12.0 h1:/abBQdIxrkYjOwO79sIL0p+XPnMCCtKhiWToHKXXqHg= -github.com/jfrog/build-info-go v1.12.0/go.mod h1:szdz9+WzB7+7PGnILLUgyY+OF5qD5geBT7UGNIxibyw= +github.com/jfrog/build-info-go v1.12.4 h1:eoHoJDOF7Rx2gAOAXEAjbEIpnH+4y5ha2quQT48Py3Q= +github.com/jfrog/build-info-go v1.12.4/go.mod h1:NEJwH1HxzhtWuiT8eR/anbjT0A3OyLBWpZZrDJs+hWQ= github.com/jfrog/froggit-go v1.20.4 h1:N9XkNV00HNjpI8p6xXlF9DrWmvE9hz3z2XRDAYJDweQ= github.com/jfrog/froggit-go v1.20.4/go.mod h1:obSG1SlsWjktkuqmKtpq7MNTTL63e0ot+ucTnlOMV88= github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s= @@ -138,12 +138,12 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251021143342-49bab7f38cec h1:iB5bXWKvzNejqyUgqxKf8YNj+DBx1suf2r2KzI03wkU= github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251021143342-49bab7f38cec/go.mod h1:JE/35+kU8cBET4I4iuNcVBvhm8SF64DAmGgtHRzf5Do= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251023084247-a56afca52451 h1:Q0PY8VSOVsfvXzKiUnn+Rv7Ynf901QW6Wn1CbWpHBD0= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251023084247-a56afca52451/go.mod h1:UOeOwEEmRIi57cRwghN5OBVoqkJieYQQfLpeqw8Yv38= -github.com/jfrog/jfrog-cli-security v1.21.9 h1:QSWADhVE0OYa0SPIc2YhV6QVtuhO6Y+K8rjGHE3MgeY= -github.com/jfrog/jfrog-cli-security v1.21.9/go.mod h1:XoJ6YBf/TrwkqC/r9+x/WKDIwnZogTF6+2wos1PJBUs= -github.com/jfrog/jfrog-client-go v1.55.1-0.20251023073119-78f187c9afbf h1:Ld+lGdCauixqWbkwK+wJn3QbPPBRgY35KgY+MxgrgCg= -github.com/jfrog/jfrog-client-go v1.55.1-0.20251023073119-78f187c9afbf/go.mod h1:jrODQbAbCt97F24d/0bYpqpdc0PFMuBxNJOTfTdW+Fk= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0 h1:EsasTBE5i2MyCESS/icZxKIlObpGiOyW9K67MAaEWco= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0/go.mod h1:d9aADumiyjCBvZLffp8wldvP9XFHxcvk2PoOSUYms2g= +github.com/jfrog/jfrog-cli-security v1.23.0 h1:kV/NQhyID/P9Lf7D+sgscvkIDQ0l1sYMXnjs1EKWXaE= +github.com/jfrog/jfrog-cli-security v1.23.0/go.mod h1:qBAvU9kN41nReJk/O4V9Q/xwiXfAdyhqRIYaOjVm8nE= +github.com/jfrog/jfrog-client-go v1.55.1-0.20251202154341-6ef0c0e3e9ce h1:2y4Nhptm15CLYNlkZRdk6z0J8uLPcCxZFliK2E2lcLQ= +github.com/jfrog/jfrog-client-go v1.55.1-0.20251202154341-6ef0c0e3e9ce/go.mod h1:ureS+L3wNs0qYUBSwH8C9PjwnraTX9ibZu7JkaqjO/E= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= @@ -204,8 +204,8 @@ github.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9l github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= -github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= +github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= +github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/owenrumney/go-sarif/v3 v3.2.3 h1:n6mdX5ugKwCrZInvBsf6WumXmpAe3mbmQXgkXlIq34U= github.com/owenrumney/go-sarif/v3 v3.2.3/go.mod h1:1bV7t8SZg7pX41spaDkEUs8/yEjzk9JapztMoX1XNjg= github.com/package-url/packageurl-go v0.1.3 h1:4juMED3hHiz0set3Vq3KeQ75KD1avthoXLtmE3I0PLs= @@ -276,8 +276,8 @@ github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.22.17 h1:SYzXoiPfQjHBbkYxbew5prZHS1TOLT3ierW8SYLqtVQ= github.com/urfave/cli v1.22.17/go.mod h1:b0ht0aqgH/6pBYzzxURyrM4xXNgsoT/n2ZzwQiEhNVo= -github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8= -github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ= +github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU= +github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4= github.com/vbauerster/mpb/v8 v8.10.2 h1:2uBykSHAYHekE11YvJhKxYmLATKHAGorZwFlyNw4hHM= github.com/vbauerster/mpb/v8 v8.10.2/go.mod h1:+Ja4P92E3/CorSZgfDtK46D7AVbDqmBQRTmyTqPElo0= github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 h1:JwtAtbp7r/7QSyGz8mKUbYJBg2+6Cd7OjM8o/GNOcVo= @@ -297,8 +297,8 @@ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofm github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= -github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 h1:FnBeRrxr7OU4VvAzt5X7s6266i6cSVkkFPS0TuXWbIg= +github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -311,15 +311,15 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= -golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= -golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= -golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY= +golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= -golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= +golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -333,8 +333,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM= -golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo= @@ -345,8 +345,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -378,16 +378,16 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= -golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= -golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -395,8 +395,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -404,8 +404,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= -golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/scanpullrequest/scanpullrequest.go b/scanpullrequest/scanpullrequest.go index 639553b7b..45cfe7eb9 100644 --- a/scanpullrequest/scanpullrequest.go +++ b/scanpullrequest/scanpullrequest.go @@ -14,12 +14,12 @@ import ( "github.com/jfrog/froggit-go/vcsclient" "github.com/jfrog/froggit-go/vcsutils" "github.com/jfrog/jfrog-cli-security/utils/formats" + "github.com/jfrog/jfrog-cli-security/utils/formats/violationutils" "github.com/jfrog/jfrog-cli-security/utils/jasutils" "github.com/jfrog/jfrog-cli-security/utils/results" "github.com/jfrog/jfrog-cli-security/utils/results/conversion" "github.com/jfrog/jfrog-cli-security/utils/xsc" "github.com/jfrog/jfrog-client-go/utils/log" - "github.com/owenrumney/go-sarif/v3/pkg/report/v210/sarif" ) const ( @@ -175,7 +175,6 @@ func createBaseScanDetails(repoConfig *utils.Repository, client vcsclient.VcsCli SetResultsContext(repositoryCloneUrl, repoConfig.Watches, repoConfig.JFrogProjectKey, repoConfig.IncludeVulnerabilities, len(repoConfig.AllowedLicenses) > 0). SetFixableOnly(repoConfig.FixableOnly). SetConfigProfile(repoConfig.ConfigProfile). - SetSkipAutoInstall(repoConfig.SkipAutoInstall). SetDisableJas(repoConfig.DisableJas). SetXscPRGitInfoContext(repoConfig.Project, client, repoConfig.PullRequestDetails). SetDiffScan(!repoConfig.IncludeAllVulnerabilities). @@ -270,7 +269,7 @@ func auditPullRequestSourceCode(repoConfig *utils.Repository, scanDetails *utils } // Convert to issues - if issues, e := scanResultsToIssuesCollection(scanResults, repoConfig.AllowedLicenses, workingDirs...); e == nil { + if issues, e := scanResultsToIssuesCollection(scanResults, workingDirs...); e == nil { issuesCollection = issues return } else { @@ -300,109 +299,92 @@ func filterOutFailedScansIfAllowPartialResultsEnabled(targetResults, sourceResul targetResult := targetResults.Targets[idx] sourceResult := sourceResults.Targets[idx] - filterOutScaResultsIfScanFailed(targetResult, sourceResult) - filterJasResultsIfScanFailed(targetResult, sourceResult, jasutils.Applicability) - filterJasResultsIfScanFailed(targetResult, sourceResult, jasutils.Secrets) - filterJasResultsIfScanFailed(targetResult, sourceResult, jasutils.IaC) - filterJasResultsIfScanFailed(targetResult, sourceResult, jasutils.Sast) + filterOutScaResultsIfScanFailed(targetResult, sourceResult, sourceResults.Violations) + filterJasResultsIfScanFailed(targetResult, sourceResult, results.CmdStepContextualAnalysis) + filterJasResultsIfScanFailed(targetResult, sourceResult, results.CmdStepSecrets) + filterJasResultsIfScanFailed(targetResult, sourceResult, results.CmdStepIaC) + filterJasResultsIfScanFailed(targetResult, sourceResult, results.CmdStepSast) } return nil } -func filterJasResultsIfScanFailed(targetResult, sourceResult *results.TargetResults, scanType jasutils.JasScanType) { - switch scanType { - case jasutils.Applicability: - if isJasScanFailedInSourceOrTarget(sourceResult.JasResults.ApplicabilityScanResults, targetResult.JasResults.ApplicabilityScanResults) { - log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, scanType.String())) +func filterJasResultsIfScanFailed(targetResult, sourceResult *results.TargetResults, cmdStep results.SecurityCommandStep) { + sourceResults := []*results.TargetResults{sourceResult} + targetResults := []*results.TargetResults{targetResult} + switch cmdStep { + case results.CmdStepContextualAnalysis: + if isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) { + log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, cmdStep)) sourceResult.JasResults.ApplicabilityScanResults = nil } - case jasutils.Secrets: - if isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasVulnerabilities.SecretsScanResults, targetResult.JasResults.JasVulnerabilities.SecretsScanResults) { - log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, scanType.String())) + case results.CmdStepSecrets: + if isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) { + log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, cmdStep)) sourceResult.JasResults.JasVulnerabilities.SecretsScanResults = nil } - - if (sourceResult.JasResults.JasViolations.SecretsScanResults != nil || targetResult.JasResults.JasViolations.SecretsScanResults != nil) && isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasViolations.SecretsScanResults, targetResult.JasResults.JasViolations.SecretsScanResults) { - log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, scanType.String())) + if (sourceResult.JasResults.JasViolations.SecretsScanResults != nil || targetResult.JasResults.JasViolations.SecretsScanResults != nil) && + isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) { + log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, cmdStep)) sourceResult.JasResults.JasViolations.SecretsScanResults = nil } - case jasutils.IaC: - if isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasVulnerabilities.IacScanResults, targetResult.JasResults.JasVulnerabilities.IacScanResults) { - log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, scanType.String())) + case results.CmdStepIaC: + if isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) { + log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, cmdStep)) sourceResult.JasResults.JasVulnerabilities.IacScanResults = nil } - if (sourceResult.JasResults.JasViolations.IacScanResults != nil || targetResult.JasResults.JasViolations.IacScanResults != nil) && isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasViolations.IacScanResults, targetResult.JasResults.JasViolations.IacScanResults) { - log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, scanType.String())) + if (sourceResult.JasResults.JasViolations.IacScanResults != nil || targetResult.JasResults.JasViolations.IacScanResults != nil) && isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) { + log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, cmdStep)) sourceResult.JasResults.JasViolations.IacScanResults = nil } - case jasutils.Sast: - if isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasVulnerabilities.SastScanResults, targetResult.JasResults.JasVulnerabilities.SastScanResults) { - log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, scanType.String())) + case results.CmdStepSast: + if isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) { + log.Debug(fmt.Sprintf(vulnerabilitiesFilteringErrorMessage, cmdStep)) sourceResult.JasResults.JasVulnerabilities.SastScanResults = nil } - if (sourceResult.JasResults.JasViolations.SastScanResults != nil || targetResult.JasResults.JasViolations.SastScanResults != nil) && isJasScanFailedInSourceOrTarget(sourceResult.JasResults.JasViolations.SastScanResults, targetResult.JasResults.JasViolations.SastScanResults) { - log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, scanType.String())) + if (sourceResult.JasResults.JasViolations.SastScanResults != nil || targetResult.JasResults.JasViolations.SastScanResults != nil) && isScanFailedInSourceOrTarget(sourceResults, targetResults, cmdStep) { + log.Debug(fmt.Sprintf(violationsFilteringErrorMessage, cmdStep)) sourceResult.JasResults.JasViolations.SastScanResults = nil } } } -func isJasScanFailedInSourceOrTarget(sourceResults, targetResults []results.ScanResult[[]*sarif.Run]) bool { +func isScanFailedInSourceOrTarget(sourceResults, targetResults []*results.TargetResults, step results.SecurityCommandStep) bool { for _, scanResult := range sourceResults { - if scanResult.StatusCode != 0 { + if scanResult.ResultsStatus.IsScanFailed(step) { return true } } for _, scanResult := range targetResults { - if scanResult.StatusCode != 0 { + if scanResult.ResultsStatus.IsScanFailed(step) { return true } } return false } -func filterOutScaResultsIfScanFailed(targetResult, sourceResult *results.TargetResults) { +func filterOutScaResultsIfScanFailed(targetResult, sourceResult *results.TargetResults, sourceViolations *violationutils.Violations) { // Filter out new Sca results - if sourceResult.ScaResults.ScanStatusCode != 0 || targetResult.ScaResults.ScanStatusCode != 0 { - var statusCode int + if sourceResult.ResultsStatus.IsScanFailed(results.CmdStepSca) || targetResult.ResultsStatus.IsScanFailed(results.CmdStepSca) { + var statusCode *int var errorSource string - if sourceResult.ScaResults.ScanStatusCode != 0 { - statusCode = sourceResult.ScaResults.ScanStatusCode + if sourceResult.ResultsStatus.IsScanFailed(results.CmdStepSca) { + statusCode = sourceResult.ResultsStatus.ScaScanStatusCode errorSource = "source" } else { - statusCode = targetResult.ScaResults.ScanStatusCode + statusCode = targetResult.ResultsStatus.ScaScanStatusCode errorSource = "target" } log.Debug(fmt.Sprintf("Sca scan on %s code has completed with errors (status %d). Sca vulnerability results will be removed from final report", errorSource, statusCode)) sourceResult.ScaResults.Sbom = nil - if sourceResult.ScaResults.Violations != nil { + if sourceViolations.Sca != nil { log.Debug(fmt.Sprintf("Sca scan on %s has completed with errors (status %d). Sca violations results will be removed from final report", errorSource, statusCode)) - sourceResult.ScaResults.Violations = nil + sourceViolations.Sca = nil } } - // Note: Although we have a slice on ScanResults in DeprecatedXrayResults, in fact there is only a single entry - hasScaFailure := false - for _, deprecatedScaResult := range targetResult.ScaResults.DeprecatedXrayResults { - if deprecatedScaResult.StatusCode != 0 { - hasScaFailure = true - break - } - } - for _, deprecatedScaResult := range sourceResult.ScaResults.DeprecatedXrayResults { - if deprecatedScaResult.StatusCode != 0 { - hasScaFailure = true - break - } - } - if hasScaFailure { - log.Debug("Sca scan has completed with errors. Sca vulnerabilities and violations results will be removed from final report") - // Violations are being filtered as well as they are included in the DeprecatedXrayResults - sourceResult.ScaResults.DeprecatedXrayResults = nil - } } // Sorts the Targets slice in both targetResults and sourceResults @@ -426,11 +408,10 @@ func sortTargetsByPhysicalLocation(targetResults, sourceResults *results.Securit return nil } -func scanResultsToIssuesCollection(scanResults *results.SecurityCommandResults, allowedLicenses []string, workingDirs ...string) (issuesCollection *issues.ScansIssuesCollection, err error) { +func scanResultsToIssuesCollection(scanResults *results.SecurityCommandResults, workingDirs ...string) (issuesCollection *issues.ScansIssuesCollection, err error) { simpleJsonResults, err := conversion.NewCommandResultsConvertor(conversion.ResultConvertParams{ IncludeVulnerabilities: scanResults.IncludesVulnerabilities(), HasViolationContext: scanResults.HasViolationContext(), - AllowedLicenses: allowedLicenses, IncludeLicenses: true, SimplifiedOutput: true, }).ConvertToSimpleJson(scanResults) diff --git a/scanrepository/scanrepository.go b/scanrepository/scanrepository.go index 5b9e0b7b5..1bac80700 100644 --- a/scanrepository/scanrepository.go +++ b/scanrepository/scanrepository.go @@ -12,9 +12,6 @@ import ( "github.com/go-git/go-git/v5" biutils "github.com/jfrog/build-info-go/utils" - "github.com/jfrog/frogbot/v2/packagehandlers" - "github.com/jfrog/frogbot/v2/utils" - "github.com/jfrog/frogbot/v2/utils/outputwriter" "github.com/jfrog/froggit-go/vcsclient" "github.com/jfrog/froggit-go/vcsutils" "github.com/jfrog/gofrog/version" @@ -28,6 +25,10 @@ import ( "github.com/jfrog/jfrog-client-go/utils/log" "golang.org/x/exp/maps" "golang.org/x/exp/slices" + + "github.com/jfrog/frogbot/v2/packagehandlers" + "github.com/jfrog/frogbot/v2/utils" + "github.com/jfrog/frogbot/v2/utils/outputwriter" ) const analyticsScanRepositoryScanType = "monitor" @@ -135,7 +136,6 @@ func (cfp *ScanRepositoryCmd) setCommandPrerequisites(repository *utils.Reposito SetResultsContext(repositoryCloneUrl, repository.Watches, repository.JFrogProjectKey, repository.IncludeVulnerabilities, len(repository.AllowedLicenses) > 0). SetFixableOnly(repository.FixableOnly). SetConfigProfile(repository.ConfigProfile). - SetSkipAutoInstall(repository.SkipAutoInstall). SetAllowPartialResults(repository.AllowPartialResults). SetDisableJas(repository.DisableJas) diff --git a/utils/consts.go b/utils/consts.go index 8fa515d77..4bd513c9d 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -38,10 +38,10 @@ const ( JfrogConfigProfileEnv = "JF_CONFIG_PROFILE" // Git environment variables - GitProvider = "JF_GIT_PROVIDER" - GitRepoOwnerEnv = "JF_GIT_OWNER" - GitRepoEnv = "JF_GIT_REPO" - GitProjectEnv = "JF_GIT_PROJECT" + GitProvider = "JF_GIT_PROVIDER" + GitRepoOwnerEnv = "JF_GIT_OWNER" + GitRepoEnv = "JF_GIT_REPO" + GitProjectEnv = "JF_GIT_PROJECT" GitUsernameEnv = "JF_GIT_USERNAME" GitUseLocalRepositoryEnv = "JF_USE_LOCAL_REPOSITORY" GitDependencyGraphSubmissionEnv = "JF_UPLOAD_SBOM_TO_VCS" @@ -76,7 +76,6 @@ const ( DisableJasEnv = "JF_DISABLE_ADVANCED_SECURITY" DetectionOnlyEnv = "JF_SKIP_AUTOFIX" AllowedLicensesEnv = "JF_ALLOWED_LICENSES" - SkipAutoInstallEnv = "JF_SKIP_AUTO_INSTALL" AllowPartialResultsEnv = "JF_ALLOW_PARTIAL_RESULTS" WatchesDelimiter = "," diff --git a/utils/params.go b/utils/params.go index b1abdbf0d..c7037e239 100644 --- a/utils/params.go +++ b/utils/params.go @@ -19,10 +19,11 @@ import ( "github.com/jfrog/jfrog-client-go/xsc/services" "golang.org/x/exp/slices" - "github.com/jfrog/frogbot/v2/utils/outputwriter" securityutils "github.com/jfrog/jfrog-cli-security/utils" "github.com/jfrog/jfrog-cli-security/utils/severityutils" + "github.com/jfrog/frogbot/v2/utils/outputwriter" + "github.com/jfrog/build-info-go/utils" "github.com/jfrog/froggit-go/vcsclient" "github.com/jfrog/froggit-go/vcsutils" @@ -95,7 +96,6 @@ type Project struct { DepsRepo string `yaml:"repository,omitempty"` InstallCommandName string InstallCommandArgs []string - IsRecursiveScan bool } func (p *Project) setDefaultsIfNeeded() error { @@ -106,7 +106,6 @@ func (p *Project) setDefaultsIfNeeded() error { // If no working directories are provided, and none exist in the environment variable, we designate the project's root directory as our sole working directory. // We then execute a recursive scan across the entire project, commencing from the root. workingDir = RootDir - p.IsRecursiveScan = true p.WorkingDirs = append(p.WorkingDirs, workingDir) } else { workingDirs := strings.Split(workingDir, ",") @@ -226,11 +225,6 @@ func (s *Scan) setDefaultsIfNeeded() (err error) { } s.MinSeverity = severity.String() } - if !s.SkipAutoInstall { - if s.SkipAutoInstall, err = getBoolEnv(SkipAutoInstallEnv, false); err != nil { - return - } - } if len(s.Projects) == 0 { s.Projects = append(s.Projects, Project{}) } @@ -240,7 +234,7 @@ func (s *Scan) setDefaultsIfNeeded() (err error) { } } if !s.AllowPartialResults { - if s.AllowPartialResults, err = getBoolEnv(AllowPartialResultsEnv, false); err != nil { + if s.AllowPartialResults, err = getBoolEnv(AllowPartialResultsEnv, true); err != nil { return } } @@ -285,21 +279,21 @@ func (jp *JFrogPlatform) setDefaultsIfNeeded() (err error) { type Git struct { GitProvider vcsutils.VcsProvider vcsclient.VcsInfo - RepoOwner string - RepoName string `yaml:"repoName,omitempty"` - Branches []string `yaml:"branches,omitempty"` - BranchNameTemplate string `yaml:"branchNameTemplate,omitempty"` - CommitMessageTemplate string `yaml:"commitMessageTemplate,omitempty"` - PullRequestTitleTemplate string `yaml:"pullRequestTitleTemplate,omitempty"` - PullRequestCommentTitle string `yaml:"pullRequestCommentTitle,omitempty"` - PullRequestSecretComments bool `yaml:"pullRequestSecretComments,omitempty"` - AvoidExtraMessages bool `yaml:"avoidExtraMessages,omitempty"` - EmailAuthor string `yaml:"emailAuthor,omitempty"` - AggregateFixes bool `yaml:"aggregateFixes,omitempty"` - PullRequestDetails vcsclient.PullRequestInfo - RepositoryCloneUrl string - UseLocalRepository bool - UploadSbomToVcs *bool `yaml:"uploadSbomToVcs,omitempty"` + RepoOwner string + RepoName string `yaml:"repoName,omitempty"` + Branches []string `yaml:"branches,omitempty"` + BranchNameTemplate string `yaml:"branchNameTemplate,omitempty"` + CommitMessageTemplate string `yaml:"commitMessageTemplate,omitempty"` + PullRequestTitleTemplate string `yaml:"pullRequestTitleTemplate,omitempty"` + PullRequestCommentTitle string `yaml:"pullRequestCommentTitle,omitempty"` + PullRequestSecretComments bool `yaml:"pullRequestSecretComments,omitempty"` + AvoidExtraMessages bool `yaml:"avoidExtraMessages,omitempty"` + EmailAuthor string `yaml:"emailAuthor,omitempty"` + AggregateFixes bool `yaml:"aggregateFixes,omitempty"` + PullRequestDetails vcsclient.PullRequestInfo + RepositoryCloneUrl string + UseLocalRepository bool + UploadSbomToVcs *bool `yaml:"uploadSbomToVcs,omitempty"` } func (g *Git) GetRepositoryHttpsCloneUrl(gitClient vcsclient.VcsClient) (string, error) { diff --git a/utils/params_test.go b/utils/params_test.go index ab098b4ce..1a0d224b7 100644 --- a/utils/params_test.go +++ b/utils/params_test.go @@ -8,9 +8,10 @@ import ( "testing" "github.com/golang/mock/gomock" - "github.com/jfrog/frogbot/v2/testdata" "github.com/stretchr/testify/require" + "github.com/jfrog/frogbot/v2/testdata" + "github.com/jfrog/froggit-go/vcsclient" "github.com/jfrog/jfrog-cli-core/v2/utils/config" "github.com/jfrog/jfrog-client-go/utils/tests" @@ -448,7 +449,6 @@ func TestExtractProjectParamsFromEnv(t *testing.T) { assert.Equal(t, "", project.PipRequirementsFile) assert.Equal(t, "", project.InstallCommandName) assert.Equal(t, []string(nil), project.InstallCommandArgs) - assert.True(t, project.IsRecursiveScan) // Test value extraction SetEnvAndAssert(t, map[string]string{ @@ -468,7 +468,6 @@ func TestExtractProjectParamsFromEnv(t *testing.T) { assert.Equal(t, "nuget", project.InstallCommandName) assert.Equal(t, []string{"restore"}, project.InstallCommandArgs) assert.Equal(t, "repository", project.DepsRepo) - assert.False(t, project.IsRecursiveScan) } func TestFrogbotConfigAggregator_unmarshalFrogbotConfigYaml(t *testing.T) { diff --git a/utils/scandetails.go b/utils/scandetails.go index c9e91b343..acc86600e 100644 --- a/utils/scandetails.go +++ b/utils/scandetails.go @@ -9,8 +9,9 @@ import ( "github.com/jfrog/froggit-go/vcsclient" "github.com/jfrog/jfrog-cli-core/v2/utils/config" "github.com/jfrog/jfrog-cli-security/commands/audit" - "github.com/jfrog/jfrog-cli-security/sca/bom/buildinfo" - "github.com/jfrog/jfrog-cli-security/sca/scan/scangraph" + "github.com/jfrog/jfrog-cli-security/policy/enforcer" + "github.com/jfrog/jfrog-cli-security/sca/bom/xrayplugin" + "github.com/jfrog/jfrog-cli-security/sca/scan/enrich" "github.com/jfrog/jfrog-cli-security/utils/results" "github.com/jfrog/jfrog-cli-security/utils/severityutils" "github.com/jfrog/jfrog-client-go/utils/log" @@ -26,7 +27,6 @@ type ScanDetails struct { client vcsclient.VcsClient fixableOnly bool disableJas bool - skipAutoInstall bool minSeverityFilter severityutils.Severity baseBranch string configProfile *xscservices.ConfigProfile @@ -82,11 +82,6 @@ func (sc *ScanDetails) SetFixableOnly(fixable bool) *ScanDetails { return sc } -func (sc *ScanDetails) SetSkipAutoInstall(skipAutoInstall bool) *ScanDetails { - sc.skipAutoInstall = skipAutoInstall - return sc -} - func (sc *ScanDetails) SetMinSeverity(minSeverity string) (*ScanDetails, error) { if minSeverity == "" { return sc, nil @@ -161,16 +156,17 @@ func (sc *ScanDetails) RunInstallAndAudit(workDirs ...string) (auditResults *res SetInstallCommandName(sc.InstallCommandName). SetInstallCommandArgs(sc.InstallCommandArgs). SetTechnologies(sc.GetTechFromInstallCmdIfExists()). - SetSkipAutoInstall(sc.skipAutoInstall). SetAllowPartialResults(sc.allowPartialResults). SetExclusions(sc.PathExclusions). - SetIsRecursiveScan(sc.IsRecursiveScan). SetUseJas(!sc.DisableJas()). SetConfigProfile(sc.configProfile) auditParams := audit.NewAuditParams(). - SetBomGenerator(buildinfo.NewBuildInfoBomGenerator()). - SetScaScanStrategy(scangraph.NewScanGraphStrategy()). + SetBomGenerator(xrayplugin.NewXrayLibBomGenerator()). + SetScaScanStrategy(enrich.NewEnrichScanStrategy()). + SetUploadCdxResults(!sc.diffScan || sc.ResultsToCompare != nil). + SetGitContext(sc.XscGitInfoContext). + SetRtResultRepository(frogbotUploadRtRepoPath). SetWorkingDirs(workDirs). SetMinSeverityFilter(sc.MinSeverityFilter()). SetFixableOnly(sc.FixableOnly()). @@ -180,7 +176,8 @@ func (sc *ScanDetails) RunInstallAndAudit(workDirs ...string) (auditResults *res SetResultsToCompare(sc.ResultsToCompare). SetMultiScanId(sc.MultiScanId). SetThreads(MaxConcurrentScanners). - SetStartTime(sc.StartTime) + SetStartTime(sc.StartTime). + SetViolationGenerator(enforcer.NewPolicyEnforcerViolationGenerator()) return audit.RunAudit(auditParams) } diff --git a/utils/utils.go b/utils/utils.go index 1563aca91..f47c5961f 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -13,7 +13,6 @@ import ( "strings" "sync" - "github.com/jfrog/frogbot/v2/utils/issues" "github.com/jfrog/froggit-go/vcsclient" "github.com/jfrog/gofrog/version" "github.com/jfrog/jfrog-cli-core/v2/common/commands" @@ -29,6 +28,8 @@ import ( "github.com/jfrog/jfrog-client-go/utils/errorutils" "github.com/jfrog/jfrog-client-go/utils/io/fileutils" "github.com/jfrog/jfrog-client-go/utils/log" + + "github.com/jfrog/frogbot/v2/utils/issues" ) const ( @@ -38,6 +39,7 @@ const ( branchNameRegex = `[~^:?\\\[\]@{}*]` dependencySubmissionFrogbotDetector = "JFrog Frogbot" frogbotUrl = "https://github.com/jfrog/frogbot" + frogbotUploadRtRepoPath = "frogbot" // Branch validation error messages branchInvalidChars = "branch name cannot contain the following chars ~, ^, :, ?, *, [, ], @, {, }" @@ -247,7 +249,6 @@ func GenerateFrogbotSarifReport(extendedResults *results.SecurityCommandResults, convertor := conversion.NewCommandResultsConvertor(conversion.ResultConvertParams{ IncludeVulnerabilities: extendedResults.IncludesVulnerabilities(), HasViolationContext: extendedResults.HasViolationContext(), - AllowedLicenses: allowedLicenses, }) sarifReport, err := convertor.ConvertToSarif(extendedResults) if err != nil { From 4752ca49aa90ec9d2e948dcaa33c68b89912e771 Mon Sep 17 00:00:00 2001 From: kerenr-jfrog Date: Wed, 3 Dec 2025 11:46:12 +0200 Subject: [PATCH 2/7] fix scanpullrequest_test.go --- scanpullrequest/scanpullrequest_test.go | 358 ++++++++---------------- 1 file changed, 112 insertions(+), 246 deletions(-) diff --git a/scanpullrequest/scanpullrequest_test.go b/scanpullrequest/scanpullrequest_test.go index 982ad35bc..31ceeb54c 100644 --- a/scanpullrequest/scanpullrequest_test.go +++ b/scanpullrequest/scanpullrequest_test.go @@ -16,6 +16,7 @@ import ( "github.com/golang/mock/gomock" "github.com/jfrog/frogbot/v2/testdata" + "github.com/jfrog/jfrog-cli-security/utils/formats/violationutils" "github.com/jfrog/jfrog-cli-security/utils/jasutils" "github.com/jfrog/jfrog-cli-security/utils/xsc" "github.com/owenrumney/go-sarif/v3/pkg/report/v210/sarif" @@ -26,14 +27,10 @@ import ( "github.com/jfrog/froggit-go/vcsclient" "github.com/jfrog/froggit-go/vcsutils" coreconfig "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-cli-security/tests/validations" "github.com/jfrog/jfrog-cli-security/utils/formats" - "github.com/jfrog/jfrog-cli-security/utils/formats/sarifutils" "github.com/jfrog/jfrog-cli-security/utils/results" - "github.com/jfrog/jfrog-cli-security/utils/severityutils" "github.com/jfrog/jfrog-client-go/utils/io/fileutils" "github.com/jfrog/jfrog-client-go/utils/log" - "github.com/jfrog/jfrog-client-go/xray/services" "github.com/stretchr/testify/assert" ) @@ -67,47 +64,15 @@ func CreateMockVcsClient(t *testing.T) *testdata.MockVcsClient { } func TestScanResultsToIssuesCollection(t *testing.T) { - allowedLicenses := []string{"MIT"} - auditResults := &results.SecurityCommandResults{EntitledForJas: true, ResultContext: results.ResultContext{IncludeVulnerabilities: true}, Targets: []*results.TargetResults{{ + auditResults := &results.SecurityCommandResults{ResultsMetaData: results.ResultsMetaData{EntitledForJas: true, ResultContext: results.ResultContext{IncludeVulnerabilities: true}}, Targets: []*results.TargetResults{{ ScanTarget: results.ScanTarget{Target: "dummy"}, - ScaResults: &results.ScaScanResults{ - DeprecatedXrayResults: validations.NewMockScaResults(services.ScanResponse{ - Vulnerabilities: []services.Vulnerability{ - {Cves: []services.Cve{{Id: "CVE-2022-2122"}}, Severity: "High", Components: map[string]services.Component{"Dep-1": {FixedVersions: []string{"1.2.3"}}}}, - {Cves: []services.Cve{{Id: "CVE-2023-3122"}}, Severity: "Low", Components: map[string]services.Component{"Dep-2": {FixedVersions: []string{"1.2.2"}}}}, - }, - Licenses: []services.License{{Key: "Apache-2.0", Components: map[string]services.Component{"Dep-1": {FixedVersions: []string{"1.2.3"}}}}}, - }), - }, + ScaResults: &results.ScaScanResults{}, JasResults: &results.JasScansResults{ - ApplicabilityScanResults: validations.NewMockJasRuns( - sarifutils.CreateRunWithDummyResults( - sarifutils.CreateDummyPassingResult("applic_CVE-2023-3122"), - sarifutils.CreateResultWithOneLocation("file1", 1, 10, 2, 11, "snippet", "applic_CVE-2022-2122", ""), - ), - ), + ApplicabilityScanResults: []*sarif.Run{}, JasVulnerabilities: results.JasScanResults{ - IacScanResults: validations.NewMockJasRuns( - sarifutils.CreateRunWithDummyResults( - sarifutils.CreateResultWithLocations("Missing auto upgrade was detected", "rule", severityutils.SeverityToSarifSeverityLevel(severityutils.High).String(), - sarifutils.CreateLocation("file1", 1, 10, 2, 11, "aws-violation"), - ), - ), - ), - SecretsScanResults: validations.NewMockJasRuns( - sarifutils.CreateRunWithDummyResults( - sarifutils.CreateResultWithLocations("Secret", "rule", severityutils.SeverityToSarifSeverityLevel(severityutils.High).String(), - sarifutils.CreateLocation("index.js", 5, 6, 7, 8, "access token exposed"), - ), - ), - ), - SastScanResults: validations.NewMockJasRuns( - sarifutils.CreateRunWithDummyResults( - sarifutils.CreateResultWithLocations("XSS Vulnerability", "rule", severityutils.SeverityToSarifSeverityLevel(severityutils.High).String(), - sarifutils.CreateLocation("file1", 1, 10, 2, 11, "snippet"), - ), - ), - ), + IacScanResults: []*sarif.Run{}, + SecretsScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, }, }}} @@ -214,7 +179,7 @@ func TestScanResultsToIssuesCollection(t *testing.T) { }, } - issuesRows, err := scanResultsToIssuesCollection(auditResults, allowedLicenses) + issuesRows, err := scanResultsToIssuesCollection(auditResults) if assert.NoError(t, err) { assert.ElementsMatch(t, expectedOutput.ScaVulnerabilities, issuesRows.ScaVulnerabilities) @@ -686,16 +651,12 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { scanType: jasutils.Applicability, targetResult: &results.TargetResults{ JasResults: &results.JasScansResults{ - ApplicabilityScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + ApplicabilityScanResults: []*sarif.Run{}, }, }, sourceResult: &results.TargetResults{ JasResults: &results.JasScansResults{ - ApplicabilityScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, + ApplicabilityScanResults: []*sarif.Run{}, }, }, hasFailure: true, @@ -704,30 +665,24 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { name: "Secrets scanner failed in target - should remove secrets vulnerabilities and violations", scanType: jasutils.Secrets, targetResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{SecretsScanStatusCode: &[]int{1}[0]}, JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, + SecretsScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, + SecretsScanResults: []*sarif.Run{}, }, }, }, sourceResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{SecretsScanStatusCode: &[]int{0}[0]}, JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, }, }, }, @@ -737,30 +692,24 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { name: "IaC scanner failed in both source and target - should remove IaC vulnerabilities and violations", scanType: jasutils.IaC, targetResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{IacScanStatusCode: &[]int{1}[0]}, JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, + IacScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, + IacScanResults: []*sarif.Run{}, }, }, }, sourceResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{IacScanStatusCode: &[]int{1}[0]}, JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, + IacScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, + IacScanResults: []*sarif.Run{}, }, }, }, @@ -772,28 +721,20 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { targetResult: &results.TargetResults{ JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SastScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SastScanResults: []*sarif.Run{}, }, }, }, sourceResult: &results.TargetResults{ JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, + SastScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, + SastScanResults: []*sarif.Run{}, }, }, }, @@ -804,59 +745,31 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { scanType: jasutils.Applicability, targetResult: &results.TargetResults{ JasResults: &results.JasScansResults{ - ApplicabilityScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + ApplicabilityScanResults: []*sarif.Run{}, JasVulnerabilities: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, }, }, sourceResult: &results.TargetResults{ JasResults: &results.JasScansResults{ - ApplicabilityScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + ApplicabilityScanResults: []*sarif.Run{}, JasVulnerabilities: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, }, }, @@ -867,7 +780,7 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { // Call the function under test - filterJasResultsIfScanFailed(test.targetResult, test.sourceResult, test.scanType) + filterJasResultsIfScanFailed(test.targetResult, test.sourceResult, results.SecurityCommandStep(test.scanType)) // Validate the results based on scan type and test case if !test.hasFailure { @@ -904,40 +817,38 @@ func TestFilterOutScaResultsIfScanFailed(t *testing.T) { name string targetResult *results.TargetResults sourceResult *results.TargetResults + violations *violationutils.Violations hasFailure bool }{ { name: "SCA scan failed - should remove SCA results", targetResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{ScaScanStatusCode: &[]int{-1}[0]}, ScaResults: &results.ScaScanResults{ - ScanStatusCode: -1, - Sbom: nil, - Violations: []services.Violation{{IssueId: "test-violation"}}, + Sbom: nil, }, }, sourceResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{ScaScanStatusCode: &[]int{0}[0]}, ScaResults: &results.ScaScanResults{ - ScanStatusCode: 0, - Sbom: nil, - Violations: []services.Violation{{IssueId: "source-violation"}}, + Sbom: nil, }, }, + violations: &violationutils.Violations{}, hasFailure: true, }, { name: "SCA scan succeeded - should not remove SCA results", targetResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{ScaScanStatusCode: &[]int{0}[0]}, ScaResults: &results.ScaScanResults{ - ScanStatusCode: 0, - Sbom: nil, - Violations: []services.Violation{{IssueId: "target-violation"}}, + Sbom: nil, }, }, sourceResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{ScaScanStatusCode: &[]int{0}[0]}, ScaResults: &results.ScaScanResults{ - ScanStatusCode: 0, - Sbom: nil, - Violations: []services.Violation{{IssueId: "source-violation"}}, + Sbom: nil, }, }, hasFailure: false, @@ -946,13 +857,10 @@ func TestFilterOutScaResultsIfScanFailed(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - filterOutScaResultsIfScanFailed(test.targetResult, test.sourceResult) + filterOutScaResultsIfScanFailed(test.targetResult, test.sourceResult, test.violations) if test.hasFailure { assert.Nil(t, test.sourceResult.ScaResults.Sbom, "SBOM should be removed when SCA scan failed") - assert.Nil(t, test.sourceResult.ScaResults.Violations, "Violations should be removed when SCA scan failed") - } else { - assert.Equal(t, []services.Violation{{IssueId: "source-violation"}}, test.sourceResult.ScaResults.Violations, "Violations should NOT be removed when SCA scan succeeds") } }) } @@ -970,36 +878,26 @@ func TestFilterOutFailedScansIfAllowPartialResultsEnabled(t *testing.T) { targetResults: &results.SecurityCommandResults{ Targets: []*results.TargetResults{ { - ScanTarget: results.ScanTarget{Target: "test-target"}, - ScaResults: &results.ScaScanResults{ - ScanStatusCode: 0, - Violations: []services.Violation{{IssueId: "target-violation"}}, + ResultsStatus: results.ResultsStatus{ + ScaScanStatusCode: &[]int{0}[0], + ContextualAnalysisStatusCode: &[]int{0}[0], + SecretsScanStatusCode: &[]int{0}[0], + IacScanStatusCode: &[]int{0}[0], + SastScanStatusCode: &[]int{0}[0], }, + ScanTarget: results.ScanTarget{Target: "test-target"}, + ScaResults: &results.ScaScanResults{}, JasResults: &results.JasScansResults{ - ApplicabilityScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + ApplicabilityScanResults: []*sarif.Run{}, JasVulnerabilities: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, }, }, @@ -1008,36 +906,26 @@ func TestFilterOutFailedScansIfAllowPartialResultsEnabled(t *testing.T) { sourceResults: &results.SecurityCommandResults{ Targets: []*results.TargetResults{ { - ScanTarget: results.ScanTarget{Target: "test-target"}, - ScaResults: &results.ScaScanResults{ - ScanStatusCode: 0, - Violations: []services.Violation{{IssueId: "source-violation"}}, + ResultsStatus: results.ResultsStatus{ + ScaScanStatusCode: &[]int{0}[0], + ContextualAnalysisStatusCode: &[]int{0}[0], + SecretsScanStatusCode: &[]int{0}[0], + IacScanStatusCode: &[]int{0}[0], + SastScanStatusCode: &[]int{0}[0], }, + ScanTarget: results.ScanTarget{Target: "test-target"}, + ScaResults: &results.ScaScanResults{}, JasResults: &results.JasScansResults{ - ApplicabilityScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + ApplicabilityScanResults: []*sarif.Run{}, JasVulnerabilities: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, }, }, @@ -1050,36 +938,26 @@ func TestFilterOutFailedScansIfAllowPartialResultsEnabled(t *testing.T) { targetResults: &results.SecurityCommandResults{ Targets: []*results.TargetResults{ { - ScanTarget: results.ScanTarget{Target: "test-target"}, - ScaResults: &results.ScaScanResults{ - ScanStatusCode: -1, - Violations: []services.Violation{{IssueId: "target-violation"}}, + ResultsStatus: results.ResultsStatus{ + ScaScanStatusCode: &[]int{-1}[0], + ContextualAnalysisStatusCode: &[]int{0}[0], + SecretsScanStatusCode: &[]int{1}[0], + IacScanStatusCode: &[]int{1}[0], + SastScanStatusCode: &[]int{0}[0], }, + ScanTarget: results.ScanTarget{Target: "test-target"}, + ScaResults: &results.ScaScanResults{}, JasResults: &results.JasScansResults{ - ApplicabilityScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + ApplicabilityScanResults: []*sarif.Run{}, JasVulnerabilities: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 1}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, }, }, @@ -1088,36 +966,26 @@ func TestFilterOutFailedScansIfAllowPartialResultsEnabled(t *testing.T) { sourceResults: &results.SecurityCommandResults{ Targets: []*results.TargetResults{ { - ScanTarget: results.ScanTarget{Target: "test-target"}, - ScaResults: &results.ScaScanResults{ - ScanStatusCode: 0, - Violations: []services.Violation{{IssueId: "source-violation"}}, + ResultsStatus: results.ResultsStatus{ + ScaScanStatusCode: &[]int{0}[0], + ContextualAnalysisStatusCode: &[]int{0}[0], + SecretsScanStatusCode: &[]int{0}[0], + IacScanStatusCode: &[]int{0}[0], + SastScanStatusCode: &[]int{0}[0], }, + ScanTarget: results.ScanTarget{Target: "test-target"}, + ScaResults: &results.ScaScanResults{}, JasResults: &results.JasScansResults{ - ApplicabilityScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + ApplicabilityScanResults: []*sarif.Run{}, JasVulnerabilities: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, JasViolations: results.JasScanResults{ - SecretsScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - IacScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, - SastScanResults: []results.ScanResult[[]*sarif.Run]{ - {StatusCode: 0}, - }, + SecretsScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{}, + SastScanResults: []*sarif.Run{}, }, }, }, @@ -1134,7 +1002,6 @@ func TestFilterOutFailedScansIfAllowPartialResultsEnabled(t *testing.T) { sourceTarget := test.sourceResults.Targets[0] if test.hasFailure { - assert.Nil(t, sourceTarget.ScaResults.Violations, "SCA violations should be removed when SCA scan failed") assert.Nil(t, sourceTarget.JasResults.JasVulnerabilities.SecretsScanResults, "Secrets scan results should be removed when Secrets scan failed") assert.Nil(t, sourceTarget.JasResults.JasViolations.SecretsScanResults, "Secrets violation results should be removed when Secrets scan failed") assert.Nil(t, sourceTarget.JasResults.JasVulnerabilities.IacScanResults, "IaC scan results should be removed when IaC scan failed") @@ -1143,7 +1010,6 @@ func TestFilterOutFailedScansIfAllowPartialResultsEnabled(t *testing.T) { assert.NotNil(t, sourceTarget.JasResults.JasVulnerabilities.SastScanResults, "SAST scan results should NOT be removed when SAST scan succeeds") assert.NotNil(t, sourceTarget.JasResults.JasViolations.SastScanResults, "SAST violation results should NOT be removed when SAST scan succeeds") } else { - assert.NotNil(t, sourceTarget.ScaResults.Violations, "SCA violations should NOT be removed when SCA scan succeeds") assert.NotNil(t, sourceTarget.JasResults.JasVulnerabilities.SecretsScanResults, "Secrets scan results should NOT be removed when Secrets scan succeeds") assert.NotNil(t, sourceTarget.JasResults.JasViolations.SecretsScanResults, "Secrets violation results should NOT be removed when Secrets scan succeeds") assert.NotNil(t, sourceTarget.JasResults.JasVulnerabilities.IacScanResults, "IaC scan results should NOT be removed when IaC scan succeeds") From 82aeca58a044223b6b59953df6664d8322015bd7 Mon Sep 17 00:00:00 2001 From: kerenr-jfrog Date: Wed, 3 Dec 2025 14:25:27 +0200 Subject: [PATCH 3/7] fix scanrepository_test.go --- scanrepository/scanrepository_test.go | 81 ++------------------------- 1 file changed, 6 insertions(+), 75 deletions(-) diff --git a/scanrepository/scanrepository_test.go b/scanrepository/scanrepository_test.go index c5f458e27..e23ab5ec7 100644 --- a/scanrepository/scanrepository_test.go +++ b/scanrepository/scanrepository_test.go @@ -25,7 +25,6 @@ import ( "github.com/jfrog/froggit-go/vcsclient" "github.com/jfrog/froggit-go/vcsutils" "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" - "github.com/jfrog/jfrog-cli-security/tests/validations" "github.com/jfrog/jfrog-cli-security/utils/formats" "github.com/jfrog/jfrog-cli-security/utils/results" "github.com/jfrog/jfrog-cli-security/utils/techutils" @@ -496,43 +495,11 @@ func TestCreateVulnerabilitiesMap(t *testing.T) { { name: "Scan results with vulnerabilities and no violations", scanResults: &results.SecurityCommandResults{ - ResultContext: results.ResultContext{IncludeVulnerabilities: true}, + ResultsMetaData: results.ResultsMetaData{ + ResultContext: results.ResultContext{IncludeVulnerabilities: true}}, Targets: []*results.TargetResults{{ ScanTarget: results.ScanTarget{Target: "target1"}, - ScaResults: &results.ScaScanResults{ - DeprecatedXrayResults: validations.NewMockScaResults( - services.ScanResponse{ - Vulnerabilities: []services.Vulnerability{ - { - Cves: []services.Cve{ - {Id: "CVE-2023-1234", CvssV3Score: "9.1"}, - {Id: "CVE-2023-4321", CvssV3Score: "8.9"}, - }, - Severity: "Critical", - Components: map[string]services.Component{ - "vuln1": { - FixedVersions: []string{"1.9.1", "2.0.3", "2.0.5"}, - ImpactPaths: [][]services.ImpactPathNode{{{ComponentId: "root"}, {ComponentId: "vuln1"}}}, - }, - }, - }, - { - Cves: []services.Cve{ - {Id: "CVE-2022-1234", CvssV3Score: "7.1"}, - {Id: "CVE-2022-4321", CvssV3Score: "7.9"}, - }, - Severity: "High", - Components: map[string]services.Component{ - "vuln2": { - FixedVersions: []string{"2.4.1", "2.6.3", "2.8.5"}, - ImpactPaths: [][]services.ImpactPathNode{{{ComponentId: "root"}, {ComponentId: "vuln1"}, {ComponentId: "vuln2"}}}, - }, - }, - }, - }, - }, - ), - }, + ScaResults: &results.ScaScanResults{}, JasResults: &results.JasScansResults{}, }}, }, @@ -551,47 +518,11 @@ func TestCreateVulnerabilitiesMap(t *testing.T) { { name: "Scan results with violations and no vulnerabilities", scanResults: &results.SecurityCommandResults{ - ResultContext: results.ResultContext{IncludeVulnerabilities: true, Watches: []string{"w1"}}, + ResultsMetaData: results.ResultsMetaData{ + ResultContext: results.ResultContext{IncludeVulnerabilities: true, Watches: []string{"w1"}}}, Targets: []*results.TargetResults{{ ScanTarget: results.ScanTarget{Target: "target1"}, - ScaResults: &results.ScaScanResults{ - DeprecatedXrayResults: validations.NewMockScaResults( - services.ScanResponse{ - Violations: []services.Violation{ - { - ViolationType: "security", - WatchName: "w1", - Cves: []services.Cve{ - {Id: "CVE-2023-1234", CvssV3Score: "9.1"}, - {Id: "CVE-2023-4321", CvssV3Score: "8.9"}, - }, - Severity: "Critical", - Components: map[string]services.Component{ - "viol1": { - FixedVersions: []string{"1.9.1", "2.0.3", "2.0.5"}, - ImpactPaths: [][]services.ImpactPathNode{{{ComponentId: "root"}, {ComponentId: "viol1"}}}, - }, - }, - }, - { - ViolationType: "security", - WatchName: "w1", - Cves: []services.Cve{ - {Id: "CVE-2022-1234", CvssV3Score: "7.1"}, - {Id: "CVE-2022-4321", CvssV3Score: "7.9"}, - }, - Severity: "High", - Components: map[string]services.Component{ - "viol2": { - FixedVersions: []string{"2.4.1", "2.6.3", "2.8.5"}, - ImpactPaths: [][]services.ImpactPathNode{{{ComponentId: "root"}, {ComponentId: "viol1"}, {ComponentId: "viol2"}}}, - }, - }, - }, - }, - }, - ), - }, + ScaResults: &results.ScaScanResults{}, JasResults: &results.JasScansResults{}, }}, }, From 7f0c2c6f6f40f23067677c85f958fe80882cf033 Mon Sep 17 00:00:00 2001 From: kerenr-jfrog Date: Thu, 4 Dec 2025 12:00:43 +0200 Subject: [PATCH 4/7] fix scanpullrequest_test.go --- scanpullrequest/scanpullrequest.go | 2 +- scanpullrequest/scanpullrequest_test.go | 77 ++++++++++++++++--------- 2 files changed, 52 insertions(+), 27 deletions(-) diff --git a/scanpullrequest/scanpullrequest.go b/scanpullrequest/scanpullrequest.go index 45cfe7eb9..3d12ad1d9 100644 --- a/scanpullrequest/scanpullrequest.go +++ b/scanpullrequest/scanpullrequest.go @@ -379,7 +379,7 @@ func filterOutScaResultsIfScanFailed(targetResult, sourceResult *results.TargetR } log.Debug(fmt.Sprintf("Sca scan on %s code has completed with errors (status %d). Sca vulnerability results will be removed from final report", errorSource, statusCode)) sourceResult.ScaResults.Sbom = nil - if sourceViolations.Sca != nil { + if sourceViolations != nil && sourceViolations.Sca != nil { log.Debug(fmt.Sprintf("Sca scan on %s has completed with errors (status %d). Sca violations results will be removed from final report", errorSource, statusCode)) sourceViolations.Sca = nil } diff --git a/scanpullrequest/scanpullrequest_test.go b/scanpullrequest/scanpullrequest_test.go index 31ceeb54c..e203fd08e 100644 --- a/scanpullrequest/scanpullrequest_test.go +++ b/scanpullrequest/scanpullrequest_test.go @@ -16,9 +16,13 @@ import ( "github.com/golang/mock/gomock" "github.com/jfrog/frogbot/v2/testdata" + securityutils "github.com/jfrog/jfrog-cli-security/utils" + "github.com/jfrog/jfrog-cli-security/utils/formats/sarifutils" "github.com/jfrog/jfrog-cli-security/utils/formats/violationutils" "github.com/jfrog/jfrog-cli-security/utils/jasutils" + "github.com/jfrog/jfrog-cli-security/utils/severityutils" "github.com/jfrog/jfrog-cli-security/utils/xsc" + "github.com/jfrog/jfrog-client-go/xray/services" "github.com/owenrumney/go-sarif/v3/pkg/report/v210/sarif" "github.com/jfrog/frogbot/v2/utils" @@ -65,14 +69,52 @@ func CreateMockVcsClient(t *testing.T) *testdata.MockVcsClient { func TestScanResultsToIssuesCollection(t *testing.T) { auditResults := &results.SecurityCommandResults{ResultsMetaData: results.ResultsMetaData{EntitledForJas: true, ResultContext: results.ResultContext{IncludeVulnerabilities: true}}, Targets: []*results.TargetResults{{ + ResultsStatus: results.ResultsStatus{ + ScaScanStatusCode: securityutils.NewIntPtr(0), + ContextualAnalysisStatusCode: securityutils.NewIntPtr(0), + IacScanStatusCode: securityutils.NewIntPtr(0), + SecretsScanStatusCode: securityutils.NewIntPtr(0), + SastScanStatusCode: securityutils.NewIntPtr(0), + }, ScanTarget: results.ScanTarget{Target: "dummy"}, - ScaResults: &results.ScaScanResults{}, + ScaResults: &results.ScaScanResults{ + DeprecatedXrayResults: []services.ScanResponse{{ + Vulnerabilities: []services.Vulnerability{ + {Cves: []services.Cve{{Id: "CVE-2022-2122"}}, Severity: "High", Components: map[string]services.Component{"Dep-1": {FixedVersions: []string{"1.2.3"}}}}, + {Cves: []services.Cve{{Id: "CVE-2023-3122"}}, Severity: "Low", Components: map[string]services.Component{"Dep-2": {FixedVersions: []string{"1.2.2"}}}}, + }, + Licenses: []services.License{{Key: "Apache-2.0", Components: map[string]services.Component{"Dep-1": {FixedVersions: []string{"1.2.3"}}}}}, + }}, + }, JasResults: &results.JasScansResults{ - ApplicabilityScanResults: []*sarif.Run{}, + ApplicabilityScanResults: []*sarif.Run{ + sarifutils.CreateRunWithDummyResults( + sarifutils.CreateDummyPassingResult("applic_CVE-2023-3122"), + sarifutils.CreateResultWithOneLocation("file1", 1, 10, 2, 11, "snippet", "applic_CVE-2022-2122", ""), + ), + }, JasVulnerabilities: results.JasScanResults{ - IacScanResults: []*sarif.Run{}, - SecretsScanResults: []*sarif.Run{}, - SastScanResults: []*sarif.Run{}, + IacScanResults: []*sarif.Run{ + sarifutils.CreateRunWithDummyResults( + sarifutils.CreateResultWithLocations("Missing auto upgrade was detected", "rule", severityutils.SeverityToSarifSeverityLevel(severityutils.High).String(), + sarifutils.CreateLocation("file1", 1, 10, 2, 11, "aws-violation"), + ), + ), + }, + SecretsScanResults: []*sarif.Run{ + sarifutils.CreateRunWithDummyResults( + sarifutils.CreateResultWithLocations("Secret", "rule", severityutils.SeverityToSarifSeverityLevel(severityutils.High).String(), + sarifutils.CreateLocation("index.js", 5, 6, 7, 8, "access token exposed"), + ), + ), + }, + SastScanResults: []*sarif.Run{ + sarifutils.CreateRunWithDummyResults( + sarifutils.CreateResultWithLocations("XSS Vulnerability", "rule", severityutils.SeverityToSarifSeverityLevel(severityutils.High).String(), + sarifutils.CreateLocation("file1", 1, 10, 2, 11, "snippet"), + ), + ), + }, }, }, }}} @@ -82,7 +124,7 @@ func TestScanResultsToIssuesCollection(t *testing.T) { Applicable: "Applicable", FixedVersions: []string{"1.2.3"}, ImpactedDependencyDetails: formats.ImpactedDependencyDetails{ - SeverityDetails: formats.SeverityDetails{Severity: "High", SeverityNumValue: 26}, + SeverityDetails: formats.SeverityDetails{Severity: "High", SeverityNumValue: 31}, ImpactedDependencyName: "Dep-1", }, Cves: []formats.CveRow{{Id: "CVE-2022-2122", Applicability: &formats.Applicability{Status: "Applicable", ScannerDescription: "rule-msg", Evidence: []formats.Evidence{{Reason: "result-msg", Location: formats.Location{File: "file1", StartLine: 1, StartColumn: 10, EndLine: 2, EndColumn: 11, Snippet: "snippet"}}}}}}, @@ -101,7 +143,7 @@ func TestScanResultsToIssuesCollection(t *testing.T) { { SeverityDetails: formats.SeverityDetails{ Severity: "High", - SeverityNumValue: 26, + SeverityNumValue: 31, }, ScannerInfo: formats.ScannerInfo{ ScannerDescription: "rule-msg", @@ -122,7 +164,7 @@ func TestScanResultsToIssuesCollection(t *testing.T) { { SeverityDetails: formats.SeverityDetails{ Severity: "High", - SeverityNumValue: 26, + SeverityNumValue: 31, }, ScannerInfo: formats.ScannerInfo{ ScannerDescription: "rule-msg", @@ -143,7 +185,7 @@ func TestScanResultsToIssuesCollection(t *testing.T) { { SeverityDetails: formats.SeverityDetails{ Severity: "High", - SeverityNumValue: 26, + SeverityNumValue: 31, }, ScannerInfo: formats.ScannerInfo{ ScannerDescription: "rule-msg", @@ -160,23 +202,6 @@ func TestScanResultsToIssuesCollection(t *testing.T) { }, }, }, - LicensesViolations: []formats.LicenseViolationRow{ - { - LicenseRow: formats.LicenseRow{ - LicenseKey: "Apache-2.0", - ImpactedDependencyDetails: formats.ImpactedDependencyDetails{ - SeverityDetails: formats.SeverityDetails{ - Severity: "Medium", - SeverityNumValue: 19, - }, - ImpactedDependencyName: "Dep-1", - }, - }, - ViolationContext: formats.ViolationContext{ - Watch: "jfrog_custom_license_violation", - }, - }, - }, } issuesRows, err := scanResultsToIssuesCollection(auditResults) From 862d5d917dd9bd4a20647ed1e961f321a6c48a76 Mon Sep 17 00:00:00 2001 From: kerenr-jfrog Date: Sun, 7 Dec 2025 16:02:08 +0200 Subject: [PATCH 5/7] merged v3_er into branch + added lock files for ScanPullRequestSubdir test --- go.mod | 2 +- go.sum | 8 ++++---- .../test-proj-subdir/sourceBranch.gz | Bin 267 -> 1177 bytes .../test-proj-subdir/targetBranch.gz | Bin 13662 -> 14303 bytes utils/params.go | 1 - 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 6a4cf5335..b7dcc91fc 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/jfrog/froggit-go v1.20.6 github.com/jfrog/gofrog v1.7.6 github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251118100843-ac34330a70d3 - github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251023084247-a56afca52451 + github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0 github.com/jfrog/jfrog-cli-security v1.22.0 github.com/jfrog/jfrog-client-go v1.55.1-0.20251119183924-d765eb708cec github.com/owenrumney/go-sarif/v3 v3.2.3 diff --git a/go.sum b/go.sum index fad07a39f..ec7eb191f 100644 --- a/go.sum +++ b/go.sum @@ -138,10 +138,10 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251118100843-ac34330a70d3 h1:sIjwBWBmyb7UEqP0IhQ22CWOedOPlNetyHzECS3sUyA= github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251118100843-ac34330a70d3/go.mod h1:3hLZrM2xT+PkIevIGret4x1xDFTaVoNu3h374QnrKyc= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251023084247-a56afca52451 h1:Q0PY8VSOVsfvXzKiUnn+Rv7Ynf901QW6Wn1CbWpHBD0= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251023084247-a56afca52451/go.mod h1:UOeOwEEmRIi57cRwghN5OBVoqkJieYQQfLpeqw8Yv38= -github.com/jfrog/jfrog-cli-security v1.22.0 h1:KNovA+BA1IpE0c0jI6jWF33fOimgylR9a7T84ZmgNJI= -github.com/jfrog/jfrog-cli-security v1.22.0/go.mod h1:uoACrGyWZViNPU0STC0fF38bVKtNXjm3hzWW/DKI0DY= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0 h1:EsasTBE5i2MyCESS/icZxKIlObpGiOyW9K67MAaEWco= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0/go.mod h1:d9aADumiyjCBvZLffp8wldvP9XFHxcvk2PoOSUYms2g= +github.com/jfrog/jfrog-cli-security v1.23.0 h1:kV/NQhyID/P9Lf7D+sgscvkIDQ0l1sYMXnjs1EKWXaE= +github.com/jfrog/jfrog-cli-security v1.23.0/go.mod h1:qBAvU9kN41nReJk/O4V9Q/xwiXfAdyhqRIYaOjVm8nE= github.com/jfrog/jfrog-client-go v1.55.1-0.20251119183924-d765eb708cec h1:tNfeGi/2FuxIUSi8urFZuqa33grynAHwLRH6iIK/DB0= github.com/jfrog/jfrog-client-go v1.55.1-0.20251119183924-d765eb708cec/go.mod h1:ureS+L3wNs0qYUBSwH8C9PjwnraTX9ibZu7JkaqjO/E= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= diff --git a/testdata/scanpullrequest/test-proj-subdir/sourceBranch.gz b/testdata/scanpullrequest/test-proj-subdir/sourceBranch.gz index 232ba33b7b03fcb7d79c013237c0bcef116a989f..c4a7f429423be6a74a63265ad0ddce4c24a7c45e 100755 GIT binary patch literal 1177 zcmV;K1ZMjmiwFP!000001MOE?lcGov_PKwB;Va86pcBy>;o06ti?sT(flxxJ99DtX zM(=N5!10>ZR%d5=V`KOtl(Le_D!wl>NwMQ24djt(YbKreIbZ@vk`!K9NnlQ|dn8za zWd%-P(gK@cSf1g9L{j)k=Q)FqJryOBi5Wn^M%VAVW&fW7pX%=c?2#^VrX=>qIz&Gx zAnwvXofagH5k!s)^cOjii}n8ue60VE34^=ypJ#%vbRx9!Qmp@H;4b}LRhy{>Am@%Y zqo&xgAKT-G{%Mhw4)tFM_2)QA3hF=ea~}B|zqtN?J|&YWTeU#yOEPuPKlNKUy#xqD z#||wl#Zb&{HVlFZoCD=x<)e877CuA(2NNFhK{WR@aKgE8qhRJRy1H#-y0~>@(SZwW z9oQN?aT{4IXhREPZ?}k}gu|l1=o@o5*^tw4O^S=GUybk4^?i45%64?{hvn%09AH|t zbTEN7I6d??Cu5H%3!dGXFM%GKOwV)i7n(-E2u_4HlQ0p0Pc8 zgSH0@1iek@4x6gLa%7LItQgsA&6+i{s*dxksxz%OvcpPSkQrM5t;JhSYM?oo)7#>B z;&t7%tGY1bjW9o8D{m^{6J4;;U##u6)n_awOT22v^Yd}nIn;oSBUSRfBFU45x$0w( zY`-R(Rrz=yu#Mo{-v|(L7q0yMnW54YcL%{Il3gbFRK|fZD)bhwitFiu;0*&^8CAIWWWtvG8gc zAC8Dle?2R{X-0L>SY07FB=kBpj_Z9y4MXvi^e{DhrvWwlAsKnPO^sYwGy0&rRlHuo z;M&HJ9=EgRw3*eE^kBGVva(VqFi(`t*;E!A&Js5O;dYu^_iaLmn?ap6`*4dnqwmNo zep+cViYj-nQ$r6}_MWU?IY?h2)eV>Z6;z75;%@iWBduuJWqMgE%|FcV(Qm-;@dvqc zcbjCzD=hQbUbSn^c(p8=L@Ohd)J0Xzm#ewSC|mG}R;^M|mRcr1E@}3%sFhbDUUWIV zi)67kZ==zI_o~ZHF-w$Q7WBM^HfJPXC-S7&MHw9A@PWzu^F9;Q>f8LER^vAOTd$;8Vk6+GF)n(mzjlJ19OBE z%O4fkuZF(?MUFM)04M+exc5{M literal 267 zcmV+m0rdVKiwFSl9KB=!1MQOEYJ)Ho#=Z6_LawJfiTMM2o3tKFT#aJlpp3qIqn5%p z+y-kmM*ZC!INwKdPQC>6A?y0K&it?`ZU2~D9{|u&lBp^^Rp4T-X9yEQY7SCyPJju` zctYe2X8FM2gX!Zacrg1CmwnMzRiB)5-s4jL3E_SIH~0qM&A*TZQ%c4B6=$&K{~Ijj z-R*;givQ1q)&uiJ_CIi+b`IA z+qzLROYG2<=(ZMpl*R*Mx3SJP)`!{5b2*u#FzoiWI%M_erF>GNa7>TsU$4Hh Rva)j5oB+9~x|9G6005&FjKBZ@ diff --git a/testdata/scanpullrequest/test-proj-subdir/targetBranch.gz b/testdata/scanpullrequest/test-proj-subdir/targetBranch.gz index effcf4996e43407feeeddfaa1c8c032b05e3f43c..ebba86e9ef0ee684a16ce8120415f54d52c0ff3d 100755 GIT binary patch literal 14303 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 GF#iV~&2C!& literal 13662 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 diff --git a/utils/params.go b/utils/params.go index 484c415bd..d7beef151 100644 --- a/utils/params.go +++ b/utils/params.go @@ -21,7 +21,6 @@ import ( "github.com/jfrog/frogbot/v2/utils/outputwriter" - "github.com/jfrog/build-info-go/utils" "github.com/jfrog/froggit-go/vcsclient" "github.com/jfrog/froggit-go/vcsutils" coreconfig "github.com/jfrog/jfrog-cli-core/v2/utils/config" From d07f5227d0e670ff3beb2de8296864cbebc0329f Mon Sep 17 00:00:00 2001 From: kerenr-jfrog Date: Tue, 9 Dec 2025 12:04:00 +0200 Subject: [PATCH 6/7] progress --- go.mod | 3 ++- go.sum | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b7dcc91fc..46a9cee89 100644 --- a/go.mod +++ b/go.mod @@ -123,7 +123,8 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect ) -replace github.com/jfrog/jfrog-cli-security => github.com/jfrog/jfrog-cli-security v1.23.0 +// fix-sbom-component-ref-compare +replace github.com/jfrog/jfrog-cli-security => github.com/kerenr-jfrog/jfrog-cli-security v0.0.0-20251209075212-257d63a4e1f2 // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev diff --git a/go.sum b/go.sum index ec7eb191f..6f6f36e21 100644 --- a/go.sum +++ b/go.sum @@ -140,14 +140,14 @@ github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251118100843-ac34330a70d3 h1:s github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251118100843-ac34330a70d3/go.mod h1:3hLZrM2xT+PkIevIGret4x1xDFTaVoNu3h374QnrKyc= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0 h1:EsasTBE5i2MyCESS/icZxKIlObpGiOyW9K67MAaEWco= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0/go.mod h1:d9aADumiyjCBvZLffp8wldvP9XFHxcvk2PoOSUYms2g= -github.com/jfrog/jfrog-cli-security v1.23.0 h1:kV/NQhyID/P9Lf7D+sgscvkIDQ0l1sYMXnjs1EKWXaE= -github.com/jfrog/jfrog-cli-security v1.23.0/go.mod h1:qBAvU9kN41nReJk/O4V9Q/xwiXfAdyhqRIYaOjVm8nE= github.com/jfrog/jfrog-client-go v1.55.1-0.20251119183924-d765eb708cec h1:tNfeGi/2FuxIUSi8urFZuqa33grynAHwLRH6iIK/DB0= github.com/jfrog/jfrog-client-go v1.55.1-0.20251119183924-d765eb708cec/go.mod h1:ureS+L3wNs0qYUBSwH8C9PjwnraTX9ibZu7JkaqjO/E= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= +github.com/kerenr-jfrog/jfrog-cli-security v0.0.0-20251209075212-257d63a4e1f2 h1:171RZZDmmBf+bKzc8JkpkfNnTfxwlfRttWUOjKdyEoM= +github.com/kerenr-jfrog/jfrog-cli-security v0.0.0-20251209075212-257d63a4e1f2/go.mod h1:qBAvU9kN41nReJk/O4V9Q/xwiXfAdyhqRIYaOjVm8nE= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= From 0a58b2b725070c35e9e1fa0748ae07e4fc36b33e Mon Sep 17 00:00:00 2001 From: kerenr-jfrog Date: Thu, 11 Dec 2025 10:43:53 +0200 Subject: [PATCH 7/7] fixed utils_test linter issue + add lock files to scan pull request and scan repository tests --- go.mod | 39 ++++---- go.sum | 86 +++++++++++------- scanpullrequest/scanpullrequest_test.go | 28 +++++- .../clean-test-proj/sourceBranch.gz | Bin 161 -> 322 bytes .../clean-test-proj/targetBranch.gz | Bin 161 -> 323 bytes .../multi-dir-test-proj/sourceBranch.gz | Bin 650 -> 1867 bytes .../multi-dir-test-proj/targetBranch.gz | Bin 377 -> 1277 bytes .../scanpullrequest/test-proj/targetBranch.gz | Bin 13621 -> 14276 bytes .../npm1/package-lock.json | 74 +++++++++++++++ .../npm2/package-lock.json | 18 ++++ .../npm/package-lock.json | 74 +++++++++++++++ utils/utils_test.go | 16 ++-- 12 files changed, 272 insertions(+), 63 deletions(-) create mode 100644 testdata/scanrepository/cmd/aggregate-multi-dir/npm1/package-lock.json create mode 100644 testdata/scanrepository/cmd/aggregate-multi-dir/npm2/package-lock.json create mode 100644 testdata/scanrepository/cmd/aggregate-multi-project/npm/package-lock.json diff --git a/go.mod b/go.mod index 46a9cee89..4e6bc6736 100644 --- a/go.mod +++ b/go.mod @@ -6,17 +6,17 @@ require ( github.com/go-git/go-git/v5 v5.16.3 github.com/golang/mock v1.6.0 github.com/google/go-github/v45 v45.2.0 - github.com/jfrog/build-info-go v1.12.4 + github.com/jfrog/build-info-go v1.12.5-0.20251209031413-f5f0e93dc8db github.com/jfrog/froggit-go v1.20.6 github.com/jfrog/gofrog v1.7.6 - github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251118100843-ac34330a70d3 + github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20251210074251-c15fabe27f7f github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0 - github.com/jfrog/jfrog-cli-security v1.22.0 - github.com/jfrog/jfrog-client-go v1.55.1-0.20251119183924-d765eb708cec + github.com/jfrog/jfrog-cli-security v1.24.0 + github.com/jfrog/jfrog-client-go v1.55.1-0.20251209090954-d6b1c70d3a5e github.com/owenrumney/go-sarif/v3 v3.2.3 github.com/stretchr/testify v1.11.1 github.com/urfave/cli/v2 v2.27.7 - golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 + golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 ) require ( @@ -29,9 +29,11 @@ require ( github.com/buger/jsonparser v1.1.1 // indirect github.com/c-bata/go-prompt v0.2.6 // indirect github.com/chzyer/readline v1.5.1 // indirect + github.com/clipperhouse/stringish v0.1.1 // indirect + github.com/clipperhouse/uax29/v2 v2.3.0 // indirect github.com/cloudflare/circl v1.6.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect - github.com/cyphar/filepath-securejoin v0.4.1 // indirect + github.com/cyphar/filepath-securejoin v0.6.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/emirpasic/gods v1.18.1 // indirect @@ -58,19 +60,19 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/jedib0t/go-pretty/v6 v6.6.8 // indirect + github.com/jedib0t/go-pretty/v6 v6.7.5 // indirect github.com/jfrog/archiver/v3 v3.6.1 // indirect github.com/jfrog/jfrog-apps-config v1.0.1 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.1 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/pgzip v1.2.6 // indirect github.com/ktrysmt/go-bitbucket v0.9.80 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mattn/go-tty v0.0.3 // indirect + github.com/mattn/go-runewidth v0.0.19 // indirect + github.com/mattn/go-tty v0.0.7 // indirect github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.0 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -85,10 +87,9 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sagikazarmark/locafero v0.11.0 // indirect + github.com/sagikazarmark/locafero v0.12.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.3.1 // indirect - github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.10.0 // indirect github.com/spf13/pflag v1.0.10 // indirect @@ -107,16 +108,16 @@ require ( github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.45.0 // indirect - golang.org/x/mod v0.29.0 // indirect + golang.org/x/mod v0.30.0 // indirect golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.31.0 // indirect + golang.org/x/oauth2 v0.33.0 // indirect golang.org/x/sync v0.18.0 // indirect golang.org/x/sys v0.38.0 // indirect golang.org/x/term v0.37.0 // indirect golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.12.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 // indirect - google.golang.org/grpc v1.67.3 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect + google.golang.org/grpc v1.72.1 // indirect google.golang.org/protobuf v1.36.8 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect @@ -124,7 +125,8 @@ require ( ) // fix-sbom-component-ref-compare -replace github.com/jfrog/jfrog-cli-security => github.com/kerenr-jfrog/jfrog-cli-security v0.0.0-20251209075212-257d63a4e1f2 +//attiasas:update_ftoggit_1_20_6 +replace github.com/jfrog/jfrog-cli-security => github.com/kerenr-jfrog/jfrog-cli-security v0.0.0-20251210110046-5c022222a67c // replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev @@ -132,6 +134,7 @@ replace github.com/jfrog/jfrog-cli-security => github.com/kerenr-jfrog/jfrog-cli // replace github.com/jfrog/build-info-go => github.com/jfrog/build-info-go dev -//replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go master +// attiasas:fix_cdx_remediation_api +replace github.com/jfrog/jfrog-client-go => github.com/attiasas/jfrog-client-go v0.0.0-20251210093930-2b29e73a9eb0 // replace github.com/jfrog/froggit-go => github.com/jfrog/froggit-go master diff --git a/go.sum b/go.sum index 6f6f36e21..40b622f63 100644 --- a/go.sum +++ b/go.sum @@ -21,6 +21,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/attiasas/jfrog-client-go v0.0.0-20251210093930-2b29e73a9eb0 h1:Xc39FpfwsS2F0eVKmQ2KyMpb/7Yluk56jgLVCd90mT4= +github.com/attiasas/jfrog-client-go v0.0.0-20251210093930-2b29e73a9eb0/go.mod h1:WQ5Y+oKYyHFAlCbHN925bWhnShTd2ruxZ6YTpb76fpU= github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= @@ -38,13 +40,17 @@ github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObk github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= +github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= +github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= +github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= +github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= -github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is= +github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= 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= @@ -77,6 +83,10 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= github.com/go-git/go-git/v5 v5.16.3 h1:Z8BtvxZ09bYm/yYNgPKCzgWtaRqDTgIKRgIRHBfU6Z8= github.com/go-git/go-git/v5 v5.16.3/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= +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-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 h1:FWNFq4fM1wPfcK40yHE5UO3RUdSNPaBC+j3PokzA6OQ= @@ -124,35 +134,33 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jedib0t/go-pretty/v6 v6.6.8 h1:JnnzQeRz2bACBobIaa/r+nqjvws4yEhcmaZ4n1QzsEc= -github.com/jedib0t/go-pretty/v6 v6.6.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= +github.com/jedib0t/go-pretty/v6 v6.7.5 h1:9dJSWTJnsXJVVAbvxIFxeHf/JxoJd7GUl5o3UzhtuiM= +github.com/jedib0t/go-pretty/v6 v6.7.5/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU= github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5eI= github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw= -github.com/jfrog/build-info-go v1.12.4 h1:eoHoJDOF7Rx2gAOAXEAjbEIpnH+4y5ha2quQT48Py3Q= -github.com/jfrog/build-info-go v1.12.4/go.mod h1:NEJwH1HxzhtWuiT8eR/anbjT0A3OyLBWpZZrDJs+hWQ= +github.com/jfrog/build-info-go v1.12.5-0.20251209031413-f5f0e93dc8db h1:5q4hUqZVl7Xt+R+ono5lDH1/lkvV1spnfDtp0VtJqlo= +github.com/jfrog/build-info-go v1.12.5-0.20251209031413-f5f0e93dc8db/go.mod h1:9W4U440fdTHwW1HiB/R0VQvz/5q8ZHsms9MWcq+JrdY= github.com/jfrog/froggit-go v1.20.6 h1:Xp7+LlEh0m1KGrQstb+u0aGfjRUtv1eh9xQBV3571jQ= github.com/jfrog/froggit-go v1.20.6/go.mod h1:obSG1SlsWjktkuqmKtpq7MNTTL63e0ot+ucTnlOMV88= github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s= github.com/jfrog/gofrog v1.7.6/go.mod h1:ntr1txqNOZtHplmaNd7rS4f8jpA5Apx8em70oYEe7+4= github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY= github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= -github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251118100843-ac34330a70d3 h1:sIjwBWBmyb7UEqP0IhQ22CWOedOPlNetyHzECS3sUyA= -github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251118100843-ac34330a70d3/go.mod h1:3hLZrM2xT+PkIevIGret4x1xDFTaVoNu3h374QnrKyc= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20251210074251-c15fabe27f7f h1:aoYtLX8ImiaYmStWeTXllidkMy1Hpet/TGOjicf1WhU= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20251210074251-c15fabe27f7f/go.mod h1:wKTWZqomaLxrHuvVF4iryZ8V4rn6h2y09jbuOBVRQUY= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0 h1:EsasTBE5i2MyCESS/icZxKIlObpGiOyW9K67MAaEWco= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251125083543-e689762c4ff0/go.mod h1:d9aADumiyjCBvZLffp8wldvP9XFHxcvk2PoOSUYms2g= -github.com/jfrog/jfrog-client-go v1.55.1-0.20251119183924-d765eb708cec h1:tNfeGi/2FuxIUSi8urFZuqa33grynAHwLRH6iIK/DB0= -github.com/jfrog/jfrog-client-go v1.55.1-0.20251119183924-d765eb708cec/go.mod h1:ureS+L3wNs0qYUBSwH8C9PjwnraTX9ibZu7JkaqjO/E= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= -github.com/kerenr-jfrog/jfrog-cli-security v0.0.0-20251209075212-257d63a4e1f2 h1:171RZZDmmBf+bKzc8JkpkfNnTfxwlfRttWUOjKdyEoM= -github.com/kerenr-jfrog/jfrog-cli-security v0.0.0-20251209075212-257d63a4e1f2/go.mod h1:qBAvU9kN41nReJk/O4V9Q/xwiXfAdyhqRIYaOjVm8nE= +github.com/kerenr-jfrog/jfrog-cli-security v0.0.0-20251210110046-5c022222a67c h1:cdu69MmULzpDwRtVGQwyjnChlo4f4OA3K/6mLQQWLMs= +github.com/kerenr-jfrog/jfrog-cli-security v0.0.0-20251210110046-5c022222a67c/go.mod h1:mKaAAEI1avRih1vFw9OZE5b5l0H1SkHuTb/hvqjsbbs= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -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/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= +github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= @@ -189,10 +197,11 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 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-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI= +github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= +github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= +github.com/mattn/go-tty v0.0.7 h1:KJ486B6qI8+wBO7kQxYgmmEFDaFEE96JMBQ7h400N8Q= +github.com/mattn/go-tty v0.0.7/go.mod h1:f2i5ZOvXBU/tCABmLmOfzLz9azMo5wdAaElRNnJKr+k= github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.0 h1:mmJCWLe63QvybxhW1iBmQWEaCKdc4SKgALfTNZ+OphU= github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.0/go.mod h1:mDunUZ1IUJdJIRHvFb+LPBUtxe3AYB5MI6BMXNg8194= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= @@ -226,7 +235,6 @@ github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiK github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= @@ -235,15 +243,13 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t 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/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= -github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= +github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4= +github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI= 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/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= -github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= -github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= @@ -303,6 +309,18 @@ github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZ github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -313,13 +331,13 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY= -golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70= +golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 h1:DHNhtq3sNNzrvduZZIiFyXWOL9IWaDPHqTnLJp+rCBY= +golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -337,8 +355,8 @@ golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo= -golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= +golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -404,17 +422,17 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 h1:TqExAhdPaB60Ux47Cn0oLV07rGnxZzIsaRhQaqS666A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA= -google.golang.org/grpc v1.67.3 h1:OgPcDAFKHnH8X3O4WcO4XUc8GRDeKsKReqbQtiCj7N8= -google.golang.org/grpc v1.67.3/go.mod h1:YGaHCc6Oap+FzBJTZLBzkGSYt/cvGPFTPxkn7QfSU8s= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA= +google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/scanpullrequest/scanpullrequest_test.go b/scanpullrequest/scanpullrequest_test.go index 7bd36f81d..28eba9108 100644 --- a/scanpullrequest/scanpullrequest_test.go +++ b/scanpullrequest/scanpullrequest_test.go @@ -567,11 +567,17 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { name: "Applicability scanner failed - should remove applicability results", scanType: jasutils.Applicability, targetResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{ + ContextualAnalysisStatusCode: securityutils.NewIntPtr(0), + }, JasResults: &results.JasScansResults{ ApplicabilityScanResults: []*sarif.Run{}, }, }, sourceResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{ + ContextualAnalysisStatusCode: securityutils.NewIntPtr(1), + }, JasResults: &results.JasScansResults{ ApplicabilityScanResults: []*sarif.Run{}, }, @@ -582,7 +588,9 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { name: "Secrets scanner failed in target - should remove secrets vulnerabilities and violations", scanType: jasutils.Secrets, targetResult: &results.TargetResults{ - ResultsStatus: results.ResultsStatus{SecretsScanStatusCode: &[]int{1}[0]}, + ResultsStatus: results.ResultsStatus{ + SecretsScanStatusCode: securityutils.NewIntPtr(1), + }, JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ SecretsScanResults: []*sarif.Run{}, @@ -593,7 +601,9 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { }, }, sourceResult: &results.TargetResults{ - ResultsStatus: results.ResultsStatus{SecretsScanStatusCode: &[]int{0}[0]}, + ResultsStatus: results.ResultsStatus{ + SecretsScanStatusCode: securityutils.NewIntPtr(0), + }, JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ SecretsScanResults: []*sarif.Run{}, @@ -609,7 +619,9 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { name: "IaC scanner failed in both source and target - should remove IaC vulnerabilities and violations", scanType: jasutils.IaC, targetResult: &results.TargetResults{ - ResultsStatus: results.ResultsStatus{IacScanStatusCode: &[]int{1}[0]}, + ResultsStatus: results.ResultsStatus{ + IacScanStatusCode: securityutils.NewIntPtr(1), + }, JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ IacScanResults: []*sarif.Run{}, @@ -620,7 +632,9 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { }, }, sourceResult: &results.TargetResults{ - ResultsStatus: results.ResultsStatus{IacScanStatusCode: &[]int{1}[0]}, + ResultsStatus: results.ResultsStatus{ + IacScanStatusCode: securityutils.NewIntPtr(1), + }, JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ IacScanResults: []*sarif.Run{}, @@ -636,6 +650,9 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { name: "SAST scanner failed - should remove SAST vulnerabilities and violations", scanType: jasutils.Sast, targetResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{ + SastScanStatusCode: securityutils.NewIntPtr(0), + }, JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ SastScanResults: []*sarif.Run{}, @@ -646,6 +663,9 @@ func TestFilterJasResultsIfScanFailed(t *testing.T) { }, }, sourceResult: &results.TargetResults{ + ResultsStatus: results.ResultsStatus{ + SastScanStatusCode: securityutils.NewIntPtr(1), + }, JasResults: &results.JasScansResults{ JasVulnerabilities: results.JasScanResults{ SastScanResults: []*sarif.Run{}, diff --git a/testdata/scanpullrequest/clean-test-proj/sourceBranch.gz b/testdata/scanpullrequest/clean-test-proj/sourceBranch.gz index 57c33cddfd00c7a767217d2d2e37f162cc5f0a9a..7d3ff98345a358d1db88bf1f455738d05aa9626d 100755 GIT binary patch literal 322 zcmV-I0loeoiwFP!000001MSt#PJ}QJ2XM|j1>r2%^3f(9eF*QQJ1PqnY{84!cbDQy z)~_WhyPJ*wUqafp z6|Zfh|F*|m{Zqz2)L#nM|7@98-0z>)|Je_MP!|srUIn45snAhJwu@TRtiubJd?I7Z zM!P(ZWz1fq?rPkYHQh|vbc`E%>`Oy-2y~{WF}A%JND4_Vxb)tv{OUf6j+onu}o~1atp?A(I6Ce+<9v{}r{QSEN-r^)egQZ>-qh#5-KRz*!WC3o*gpsOxJ zA>iBmVZMk)>+bdj=eT7*=itfCgb+q4_G@2BIWTh31_xsVp2I;ajYo73M*?`>^iX}mK=h;l@29saf0KrLA^V6 zC{cMe0{T$Z|C1tHGm-3MX1sAT^0&^|^5Hr;3?68$<0^E)x7T-xD1=ZGJyEhqxR6}t z2`dhCpAS~8H;%DnL5{5Z`Msh1neyB9Z%nx`Gun3_{HFe)148}tTyoU^7{0ClW*sf- zaxtE_wf)~2L-m(je5$`zxkwn_&nND7;q`w>8OyABr0j-e<&umYd20QrarHdAipghk zZB^Tt7h^regQZ>-qh#5-KRz*!WC3o*gpsOxJ zA>iBmVZMk)>+bdj=eT7*=itfCgb+q4_G@2BIWTh31_xsVp2I;ajY`sQenQ( z2`-ucEXyRqS`JeEuYq{_yRtf$rzmYY>O3>^9s8ntoY7wh>-PFHM1K|nz$TL58-3>^ z{KWPD)4OEy#+EH~^F#9H4gGI^A2wJa&o>-9Y{O(g2JA{hZ+J3HG~Cz1sN6$~rQso; z6kul+qGtX#_^_mquKQSG#y#W;OX|&nqgx!^$ffT&H1{_Gi5m zmZ>hb+ zvESr2@?s$3nNc&9b?Ezj+_qo6Byg1TAnmmB)y zfbRq+C=V(A1X-S}qBJ6s+RxOy%@+Cj47!euhkPBEq<4nTGnSX~gV_jrU@+oUrYlyZ zz%*Sv4)oQdRo+(gZR=^0uZflJ2&a}4)R|2>vtlPZVkYIyguy{|b!=6}q=g&SgJ^D__u!*mZ|MO(D@eSWB}%+rq(Qtu zk?ngcPV<9J_o4XY=v8-{cZ5d;R=2S44el1j8t+LNUvycm>q$c2Y~%`gd!;OWEIBCFJkV(~+(7)US;Dc`BQ$g002MP0TbJg`v9T8(DsX zHRD09`^~B6A-ExdXBG^r!ep?VRcm6Im5h!toeYBe#}X2eTpyG>>|`#p!$zkNkNShT z9{Mmm`0k|k$XUbsHv^7h*vCe94D8m@q%ym|zFbr;mZ%3a@zgW+@)`AFlt}t=8a-cQ zOeO}m3V9%=hFsTL4@FJstrRYsYstOBeN$NE3yPsZTWdYq%ErmLhT)ei)P5K)hW+uP zTYycu!}aemuZT-cD6{^elanf+S`~f?q3^=u{kzNd|Cew5Bb39+@ETuokF)WggU9-_kcBk8n2kzLnB8RBp&WQQ+h!Uq3d{bl-(fBpTR zU*StqoI&i`w`MQazS`1Y0yx6<$2%`6}nWXG3bzW2~5u7Ei6 zA6{qu#{tMdD6+f1{|j{ecMZhTpZwxJ-w7_t{}6Z*{{aVCs{b``f&QPJ1aeXS2QP-t ze?f%w`F{=2{12M{LGwRo{s+zfp!pv(|AXd#(EN`xn$Y|Yn*TxbKWP5PPbmN6c>n*^ z|NjH9fd4T6Lu7fn|Gx(QEAl_SHwhFJ6ciK`6ciK`6ciK`6ciK`6cqo5_z(4_sJ8%6 F003{7!_)u( literal 650 zcmV;50(Jc#iwFQO5WQpo1MQg4ZqqOv#{&{Vlrx;IoT=yk?vQ#YXi_H?0o#Ot3o@x& zQkpbN(ykTS6Yv7ux$^)#1FylIN5IJ{U|rLW5mHe7kz6wM(2*R2ESTL)9 z6%^=CH=sX56jLfmuD=vk|0*cd-~6zWCc*Eo{}Ksl^{;}}`bWxptNI!al2Lf|cbM@I zj1}u|j(z9#Czx{L090N#i`jDh-_-zcLltQEK5&;z2KQcOFwt@1kHX9bLj=)TYF9@( z?CQ|-bz-uzs!VF&hkl?^?@eY+jWx@yP0qMK^n0`VATxFeB#^r%rU^`^>6PEH*8dqjfBqw88DQ4`E8)i7o6dE|d89n>_z*k?bFwt&mI=g! zV-vFHkC&^mb#!zv|C^QgV8ZPMlWRZI?|7pCswf(2XlCC;hbr`RX7FwDzW@2_r!OUR z(o#gB|36XFwpLvo@BHyPu-5hRyyz{R{oQz?SMhd{_Fi8(F^-OV|M?qgh)>#?WN5ogAIsk(QI&H9x#*;Z@Oug3Ml;kU(VG( kXZ`(OEZqMQlh*$$;h(tw+uh${u~;hSJB@S;tNt<8 diff --git a/testdata/scanpullrequest/multi-dir-test-proj/targetBranch.gz b/testdata/scanpullrequest/multi-dir-test-proj/targetBranch.gz index b56ceaa4bdc926bc072f41541c9ef6a862a1be5f..c77f7fab30aef8acde676be3cb7ea151f79d87a9 100755 GIT binary patch literal 1277 zcmVMHuzYoaZmv32*(zf$-V>ve%gYu*2T=rs zMx$HV&%QtsH5pSvX5;M6o?n##yW7*v|D0|bPN?Ragr4}CqmQ`U*MK4vMTw7Ck zl^m8ZmU%_Mf|Ns8Kmy9;r7s%K8^VBUem~Nq2vYh#2#5I7L6Bws3%r;^Jd&{l{yzj+ z{O@V{L^BCvyZVG32dU)7 z4*wT^iyO>|A6Tvvx4|r8(Q|1W2M?A_)OD?pl>1~BT0RM)0_uk(DSL^XxGe56Dp{YU z7(mi!=OB_AgLuR-h@)Fu9V9iOXfhu&Z7%;?Kv^xsu87L@QveqVp;+9m#pJW#{uj5=GrL7tWTN55=+h1 z#+v0&V)_NCSjiG@wEl&)6S&b7}d4m$)fI#o2~L)?NaI^MF|Mey+=>;tP;Hsgj-y@(TZWQOP0pPbhYXX&=i%6*SdLpyy?}pbm9bw3r>2cjKEZF zEeuHh@;cwH_c!f`V@BhCr*W)Z{L9~u5i7EM3V~gZTGL3N4+KW6z$%#qel;2i{CdhH zmi7zWuRbE?#iQa|l8w+3a;-CE$MSLo812^<_ z!c3E&?Uom_qL5kNjonD$%@^j`+5&-B$oDj6w`L4jFh4(cBhZ3Vhpe6Ly;@Bwd+c&DbLE4p=Ah;(Y|wrOSj}% zR#2Ui%Z@rzd$+T0MQCbQVy{J|p%NPM86V89O8xW2$17H*TflokkK)hM(a+xM06X}^ z{y)psKVjeVAC|<;^MCUECt!?W|9=R6WdFZ&(f?q}4GX}(ll1eS|JwIIZ{|Oec?|D= z4nY?GzdYAZi9-XHKGL*(?DapE-}zs}NP_kM5P0O#BRV}k7URd8pFJAj(4?RL!eQ3` zIR6vB|CeF?KLlC)AN>(O69k#^KVsC5#}b13|3S#?|4$@=GUb0nA-?}BSb_WhA%OhP z_b>Y({{#6S$p1k8=Y4QP{s;0ukpF@F&#%O1_y7Ok|9_!m|Nl1sqsXxTKL`iR|NQJr n1poj50000000000000000000000000_$B!p_gEC808jt`*DRS) literal 377 zcmV-<0fzn`iwFRq*jHl!1MQdHZh|lr$Gzq$8m>pzPrEGfVHh3_P70%Caa(-%6*XI8 z6sD50W&K@nLeB~9>A$C?MYFbfGSBP8g0V?em#ZXOL#pp5gFy&UQlg!m?k!>r^xtG{WU=rD`mBK@6% zP(>vT`um_$e>S52Ea>lpPW|}^`tSCCMTH9b`=CdE_YgNPf{W{)5yDB(-v>X@ze=;` zbP0H6N_|ZqZa$_$oY$X9exyI+R89~XI@weFbNxRegkqf*5I>^$#A1l=+JIN6O(RfX|NIw6_3z$PsDB@L XJpZGya}5LnfxtJP?r~^g02%-Q9HO^+ diff --git a/testdata/scanpullrequest/test-proj/targetBranch.gz b/testdata/scanpullrequest/test-proj/targetBranch.gz index f9ee6af5309fe33687814382f34471e624344f27..3ff8328c5d70e3b8ed17f2b04b18ab21a62e9269 100755 GIT binary patch literal 14276 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 literal 13621 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 H06+l%(E@m= diff --git a/testdata/scanrepository/cmd/aggregate-multi-dir/npm1/package-lock.json b/testdata/scanrepository/cmd/aggregate-multi-dir/npm1/package-lock.json new file mode 100644 index 000000000..2a35cf0bd --- /dev/null +++ b/testdata/scanrepository/cmd/aggregate-multi-dir/npm1/package-lock.json @@ -0,0 +1,74 @@ +{ + "name": "aggregate", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "aggregate", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "minimatch": "3.0.2", + "mpath": "0.7.0", + "uuid": "^9.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", + "integrity": "sha512-itcYJNfVYt/6nrpMDiFA6FY9msZ9G7jEfB896PrgYCakHrW0mOPmzBVvfI2b9yoy6kUKNde1Rvw4ah0f1E25tA==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mpath": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz", + "integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + } + } +} diff --git a/testdata/scanrepository/cmd/aggregate-multi-dir/npm2/package-lock.json b/testdata/scanrepository/cmd/aggregate-multi-dir/npm2/package-lock.json new file mode 100644 index 000000000..246e00379 --- /dev/null +++ b/testdata/scanrepository/cmd/aggregate-multi-dir/npm2/package-lock.json @@ -0,0 +1,18 @@ +{ + "name": "npm2", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "minimist": "1.2.5" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "license": "MIT" + } + } +} diff --git a/testdata/scanrepository/cmd/aggregate-multi-project/npm/package-lock.json b/testdata/scanrepository/cmd/aggregate-multi-project/npm/package-lock.json new file mode 100644 index 000000000..2a35cf0bd --- /dev/null +++ b/testdata/scanrepository/cmd/aggregate-multi-project/npm/package-lock.json @@ -0,0 +1,74 @@ +{ + "name": "aggregate", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "aggregate", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "minimatch": "3.0.2", + "mpath": "0.7.0", + "uuid": "^9.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.2.tgz", + "integrity": "sha512-itcYJNfVYt/6nrpMDiFA6FY9msZ9G7jEfB896PrgYCakHrW0mOPmzBVvfI2b9yoy6kUKNde1Rvw4ah0f1E25tA==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mpath": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz", + "integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + } + } +} diff --git a/utils/utils_test.go b/utils/utils_test.go index 8c628047b..c179e1a3d 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -1,6 +1,13 @@ package utils import ( + "net/http/httptest" + "os" + "path" + "path/filepath" + "testing" + "time" + "github.com/CycloneDX/cyclonedx-go" "github.com/jfrog/frogbot/v2/utils/outputwriter" "github.com/jfrog/froggit-go/vcsclient" @@ -11,12 +18,6 @@ import ( "github.com/jfrog/jfrog-cli-security/utils/results" "github.com/jfrog/jfrog-cli-security/utils/techutils" "github.com/stretchr/testify/assert" - "net/http/httptest" - "os" - "path" - "path/filepath" - "testing" - "time" ) const ( @@ -523,7 +524,8 @@ func createTestSecurityCommandResults() *results.SecurityCommandResults { // Create SecurityCommandResults with the BOM scanResults := &results.SecurityCommandResults{ - StartTime: time.Date(2024, 1, 15, 10, 30, 0, 0, time.UTC), + ResultsMetaData: results.ResultsMetaData{ + StartTime: time.Date(2024, 1, 15, 10, 30, 0, 0, time.UTC)}, Targets: []*results.TargetResults{ { ScanTarget: results.ScanTarget{