-
Notifications
You must be signed in to change notification settings - Fork 338
/
parse-nuget-lock.go
81 lines (61 loc) · 2.3 KB
/
parse-nuget-lock.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package lockfile
import (
"encoding/json"
"fmt"
"path/filepath"
)
type NuGetLockPackage struct {
Resolved string `json:"resolved"`
}
// NuGetLockfile contains the required dependency information as defined in
// https://github.com/NuGet/NuGet.Client/blob/6.5.0.136/src/NuGet.Core/NuGet.ProjectModel/ProjectLockFile/PackagesLockFileFormat.cs
type NuGetLockfile struct {
Version int `json:"version"`
Dependencies map[string]map[string]NuGetLockPackage `json:"dependencies"`
}
const NuGetEcosystem Ecosystem = "NuGet"
func parseNuGetLockDependencies(dependencies map[string]NuGetLockPackage) map[string]PackageDetails {
details := map[string]PackageDetails{}
for name, dependency := range dependencies {
details[name+"@"+dependency.Resolved] = PackageDetails{
Name: name,
Version: dependency.Resolved,
Ecosystem: NuGetEcosystem,
CompareAs: NuGetEcosystem,
}
}
return details
}
func parseNuGetLock(lockfile NuGetLockfile) ([]PackageDetails, error) {
details := map[string]PackageDetails{}
// go through the dependencies for each framework, e.g. `net6.0` and parse
// its dependencies, there might be different or duplicate dependencies
// between frameworks
for _, dependencies := range lockfile.Dependencies {
details = mergePkgDetailsMap(details, parseNuGetLockDependencies(dependencies))
}
return pkgDetailsMapToSlice(details), nil
}
type NuGetLockExtractor struct{}
func (e NuGetLockExtractor) ShouldExtract(path string) bool {
return filepath.Base(path) == "packages.lock.json"
}
func (e NuGetLockExtractor) Extract(f DepFile) ([]PackageDetails, error) {
var parsedLockfile *NuGetLockfile
err := json.NewDecoder(f).Decode(&parsedLockfile)
if err != nil {
return []PackageDetails{}, fmt.Errorf("could not extract from %s: %w", f.Path(), err)
}
if parsedLockfile.Version != 1 && parsedLockfile.Version != 2 {
return []PackageDetails{}, fmt.Errorf("could not extract: unsupported lock file version %d", parsedLockfile.Version)
}
return parseNuGetLock(*parsedLockfile)
}
var _ Extractor = NuGetLockExtractor{}
//nolint:gochecknoinits
func init() {
registerExtractor("packages.lock.json", NuGetLockExtractor{})
}
func ParseNuGetLock(pathToLockfile string) ([]PackageDetails, error) {
return extractFromFile(pathToLockfile, NuGetLockExtractor{})
}