From 1cc6c08b2c409cb629146b0f2bcebafdec3b3674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vytautas=20=C5=A0altenis?= Date: Sat, 26 Aug 2017 12:45:42 +0300 Subject: [PATCH] Add a check to ensure canonical import path Reject the candidate when it's imported via a path that differs from the dependency's advertised canonical path. --- internal/gps/satisfy.go | 21 +++++++++++++++++---- internal/gps/solve_failures.go | 13 +++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/internal/gps/satisfy.go b/internal/gps/satisfy.go index 9638d766ff..47b1427f90 100644 --- a/internal/gps/satisfy.go +++ b/internal/gps/satisfy.go @@ -35,7 +35,7 @@ func (s *solver) check(a atomWithPackages, pkgonly bool) error { } } - if err = s.checkRequiredPackagesExist(a); err != nil { + if err = s.checkImportRequirementsAreValid(a); err != nil { return err } @@ -100,9 +100,9 @@ func (s *solver) checkAtomAllowable(pa atom) error { return err } -// checkRequiredPackagesExist ensures that all required packages enumerated by +// checkImportRequirementsAreValid ensures that all required packages enumerated by // existing dependencies on this atom are actually present in the atom. -func (s *solver) checkRequiredPackagesExist(a atomWithPackages) error { +func (s *solver) checkImportRequirementsAreValid(a atomWithPackages) error { ptree, err := s.b.ListPackages(a.a.id, a.a.v) if err != nil { // TODO(sdboyer) handle this more gracefully @@ -121,11 +121,24 @@ func (s *solver) checkRequiredPackagesExist(a atomWithPackages) error { fp[pkg] = errdep } else { perr, has := ptree.Packages[pkg] - if !has || perr.Err != nil { + switch { + case !has: + fallthrough + case perr.Err != nil: fp[pkg] = errDeppers{ err: perr.Err, deppers: []atom{dep.depender}, } + case perr.P.CommentPath != "" && pkg != perr.P.CommentPath: + // we have the package, but depender is trying to import it + // via non-canonical import path, so croak about it + fp[pkg] = errDeppers{ + err: &canonicalImportPathFailure{ + actual: pkg, + canonical: perr.P.CommentPath, + }, + deppers: []atom{dep.depender}, + } } } } diff --git a/internal/gps/solve_failures.go b/internal/gps/solve_failures.go index e6a2c47a85..3a890d279b 100644 --- a/internal/gps/solve_failures.go +++ b/internal/gps/solve_failures.go @@ -369,6 +369,19 @@ func (e *checkeeHasProblemPackagesFailure) traceString() string { return buf.String() } +// canonicalImportPathFailure indicates that the dependee tries to import a +// dependency via a path that is different from the one that the dependency +// declares as its canonical. +type canonicalImportPathFailure struct { + actual string + canonical string +} + +func (e *canonicalImportPathFailure) Error() string { + return fmt.Sprintf("Importing via a path different from the canonical path (got %q, want %q)", + e.actual, e.canonical) +} + // depHasProblemPackagesFailure indicates that the goal dependency was rejected // because there were problems with one or more of the packages the dependency // requires in the atom currently selected for that dependency. (This failure