diff options
| author | 2023-04-28 01:36:44 +0800 | |
|---|---|---|
| committer | 2023-04-28 01:36:44 +0800 | |
| commit | dd84b9d64fb98746a230cd24233ff50a562c39c9 (patch) | |
| tree | b583261ef00b3afe72ec4d6dacb31e57779a6faf /cli/internal/lockfile/npm_lockfile.go | |
| parent | 0b46fcd72ac34382387b2bcf9095233efbcc52f4 (diff) | |
| download | HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.tar.gz HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.zip | |
Diffstat (limited to 'cli/internal/lockfile/npm_lockfile.go')
| -rw-r--r-- | cli/internal/lockfile/npm_lockfile.go | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/cli/internal/lockfile/npm_lockfile.go b/cli/internal/lockfile/npm_lockfile.go new file mode 100644 index 0000000..67cd32a --- /dev/null +++ b/cli/internal/lockfile/npm_lockfile.go @@ -0,0 +1,107 @@ +package lockfile + +import ( + "encoding/json" + "io" + + mapset "github.com/deckarep/golang-set" + "github.com/vercel/turbo/cli/internal/ffi" + "github.com/vercel/turbo/cli/internal/turbopath" +) + +// NpmLockfile representation of package-lock.json +type NpmLockfile struct { + // We just story the entire lockfile in memory and pass it for every call + contents []byte +} + +// ResolvePackage Given a workspace, a package it imports and version returns the key, resolved version, and if it was found +func (l *NpmLockfile) ResolvePackage(workspacePath turbopath.AnchoredUnixPath, name string, version string) (Package, error) { + // This is only used when doing calculating the transitive deps, but Rust + // implementations do this calculation on the Rust side. + panic("Unreachable") +} + +// AllDependencies Given a lockfile key return all (dev/optional/peer) dependencies of that package +func (l *NpmLockfile) AllDependencies(key string) (map[string]string, bool) { + // This is only used when doing calculating the transitive deps, but Rust + // implementations do this calculation on the Rust side. + panic("Unreachable") +} + +// Subgraph Given a list of lockfile keys returns a Lockfile based off the original one that only contains the packages given +func (l *NpmLockfile) Subgraph(workspacePackages []turbopath.AnchoredSystemPath, packages []string) (Lockfile, error) { + workspaces := make([]string, len(workspacePackages)) + for i, workspace := range workspacePackages { + workspaces[i] = workspace.ToUnixPath().ToString() + } + contents, err := ffi.NpmSubgraph(l.contents, workspaces, packages) + if err != nil { + return nil, err + } + return &NpmLockfile{contents: contents}, nil +} + +// Encode the lockfile representation and write it to the given writer +func (l *NpmLockfile) Encode(w io.Writer) error { + _, err := w.Write(l.contents) + return err +} + +// Patches return a list of patches used in the lockfile +func (l *NpmLockfile) Patches() []turbopath.AnchoredUnixPath { + return nil +} + +// GlobalChange checks if there are any differences between lockfiles that would completely invalidate +// the cache. +func (l *NpmLockfile) GlobalChange(other Lockfile) bool { + o, ok := other.(*NpmLockfile) + if !ok { + return true + } + + // We just grab the few global fields and check if they've changed + type minimalJSON struct { + LockfileVersion string `json:"version"` + Requires bool `json:"requires"` + } + var self minimalJSON + var otherJSON minimalJSON + if err := json.Unmarshal(o.contents, &otherJSON); err != nil { + return true + } + if err := json.Unmarshal(l.contents, &self); err != nil { + return true + } + + return self.LockfileVersion != otherJSON.LockfileVersion || + self.Requires != otherJSON.Requires +} + +var _ (Lockfile) = (*NpmLockfile)(nil) + +// DecodeNpmLockfile Parse contents of package-lock.json into NpmLockfile +func DecodeNpmLockfile(contents []byte) (Lockfile, error) { + return &NpmLockfile{contents: contents}, nil +} + +func npmTransitiveDeps(lockfile *NpmLockfile, workspacePath turbopath.AnchoredUnixPath, unresolvedDeps map[string]string) (mapset.Set, error) { + pkgDir := workspacePath.ToString() + + packages, err := ffi.NpmTransitiveDeps(lockfile.contents, pkgDir, unresolvedDeps) + if err != nil { + return nil, err + } + + deps := make([]interface{}, len(packages)) + for i, pkg := range packages { + deps[i] = Package{ + Found: pkg.Found, + Key: pkg.Key, + Version: pkg.Version, + } + } + + return mapset.NewSetFromSlice(deps), nil +} |
