-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: nikpivkin <[email protected]>
- Loading branch information
Showing
4 changed files
with
1,856 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package uv | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" | ||
) | ||
|
||
func TestParser_Parse(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
file string | ||
wantPkgs []ftypes.Package | ||
wantDeps []ftypes.Dependency | ||
}{ | ||
{ | ||
name: "normal", | ||
file: "testdata/uv_normal.lock", | ||
wantPkgs: uvNormal, | ||
wantDeps: uvNormalDeps, | ||
}, | ||
{ | ||
name: "many", | ||
file: "testdata/uv_large.lock", | ||
wantPkgs: uvLarge, | ||
wantDeps: uvLargeDeps, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
f, err := os.Open(tt.file) | ||
require.NoError(t, err) | ||
defer f.Close() | ||
|
||
p := New() | ||
gotPkgs, gotDeps, err := p.Parse(f) | ||
require.NoError(t, err) | ||
assert.Equal(t, tt.wantPkgs, gotPkgs) | ||
assert.Equal(t, tt.wantDeps, gotDeps) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package uv | ||
|
||
import ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" | ||
|
||
var ( | ||
// docker run --name uv --rm -it python@sha256:e1141f10176d74d1a0e87a7c0a0a5a98dd98ec5ac12ce867768f40c6feae2fd9 sh | ||
// wget -qO- https://github.com/astral-sh/uv/releases/download/0.5.8/uv-installer.sh | sh | ||
// source $HOME/.local/bin/env | ||
// uv init normal && cd normal | ||
// uv add requests==2.32.0 | ||
// apk add jq | ||
// uv pip list --format json |jq -c 'sort_by(.name) | .[] | {"ID": (.name + "@" + .version), "Name": .name, "Version": .version}' | sed 's/$/,/' | sed 's/\"\([^"]*\)\":/\1:/g' | ||
|
||
// add a root project | ||
// fill in the relationships between the packages | ||
uvNormal = []ftypes.Package{ | ||
{ID: "[email protected]", Name: "certifi", Version: "2024.8.30", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "charset-normalizer", Version: "3.4.0", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "idna", Version: "3.10", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "normal", Version: "0.1.0", Relationship: ftypes.RelationshipRoot}, | ||
{ID: "[email protected]", Name: "requests", Version: "2.32.0", Relationship: ftypes.RelationshipDirect}, | ||
{ID: "[email protected]", Name: "urllib3", Version: "2.2.3", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
} | ||
|
||
// add a root project | ||
uvNormalDeps = []ftypes.Dependency{ | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]", "[email protected]", "[email protected]"}}, | ||
} | ||
|
||
// docker run --name uv --rm -it python@sha256:e1141f10176d74d1a0e87a7c0a0a5a98dd98ec5ac12ce867768f40c6feae2fd9 sh | ||
// wget -qO- https://github.com/astral-sh/uv/releases/download/0.5.8/uv-installer.sh | sh | ||
// source $HOME/.local/bin/env | ||
// uv init large && cd large | ||
// uv add asyncio==3.4.3 aiohttp==3.11.10 boto3==1.35.79 fastapi==0.115.6 simplejson==3.19.3 SQLAlchemy==2.0.36 pydantic==2.10.3 uvicorn==0.32.1 | ||
// uv add --group dev pytest==8.3.4 ruff==0.8.2 coverage==7.6.9 codespell==2.3.0 | ||
// uv add --group docs mkdocs==1.6.1 pymdown-extensions==10.12 | ||
// apk add jq | ||
// uv pip list --format json |jq -c 'sort_by(.name) | .[] | {"ID": (.name + "@" + .version), "Name": .name, "Version": .version}' | sed 's/$/,/' | sed 's/\"\([^"]*\)\":/\1:/g' | ||
|
||
// add a root project | ||
// fill in the relationships between the packages | ||
uvLarge = []ftypes.Package{ | ||
{ID: "[email protected]", Name: "aiohappyeyeballs", Version: "2.4.4", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "aiohttp", Version: "3.11.10", Relationship: ftypes.RelationshipDirect}, | ||
{ID: "[email protected]", Name: "aiosignal", Version: "1.3.1", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "annotated-types", Version: "0.7.0", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "anyio", Version: "4.7.0", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "async-timeout", Version: "5.0.1", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "asyncio", Version: "3.4.3", Relationship: ftypes.RelationshipDirect}, | ||
{ID: "[email protected]", Name: "attrs", Version: "24.2.0", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "boto3", Version: "1.35.79", Relationship: ftypes.RelationshipDirect}, | ||
{ID: "[email protected]", Name: "botocore", Version: "1.35.79", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "click", Version: "8.1.7", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "colorama", Version: "0.4.6", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "exceptiongroup", Version: "1.2.2", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "fastapi", Version: "0.115.6", Relationship: ftypes.RelationshipDirect}, | ||
{ID: "[email protected]", Name: "frozenlist", Version: "1.5.0", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "greenlet", Version: "3.1.1", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "h11", Version: "0.14.0", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "idna", Version: "3.10", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "jmespath", Version: "1.0.1", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "large", Version: "0.1.0", Relationship: ftypes.RelationshipRoot}, | ||
{ID: "[email protected]", Name: "multidict", Version: "6.1.0", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "propcache", Version: "0.2.1", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "pydantic", Version: "2.10.3", Relationship: ftypes.RelationshipDirect}, | ||
{ID: "[email protected]", Name: "pydantic-core", Version: "2.27.1", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "python-dateutil", Version: "2.9.0.post0", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "s3transfer", Version: "0.10.4", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "simplejson", Version: "3.19.3", Relationship: ftypes.RelationshipDirect}, | ||
{ID: "[email protected]", Name: "six", Version: "1.17.0", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "sniffio", Version: "1.3.1", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "sqlalchemy", Version: "2.0.36", Relationship: ftypes.RelationshipDirect}, | ||
{ID: "[email protected]", Name: "starlette", Version: "0.41.3", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "typing-extensions", Version: "4.12.2", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "urllib3", Version: "1.26.20", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
{ID: "[email protected]", Name: "uvicorn", Version: "0.32.1", Relationship: ftypes.RelationshipDirect}, | ||
{ID: "[email protected]", Name: "yarl", Version: "1.18.3", Relationship: ftypes.RelationshipIndirect, Indirect: true}, | ||
} | ||
|
||
/* | ||
uv pip list --format json | jq -r '.[] | .name' | xargs uv pip show | awk -F ': ' ' | ||
/^Name/ {name=$2} | ||
/^Version/ {version=$2} | ||
/^Requires/ {requires=$2} | ||
{ | ||
if (requires == "") { next } | ||
gsub(/, /, "\", \"", requires) | ||
requires="[]string{\"" requires "\"}" | ||
print "{ID: \"" name "@" version "\", DependsOn: " requires "}," | ||
name=""; version=""; requires="" | ||
}' | ||
*/ | ||
|
||
// add a root project | ||
// remove all groups | ||
uvLargeDeps = []ftypes.Dependency{ | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]", "[email protected]", "[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]", "[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]", "[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]", "[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]", "[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]", "[email protected]"}}, | ||
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]", "[email protected]"}}, | ||
} | ||
) |
Oops, something went wrong.