@@ -23,14 +23,6 @@ func (l Lock) packages() map[string]Package {
23
23
})
24
24
}
25
25
26
- func (l Lock ) directDeps (root Package ) set.Set [string ] {
27
- deps := set .New [string ]()
28
- for _ , dep := range root .Dependencies {
29
- deps .Append (dep .Name )
30
- }
31
- return deps
32
- }
33
-
34
26
func prodDeps (root Package , packages map [string ]Package ) set.Set [string ] {
35
27
visited := set .New [string ]()
36
28
walkPackageDeps (root , packages , visited )
@@ -42,8 +34,8 @@ func walkPackageDeps(pkg Package, packages map[string]Package, visited set.Set[s
42
34
return
43
35
}
44
36
visited .Append (pkg .Name )
45
- for _ , dep := range pkg .Dependencies {
46
- depPkg , exists := packages [dep . Name ]
37
+ for depName := range pkg .nonDevDeps (). Iter () {
38
+ depPkg , exists := packages [depName ]
47
39
if ! exists {
48
40
continue
49
41
}
@@ -69,10 +61,41 @@ func (l Lock) root() (Package, error) {
69
61
}
70
62
71
63
type Package struct {
72
- Name string `toml:"name"`
73
- Version string `toml:"version"`
74
- Source Source `toml:"source"`
75
- Dependencies []Dependency `toml:"dependencies"`
64
+ Name string `toml:"name"`
65
+ Version string `toml:"version"`
66
+ Source Source `toml:"source"`
67
+ Dependencies Dependencies `toml:"dependencies"`
68
+ DevDependencies map [string ]Dependencies `toml:"dev-dependencies"`
69
+ OptionalDependencies map [string ]Dependencies `toml:"optional-dependencies"`
70
+ }
71
+
72
+ func (p Package ) directDeps () set.Set [string ] {
73
+ deps := p .nonDevDeps ()
74
+ for _ , groupDeps := range p .DevDependencies {
75
+ deps .Append (groupDeps .toSet ().Items ()... )
76
+
77
+ }
78
+ return deps
79
+ }
80
+
81
+ func (p Package ) nonDevDeps () set.Set [string ] {
82
+ deps := p .Dependencies .toSet ()
83
+ for _ , groupDeps := range p .OptionalDependencies {
84
+ deps .Append (groupDeps .toSet ().Items ()... )
85
+ }
86
+ return deps
87
+ }
88
+
89
+ type Dependencies []struct {
90
+ Name string `toml:"name"`
91
+ }
92
+
93
+ func (d Dependencies ) toSet () set.Set [string ] {
94
+ deps := set .New [string ]()
95
+ for _ , dep := range d {
96
+ deps .Append (dep .Name )
97
+ }
98
+ return deps
76
99
}
77
100
78
101
// https://github.com/astral-sh/uv/blob/f7d647e81d7e1e3be189324b06024ed2057168e6/crates/uv-resolver/src/lock/mod.rs#L572-L579
@@ -107,7 +130,7 @@ func (p *Parser) Parse(r xio.ReadSeekerAt) ([]ftypes.Package, []ftypes.Dependenc
107
130
}
108
131
109
132
packages := lock .packages ()
110
- directDeps := lock .directDeps (rootPackage )
133
+ directDeps := rootPackage .directDeps ()
111
134
112
135
// Since each lockfile contains a root package with a list of direct dependencies,
113
136
// we can identify all production dependencies by traversing the dependency graph
@@ -120,10 +143,6 @@ func (p *Parser) Parse(r xio.ReadSeekerAt) ([]ftypes.Package, []ftypes.Dependenc
120
143
)
121
144
122
145
for _ , pkg := range lock .Packages {
123
- if ! prodDeps .Contains (pkg .Name ) {
124
- continue
125
- }
126
-
127
146
pkgID := packageID (pkg .Name , pkg .Version )
128
147
relationship := ftypes .RelationshipIndirect
129
148
if pkg .isRoot () {
@@ -137,16 +156,17 @@ func (p *Parser) Parse(r xio.ReadSeekerAt) ([]ftypes.Package, []ftypes.Dependenc
137
156
Name : pkg .Name ,
138
157
Version : pkg .Version ,
139
158
Relationship : relationship ,
159
+ Dev : ! prodDeps .Contains (pkg .Name ),
140
160
})
141
161
142
162
dependsOn := make ([]string , 0 , len (pkg .Dependencies ))
143
163
144
- for _ , dep := range pkg .Dependencies {
145
- depPkg , exists := packages [dep . Name ]
164
+ for depName := range pkg .directDeps (). Iter () {
165
+ depPkg , exists := packages [depName ]
146
166
if ! exists {
147
167
continue
148
168
}
149
- dependsOn = append (dependsOn , packageID (dep . Name , depPkg .Version ))
169
+ dependsOn = append (dependsOn , packageID (depName , depPkg .Version ))
150
170
}
151
171
152
172
if len (dependsOn ) > 0 {
0 commit comments