diff --git a/analyzer.go b/analyzer.go index f2f17996c4..2e4b6fa30a 100644 --- a/analyzer.go +++ b/analyzer.go @@ -45,7 +45,10 @@ func (a Analyzer) DeriveManifestAndLock(path string, n gps.ProjectRoot) (gps.Man return m, nil, nil } -// Info returns the name and version of this ProjectAnalyzer. -func (a Analyzer) Info() (string, int) { - return "dep", 1 +// Info returns Analyzer's name and version info. +func (a Analyzer) Info() gps.ProjectAnalyzerInfo { + return gps.ProjectAnalyzerInfo{ + Name: "dep", + Version: 1, + } } diff --git a/analyzer_test.go b/analyzer_test.go index f67fffa0d8..4e453620a4 100644 --- a/analyzer_test.go +++ b/analyzer_test.go @@ -105,9 +105,9 @@ func TestAnalyzerDeriveManifestAndLockInvalidManifest(t *testing.T) { func TestAnalyzerInfo(t *testing.T) { a := Analyzer{} - name, vers := a.Info() + info := a.Info() - if name != "dep" || vers != 1 { - t.Fatalf("expected name to be 'dep' and version to be 1: name -> %q vers -> %d", name, vers) + if info.Name != "dep" || info.Version != 1 { + t.Fatalf("expected name to be 'dep' and version to be 1: name -> %q vers -> %d", info.Name, info.Version) } } diff --git a/cmd/dep/root_analyzer.go b/cmd/dep/root_analyzer.go index ba334af6f7..f93af66f24 100644 --- a/cmd/dep/root_analyzer.go +++ b/cmd/dep/root_analyzer.go @@ -141,13 +141,16 @@ func (a *rootAnalyzer) FinalizeRootManifestAndLock(m *dep.Manifest, l *dep.Lock) } } -func (a *rootAnalyzer) Info() (string, int) { +func (a *rootAnalyzer) Info() gps.ProjectAnalyzerInfo { name := "dep" version := 1 if !a.skipTools { name = "dep+import" } - return name, version + return gps.ProjectAnalyzerInfo{ + Name: name, + Version: version, + } } func lookupVersionForRevision(rev gps.Revision, pi gps.ProjectIdentifier, sm gps.SourceManager) (gps.Version, error) { diff --git a/cmd/dep/root_analyzer_test.go b/cmd/dep/root_analyzer_test.go index baca305d9f..e4b45ee41e 100644 --- a/cmd/dep/root_analyzer_test.go +++ b/cmd/dep/root_analyzer_test.go @@ -13,7 +13,7 @@ func TestRootAnalyzer_Info(t *testing.T) { } for skipTools, want := range testCases { a := rootAnalyzer{skipTools: skipTools} - got, _ := a.Info() + got := a.Info().Name if got != want { t.Errorf("Expected the name of the importer with skipTools=%t to be '%s', got '%s'", skipTools, want, got) } diff --git a/internal/gps/example.go b/internal/gps/example.go index 5a4c2d4f54..e91db30a79 100644 --- a/internal/gps/example.go +++ b/internal/gps/example.go @@ -70,6 +70,9 @@ func (a NaiveAnalyzer) DeriveManifestAndLock(path string, n gps.ProjectRoot) (gp // Reports the name and version of the analyzer. This is used internally as part // of gps' hashing memoization scheme. -func (a NaiveAnalyzer) Info() (name string, version int) { - return "example-analyzer", 1 +func (a NaiveAnalyzer) Info() gps.ProjectAnalyzerInfo { + return gps.ProjectAnalyzerInfo{ + Name: "example-analyzer", + Version: 1, + } } diff --git a/internal/gps/hash.go b/internal/gps/hash.go index 61c7b5fcba..43e84c711d 100644 --- a/internal/gps/hash.go +++ b/internal/gps/hash.go @@ -106,9 +106,9 @@ func (s *solver) writeHashingInputs(w io.Writer) { } writeString(hhAnalyzer) - an, av := s.rd.an.Info() - writeString(an) - writeString(strconv.Itoa(av)) + ai := s.rd.an.Info() + writeString(ai.Name) + writeString(strconv.Itoa(ai.Version)) } // bytes.Buffer wrapper that injects newlines after each call to Write(). diff --git a/internal/gps/manager_test.go b/internal/gps/manager_test.go index 0bb105ca11..d505846677 100644 --- a/internal/gps/manager_test.go +++ b/internal/gps/manager_test.go @@ -27,8 +27,11 @@ func (naiveAnalyzer) DeriveManifestAndLock(string, ProjectRoot) (Manifest, Lock, return nil, nil, nil } -func (a naiveAnalyzer) Info() (name string, version int) { - return "naive-analyzer", 1 +func (a naiveAnalyzer) Info() ProjectAnalyzerInfo { + return ProjectAnalyzerInfo{ + Name: "naive-analyzer", + Version: 1, + } } func mkNaiveSM(t *testing.T) (*SourceMgr, func()) { diff --git a/internal/gps/result.go b/internal/gps/result.go index 03948ff5bd..eb9d6ad0e1 100644 --- a/internal/gps/result.go +++ b/internal/gps/result.go @@ -35,11 +35,8 @@ type solution struct { // The hash digest of the input opts hd []byte - // The analyzer name - analyzerName string - - // The analyzer version - analyzerVersion int + // The analyzer info + analyzerInfo ProjectAnalyzerInfo // The solver used in producing this solution solv Solver @@ -95,11 +92,11 @@ func (r solution) InputHash() []byte { } func (r solution) AnalyzerName() string { - return r.analyzerName + return r.analyzerInfo.Name } func (r solution) AnalyzerVersion() int { - return r.analyzerVersion + return r.analyzerInfo.Version } func (r solution) SolverName() string { diff --git a/internal/gps/result_test.go b/internal/gps/result_test.go index 42f71d5678..cc96a8e2cb 100644 --- a/internal/gps/result_test.go +++ b/internal/gps/result_test.go @@ -34,7 +34,7 @@ func init() { }, nil), }, } - basicResult.analyzerName, basicResult.analyzerVersion = (naiveAnalyzer{}).Info() + basicResult.analyzerInfo = (naiveAnalyzer{}).Info() // Just in case something needs punishing, kubernetes offers a complex, // real-world set of dependencies, and this revision is known to work. diff --git a/internal/gps/solver.go b/internal/gps/solver.go index 9d54e034ff..fd8695fd13 100644 --- a/internal/gps/solver.go +++ b/internal/gps/solver.go @@ -405,7 +405,7 @@ func (s *solver) Solve() (Solution, error) { att: s.attempts, solv: s, } - soln.analyzerName, soln.analyzerVersion = s.rd.an.Info() + soln.analyzerInfo = s.rd.an.Info() soln.hd = s.HashInputs() // Convert ProjectAtoms into LockedProjects diff --git a/internal/gps/source.go b/internal/gps/source.go index 85cdb23eb4..d687a1b687 100644 --- a/internal/gps/source.go +++ b/internal/gps/source.go @@ -276,7 +276,7 @@ func (sg *sourceGateway) getManifestAndLock(ctx context.Context, pr ProjectRoot, return nil, nil, err } - m, l, has := sg.cache.getManifestAndLock(r, an) + m, l, has := sg.cache.getManifestAndLock(r, an.Info()) if has { return m, l, nil } @@ -286,8 +286,7 @@ func (sg *sourceGateway) getManifestAndLock(ctx context.Context, pr ProjectRoot, return nil, nil, err } - name, vers := an.Info() - label := fmt.Sprintf("%s:%s.%v", sg.src.upstreamURL(), name, vers) + label := fmt.Sprintf("%s:%s", sg.src.upstreamURL(), an.Info()) err = sg.suprvsr.do(ctx, label, ctGetManifestAndLock, func(ctx context.Context) error { m, l, err = sg.src.getManifestAndLock(ctx, pr, r, an) return err @@ -317,7 +316,7 @@ func (sg *sourceGateway) getManifestAndLock(ctx context.Context, pr ProjectRoot, return nil, nil, err } - sg.cache.setManifestAndLock(r, an, m, l) + sg.cache.setManifestAndLock(r, an.Info(), m, l) return m, l, nil } diff --git a/internal/gps/source_cache.go b/internal/gps/source_cache.go index 4a1ecb6a06..b0b5e073aa 100644 --- a/internal/gps/source_cache.go +++ b/internal/gps/source_cache.go @@ -16,11 +16,11 @@ import ( type singleSourceCache interface { // Store the manifest and lock information for a given revision, as defined by // a particular ProjectAnalyzer. - setManifestAndLock(Revision, ProjectAnalyzer, Manifest, Lock) + setManifestAndLock(Revision, ProjectAnalyzerInfo, Manifest, Lock) // Get the manifest and lock information for a given revision, as defined by // a particular ProjectAnalyzer. - getManifestAndLock(Revision, ProjectAnalyzer) (Manifest, Lock, bool) + getManifestAndLock(Revision, ProjectAnalyzerInfo) (Manifest, Lock, bool) // Store a PackageTree for a given revision. setPackageTree(Revision, pkgtree.PackageTree) @@ -63,7 +63,7 @@ type singleSourceCache interface { type singleSourceCacheMemory struct { mut sync.RWMutex // protects all maps - infos map[ProjectAnalyzer]map[Revision]projectInfo + infos map[ProjectAnalyzerInfo]map[Revision]projectInfo ptrees map[Revision]pkgtree.PackageTree vMap map[UnpairedVersion]Revision rMap map[Revision][]UnpairedVersion @@ -71,7 +71,7 @@ type singleSourceCacheMemory struct { func newMemoryCache() singleSourceCache { return &singleSourceCacheMemory{ - infos: make(map[ProjectAnalyzer]map[Revision]projectInfo), + infos: make(map[ProjectAnalyzerInfo]map[Revision]projectInfo), ptrees: make(map[Revision]pkgtree.PackageTree), vMap: make(map[UnpairedVersion]Revision), rMap: make(map[Revision][]UnpairedVersion), @@ -83,12 +83,12 @@ type projectInfo struct { Lock } -func (c *singleSourceCacheMemory) setManifestAndLock(r Revision, an ProjectAnalyzer, m Manifest, l Lock) { +func (c *singleSourceCacheMemory) setManifestAndLock(r Revision, pai ProjectAnalyzerInfo, m Manifest, l Lock) { c.mut.Lock() - inner, has := c.infos[an] + inner, has := c.infos[pai] if !has { inner = make(map[Revision]projectInfo) - c.infos[an] = inner + c.infos[pai] = inner } inner[r] = projectInfo{Manifest: m, Lock: l} @@ -100,11 +100,11 @@ func (c *singleSourceCacheMemory) setManifestAndLock(r Revision, an ProjectAnaly c.mut.Unlock() } -func (c *singleSourceCacheMemory) getManifestAndLock(r Revision, an ProjectAnalyzer) (Manifest, Lock, bool) { +func (c *singleSourceCacheMemory) getManifestAndLock(r Revision, pai ProjectAnalyzerInfo) (Manifest, Lock, bool) { c.mut.Lock() defer c.mut.Unlock() - inner, has := c.infos[an] + inner, has := c.infos[pai] if !has { return nil, nil, false } diff --git a/internal/gps/source_manager.go b/internal/gps/source_manager.go index 0119fca472..6f60c6dad6 100644 --- a/internal/gps/source_manager.go +++ b/internal/gps/source_manager.go @@ -87,8 +87,19 @@ type ProjectAnalyzer interface { // expected files containing Manifest and Lock data are merely absent. DeriveManifestAndLock(path string, importRoot ProjectRoot) (Manifest, Lock, error) - // Report the name and version of this ProjectAnalyzer. - Info() (name string, version int) + // Info reports this project analyzer's info. + Info() ProjectAnalyzerInfo +} + +// ProjectAnalyzerInfo indicates a ProjectAnalyzer's name and version. +type ProjectAnalyzerInfo struct { + Name string + Version int +} + +// String returns a string like: "." +func (p ProjectAnalyzerInfo) String() string { + return fmt.Sprintf("%s.%d", p.Name, p.Version) } // SourceMgr is the default SourceManager for gps.