github.com/golang/dep@v0.5.4/gps/manifest.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package gps 6 7 import "github.com/golang/dep/gps/pkgtree" 8 9 // Manifest represents manifest-type data for a project at a particular version. 10 // The constraints expressed in a manifest determine the set of versions that 11 // are acceptable to try for a given project. 12 // 13 // Expressing a constraint in a manifest does not guarantee that a particular 14 // dependency will be present. It only guarantees that if packages in the 15 // project specified by the dependency are discovered through static analysis of 16 // the (transitive) import graph, then they will conform to the constraint. 17 // 18 // This does entail that manifests can express constraints on projects they do 19 // not themselves import. This is by design, but its implications are complex. 20 // See the gps docs for more information: https://github.com/sdboyer/gps/wiki 21 type Manifest interface { 22 // Returns a list of project-level constraints. 23 DependencyConstraints() ProjectConstraints 24 } 25 26 // RootManifest extends Manifest to add special controls over solving that are 27 // only afforded to the root project. 28 type RootManifest interface { 29 Manifest 30 31 // Overrides returns a list of ProjectConstraints that will unconditionally 32 // supersede any ProjectConstraint declarations made in either the root 33 // manifest, or in any dependency's manifest. 34 // 35 // Overrides are a special control afforded only to root manifests. Tool 36 // users should be encouraged to use them only as a last resort; they do not 37 // "play well with others" (that is their express goal), and overreliance on 38 // them can harm the ecosystem as a whole. 39 Overrides() ProjectConstraints 40 41 // IgnoredPackages returns a pkgtree.IgnoredRuleset, which comprises a set 42 // of import paths, or import path patterns, that are to be ignored during 43 // solving. These ignored import paths can be within the root project, or 44 // part of other projects. Ignoring a package means that both it and its 45 // (unique) imports will be disregarded by all relevant solver operations. 46 // 47 // It is an error to include a package in both the ignored and required 48 // sets. 49 IgnoredPackages() *pkgtree.IgnoredRuleset 50 51 // RequiredPackages returns a set of import paths to require. These packages 52 // are required to be present in any solution. The list can include main 53 // packages. 54 // 55 // It is meaningless to specify packages that are within the 56 // PackageTree of the ProjectRoot (though not an error, because the 57 // RootManifest itself does not report a ProjectRoot). 58 // 59 // It is an error to include a package in both the ignored and required 60 // sets. 61 RequiredPackages() map[string]bool 62 } 63 64 // SimpleManifest is a helper for tools to enumerate manifest data. It's 65 // generally intended for ephemeral manifests, such as those Analyzers create on 66 // the fly for projects with no manifest metadata, or metadata through a foreign 67 // tool's idioms. 68 type SimpleManifest struct { 69 Deps ProjectConstraints 70 } 71 72 var _ Manifest = SimpleManifest{} 73 74 // DependencyConstraints returns the project's dependencies. 75 func (m SimpleManifest) DependencyConstraints() ProjectConstraints { 76 return m.Deps 77 } 78 79 // simpleRootManifest exists so that we have a safe value to swap into solver 80 // params when a nil Manifest is provided. 81 type simpleRootManifest struct { 82 c, ovr ProjectConstraints 83 ig *pkgtree.IgnoredRuleset 84 req map[string]bool 85 } 86 87 func (m simpleRootManifest) DependencyConstraints() ProjectConstraints { 88 return m.c 89 } 90 func (m simpleRootManifest) Overrides() ProjectConstraints { 91 return m.ovr 92 } 93 func (m simpleRootManifest) IgnoredPackages() *pkgtree.IgnoredRuleset { 94 return m.ig 95 } 96 func (m simpleRootManifest) RequiredPackages() map[string]bool { 97 return m.req 98 } 99 100 // prepManifest ensures a manifest is prepared and safe for use by the solver. 101 // This is mostly about ensuring that no outside routine can modify the manifest 102 // while the solver is in-flight, but it also filters out any empty 103 // ProjectProperties. 104 // 105 // This is achieved by copying the manifest's data into a new SimpleManifest. 106 func prepManifest(m Manifest) SimpleManifest { 107 if m == nil { 108 return SimpleManifest{} 109 } 110 111 deps := m.DependencyConstraints() 112 113 rm := SimpleManifest{ 114 Deps: make(ProjectConstraints, len(deps)), 115 } 116 117 for k, d := range deps { 118 // A zero-value ProjectProperties is equivalent to one with an 119 // anyConstraint{} in terms of how the solver will treat it. However, we 120 // normalize between these two by omitting such instances entirely, as 121 // it negates some possibility for false mismatches in input hashing. 122 if d.Constraint == nil { 123 if d.Source == "" { 124 continue 125 } 126 d.Constraint = anyConstraint{} 127 } 128 129 rm.Deps[k] = d 130 } 131 132 return rm 133 }