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