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/yarn_lockfile.go | |
| parent | 0b46fcd72ac34382387b2bcf9095233efbcc52f4 (diff) | |
| download | HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.tar.gz HydroRoll-dd84b9d64fb98746a230cd24233ff50a562c39c9.zip | |
Diffstat (limited to 'cli/internal/lockfile/yarn_lockfile.go')
| -rw-r--r-- | cli/internal/lockfile/yarn_lockfile.go | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/cli/internal/lockfile/yarn_lockfile.go b/cli/internal/lockfile/yarn_lockfile.go new file mode 100644 index 0000000..99d7764 --- /dev/null +++ b/cli/internal/lockfile/yarn_lockfile.go @@ -0,0 +1,124 @@ +package lockfile + +import ( + "bytes" + "fmt" + "io" + + "github.com/andybalholm/crlf" + "github.com/iseki0/go-yarnlock" + "github.com/pkg/errors" + "github.com/vercel/turbo/cli/internal/turbopath" +) + +var _crlfLiteral = []byte("\r\n") + +// YarnLockfile representation of yarn lockfile +type YarnLockfile struct { + inner yarnlock.LockFile + hasCRLF bool +} + +var _ Lockfile = (*YarnLockfile)(nil) + +// ResolvePackage Given a package and version returns the key, resolved version, and if it was found +func (l *YarnLockfile) ResolvePackage(_workspacePath turbopath.AnchoredUnixPath, name string, version string) (Package, error) { + for _, key := range yarnPossibleKeys(name, version) { + if entry, ok := (l.inner)[key]; ok { + return Package{ + Found: true, + Key: key, + Version: entry.Version, + }, nil + } + } + + return Package{}, nil +} + +// AllDependencies Given a lockfile key return all (dev/optional/peer) dependencies of that package +func (l *YarnLockfile) AllDependencies(key string) (map[string]string, bool) { + deps := map[string]string{} + entry, ok := (l.inner)[key] + if !ok { + return deps, false + } + + for name, version := range entry.Dependencies { + deps[name] = version + } + for name, version := range entry.OptionalDependencies { + deps[name] = version + } + + return deps, true +} + +// Subgraph Given a list of lockfile keys returns a Lockfile based off the original one that only contains the packages given +func (l *YarnLockfile) Subgraph(_ []turbopath.AnchoredSystemPath, packages []string) (Lockfile, error) { + lockfile := make(map[string]yarnlock.LockFileEntry, len(packages)) + for _, key := range packages { + entry, ok := (l.inner)[key] + if ok { + lockfile[key] = entry + } + } + + return &YarnLockfile{lockfile, l.hasCRLF}, nil +} + +// Encode encode the lockfile representation and write it to the given writer +func (l *YarnLockfile) Encode(w io.Writer) error { + writer := w + if l.hasCRLF { + writer = crlf.NewWriter(w) + } + if err := l.inner.Encode(writer); err != nil { + return errors.Wrap(err, "Unable to encode yarn.lock") + } + return nil +} + +// Patches return a list of patches used in the lockfile +func (l *YarnLockfile) Patches() []turbopath.AnchoredUnixPath { + return nil +} + +// DecodeYarnLockfile Takes the contents of a yarn lockfile and returns a struct representation +func DecodeYarnLockfile(contents []byte) (*YarnLockfile, error) { + lockfile, err := yarnlock.ParseLockFileData(contents) + hasCRLF := bytes.HasSuffix(contents, _crlfLiteral) + newline := []byte("\n") + + // there's no trailing newline for this file, need to inspect more to see newline style + if !hasCRLF && !bytes.HasSuffix(contents, newline) { + firstNewline := bytes.IndexByte(contents, newline[0]) + if firstNewline != -1 && firstNewline != 0 { + byteBeforeNewline := contents[firstNewline-1] + hasCRLF = byteBeforeNewline == '\r' + } + } + + if err != nil { + return nil, errors.Wrap(err, "Unable to decode yarn.lock") + } + + return &YarnLockfile{lockfile, hasCRLF}, nil +} + +// GlobalChange checks if there are any differences between lockfiles that would completely invalidate +// the cache. +func (l *YarnLockfile) GlobalChange(other Lockfile) bool { + _, ok := other.(*YarnLockfile) + return !ok +} + +func yarnPossibleKeys(name string, version string) []string { + return []string{ + fmt.Sprintf("%v@%v", name, version), + fmt.Sprintf("%v@npm:%v", name, version), + fmt.Sprintf("%v@file:%v", name, version), + fmt.Sprintf("%v@workspace:%v", name, version), + fmt.Sprintf("%v@yarn:%v", name, version), + } +} |
