Skip to content

Commit

Permalink
check for multiple roots
Browse files Browse the repository at this point in the history
Signed-off-by: nikpivkin <nikita.pivkin@smartforce.io>
  • Loading branch information
nikpivkin committed Dec 17, 2024
1 parent e67015d commit fed629a
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 12 deletions.
26 changes: 15 additions & 11 deletions pkg/dependency/parser/python/uv/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ func (l Lock) directDeps(root Package) map[string]struct{} {
return deps
}

func (l Lock) prodDeps(root Package) map[string]struct{} {
packages := l.packages()
func prodDeps(root Package, packages map[string]Package) map[string]struct{} {
visited := make(map[string]struct{})
walkPackageDeps(root, packages, visited)
return visited
Expand All @@ -51,14 +50,21 @@ func walkPackageDeps(pkg Package, packages map[string]Package, visited map[strin
}
}

func (l Lock) root() Package {
func (l Lock) root() (Package, error) {
var pkgs []Package
for _, pkg := range l.Packages {
if pkg.isRoot() {
return pkg
pkgs = append(pkgs, pkg)
}
}

return Package{}
// lock file must include root package
// cf. https://github.com/astral-sh/uv/blob/f80ddf10b63c3e7b421ca4658e63f97db1e0378c/crates/uv/src/commands/project/lock.rs#L933-L936
if len(pkgs) != 1 {
return Package{}, xerrors.New("uv lockfile must contain 1 root package")
}

return pkgs[0], nil
}

type Package struct {
Expand Down Expand Up @@ -94,16 +100,14 @@ func (p *Parser) Parse(r xio.ReadSeekerAt) ([]ftypes.Package, []ftypes.Dependenc
return nil, nil, xerrors.Errorf("failed to decode uv lock file: %w", err)
}

rootPackage := lock.root()
// lock file must include root package
// cf. https://github.com/astral-sh/uv/blob/f80ddf10b63c3e7b421ca4658e63f97db1e0378c/crates/uv/src/commands/project/lock.rs#L933-L936
if rootPackage.Name == "" {
return nil, nil, xerrors.New("uv lockfile does not contain a root package.")
rootPackage, err := lock.root()
if err != nil {
return nil, nil, err
}

packages := lock.packages()
directDeps := lock.directDeps(rootPackage)
prodDeps := lock.prodDeps(rootPackage)
prodDeps := prodDeps(rootPackage, packages)

var (
pkgs ftypes.Packages
Expand Down
7 changes: 6 additions & 1 deletion pkg/dependency/parser/python/uv/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ func TestParser_Parse(t *testing.T) {
{
name: "lockfile without root",
file: "testdata/uv_without_root.lock",
wantErr: "uv lockfile does not contain a root package",
wantErr: "uv lockfile must contain 1 root package",
},
{
name: "multiple roots",
file: "testdata/uv_multiple_roots.lock",
wantErr: "uv lockfile must contain 1 root package",
},
}

Expand Down
30 changes: 30 additions & 0 deletions pkg/dependency/parser/python/uv/testdata/uv_multiple_roots.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
version = 1
requires-python = ">=3.11"

[[package]]
name = "asyncio"
version = "3.4.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/da/54/054bafaf2c0fb8473d423743e191fcdf49b2c1fd5e9af3524efbe097bafd/asyncio-3.4.3.tar.gz", hash = "sha256:83360ff8bc97980e4ff25c964c7bd3923d333d177aa4f7fb736b019f26c7cb41", size = 204411 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/22/74/07679c5b9f98a7cb0fc147b1ef1cc1853bc07a4eb9cb5731e24732c5f773/asyncio-3.4.3-py3-none-any.whl", hash = "sha256:c4d18b22701821de07bd6aea8b53d21449ec0ec5680645e5317062ea21817d2d", size = 101767 },
]

[[package]]
name = "foo"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "asyncio" },
]

[package.metadata]
requires-dist = [{ name = "asyncio", specifier = "==3.4.3" }]

[[package]]
name = "bar"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "asyncio" },
]

0 comments on commit fed629a

Please sign in to comment.