Merge pull request #151 from mhuxtable/mhuxtable/fix_nested_local_dependency_resolution

Correct path resolution to nested local dependencies
This commit is contained in:
Frederic Branczyk 2022-02-12 09:01:57 +01:00 committed by GitHub
commit 3aec759b6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 10 deletions

View file

@ -38,7 +38,7 @@ func NewLocalPackage(source *deps.Local) Interface {
func (p *LocalPackage) Install(ctx context.Context, name, dir, version string) (lockVersion string, err error) { func (p *LocalPackage) Install(ctx context.Context, name, dir, version string) (lockVersion string, err error) {
wd, err := os.Getwd() wd, err := os.Getwd()
if err != nil { if err != nil {
return "", errors.Wrap(err, "failed to get current working directory: %w") return "", errors.Wrap(err, "failed to get current working directory")
} }
oldname := filepath.Join(wd, p.Source.Directory) oldname := filepath.Join(wd, p.Source.Directory)
@ -51,17 +51,17 @@ func (p *LocalPackage) Install(ctx context.Context, name, dir, version string) (
err = os.RemoveAll(newname) err = os.RemoveAll(newname)
if err != nil { if err != nil {
return "", errors.Wrap(err, "failed to clean previous destination path: %w") return "", errors.Wrap(err, "failed to clean previous destination path")
} }
_, err = os.Stat(oldname) _, err = os.Stat(oldname)
if os.IsNotExist(err) { if os.IsNotExist(err) {
return "", errors.Wrap(err, "symlink destination path does not exist: %w") return "", errors.Wrap(err, "symlink destination path does not exist")
} }
err = os.Symlink(linkname, newname) err = os.Symlink(linkname, newname)
if err != nil { if err != nil {
return "", errors.Wrap(err, "failed to create symlink for local dependency: %w") return "", errors.Wrap(err, "failed to create symlink for local dependency")
} }
color.Magenta("LOCAL %s -> %s", name, oldname) color.Magenta("LOCAL %s -> %s", name, oldname)

View file

@ -52,7 +52,7 @@ var (
func Ensure(direct v1.JsonnetFile, vendorDir string, oldLocks map[string]deps.Dependency) (map[string]deps.Dependency, error) { func Ensure(direct v1.JsonnetFile, vendorDir string, oldLocks map[string]deps.Dependency) (map[string]deps.Dependency, error) {
// ensure all required files are in vendor // ensure all required files are in vendor
// This is the actual installation // This is the actual installation
locks, err := ensure(direct.Dependencies, vendorDir, oldLocks) locks, err := ensure(direct.Dependencies, vendorDir, "", oldLocks)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -210,7 +210,7 @@ func known(deps map[string]deps.Dependency, p string) bool {
return false return false
} }
func ensure(direct map[string]deps.Dependency, vendorDir string, locks map[string]deps.Dependency) (map[string]deps.Dependency, error) { func ensure(direct map[string]deps.Dependency, vendorDir, pathToParentModule string, locks map[string]deps.Dependency) (map[string]deps.Dependency, error) {
deps := make(map[string]deps.Dependency) deps := make(map[string]deps.Dependency)
for _, d := range direct { for _, d := range direct {
@ -231,7 +231,7 @@ func ensure(direct map[string]deps.Dependency, vendorDir string, locks map[strin
dir := filepath.Join(vendorDir, d.Name()) dir := filepath.Join(vendorDir, d.Name())
os.RemoveAll(dir) os.RemoveAll(dir)
locked, err := download(d, vendorDir) locked, err := download(d, vendorDir, pathToParentModule)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "downloading") return nil, errors.Wrap(err, "downloading")
} }
@ -257,7 +257,12 @@ func ensure(direct map[string]deps.Dependency, vendorDir string, locks map[strin
return nil, err return nil, err
} }
nested, err := ensure(f.Dependencies, vendorDir, locks) absolutePath, err := filepath.EvalSymlinks(filepath.Join(vendorDir, d.Name()))
if err != nil {
return nil, err
}
nested, err := ensure(f.Dependencies, vendorDir, absolutePath, locks)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -274,13 +279,27 @@ func ensure(direct map[string]deps.Dependency, vendorDir string, locks map[strin
// download retrieves a package from a remote upstream. The checksum of the // download retrieves a package from a remote upstream. The checksum of the
// files is generated afterwards. // files is generated afterwards.
func download(d deps.Dependency, vendorDir string) (*deps.Dependency, error) { func download(d deps.Dependency, vendorDir, pathToParentModule string) (*deps.Dependency, error) {
var p Interface var p Interface
switch { switch {
case d.Source.GitSource != nil: case d.Source.GitSource != nil:
p = NewGitPackage(d.Source.GitSource) p = NewGitPackage(d.Source.GitSource)
case d.Source.LocalSource != nil: case d.Source.LocalSource != nil:
p = NewLocalPackage(d.Source.LocalSource) wd, err := os.Getwd()
if err != nil {
return nil, fmt.Errorf("failed to get current working directory: %w", err)
}
// Resolve the relative path to the parent module. When a local
// dependency tree is resolved recursively, nested local dependencies
// with relative paths must be evaluated relative to their referencing
// jsonnetfile, rather than relative to the top-level jsonnetfile.
modulePath, err := filepath.Rel(wd, filepath.Join(pathToParentModule, d.Source.LocalSource.Directory))
if err != nil {
modulePath = d.Source.LocalSource.Directory
}
p = NewLocalPackage(&deps.Local{Directory: modulePath})
} }
if p == nil { if p == nil {