Skip to content

Commit bb84fe6

Browse files
committed
Merge pull request golang#21 from sdboyer/tracelog
Implement tracelog
2 parents 3802dcd + 56d2e3b commit bb84fe6

File tree

6 files changed

+186
-243
lines changed

6 files changed

+186
-243
lines changed

errors.go

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ type SolveError interface {
2222
Children() []error
2323
}
2424

25+
type traceError interface {
26+
traceString() string
27+
}
28+
2529
type solveError struct {
2630
lvl errorLevel
2731
msg string
@@ -54,6 +58,24 @@ func (e *noVersionError) Error() string {
5458
return buf.String()
5559
}
5660

61+
func (e *noVersionError) traceString() string {
62+
if len(e.fails) == 0 {
63+
return fmt.Sprintf("No versions found")
64+
}
65+
66+
var buf bytes.Buffer
67+
fmt.Fprintf(&buf, "No versions of %s met constraints:", e.pn.LocalName)
68+
for _, f := range e.fails {
69+
if te, ok := f.f.(traceError); ok {
70+
fmt.Fprintf(&buf, "\n %s: %s", f.v, te.traceString())
71+
} else {
72+
fmt.Fprintf(&buf, "\n %s: %s", f.v, f.f.Error())
73+
}
74+
}
75+
76+
return buf.String()
77+
}
78+
5779
type disjointConstraintFailure struct {
5880
goal Dependency
5981
failsib []Dependency
@@ -64,7 +86,7 @@ type disjointConstraintFailure struct {
6486
func (e *disjointConstraintFailure) Error() string {
6587
if len(e.failsib) == 1 {
6688
str := "Could not introduce %s at %s, as it has a dependency on %s with constraint %s, which has no overlap with existing constraint %s from %s at %s"
67-
return fmt.Sprintf(str, e.goal.Depender.Ident, e.goal.Depender.Version, e.goal.Dep.Ident.errString(), e.goal.Dep.Constraint.String(), e.failsib[0].Dep.Constraint.String(), e.failsib[0].Depender.Ident, e.failsib[0].Depender.Version)
89+
return fmt.Sprintf(str, e.goal.Depender.Ident.errString(), e.goal.Depender.Version, e.goal.Dep.Ident.errString(), e.goal.Dep.Constraint.String(), e.failsib[0].Dep.Constraint.String(), e.failsib[0].Depender.Ident.errString(), e.failsib[0].Depender.Version)
6890
}
6991

7092
var buf bytes.Buffer
@@ -74,16 +96,29 @@ func (e *disjointConstraintFailure) Error() string {
7496
sibs = e.failsib
7597

7698
str := "Could not introduce %s at %s, as it has a dependency on %s with constraint %s, which has no overlap with the following existing constraints:\n"
77-
fmt.Fprintf(&buf, str, e.goal.Depender.Ident, e.goal.Depender.Version, e.goal.Dep.Ident.errString(), e.goal.Dep.Constraint.String())
99+
fmt.Fprintf(&buf, str, e.goal.Depender.Ident.errString(), e.goal.Depender.Version, e.goal.Dep.Ident.errString(), e.goal.Dep.Constraint.String())
78100
} else {
79101
sibs = e.nofailsib
80102

81103
str := "Could not introduce %s at %s, as it has a dependency on %s with constraint %s, which does not overlap with the intersection of existing constraints from other currently selected packages:\n"
82-
fmt.Fprintf(&buf, str, e.goal.Depender.Ident, e.goal.Depender.Version, e.goal.Dep.Ident.errString(), e.goal.Dep.Constraint.String())
104+
fmt.Fprintf(&buf, str, e.goal.Depender.Ident.errString(), e.goal.Depender.Version, e.goal.Dep.Ident.errString(), e.goal.Dep.Constraint.String())
83105
}
84106

85107
for _, c := range sibs {
86-
fmt.Fprintf(&buf, "\t%s at %s with constraint %s\n", c.Depender.Ident, c.Depender.Version, c.Dep.Constraint.String())
108+
fmt.Fprintf(&buf, "\t%s from %s at %s\n", c.Dep.Constraint.String(), c.Depender.Ident.errString(), c.Depender.Version)
109+
}
110+
111+
return buf.String()
112+
}
113+
114+
func (e *disjointConstraintFailure) traceString() string {
115+
var buf bytes.Buffer
116+
fmt.Fprintf(&buf, "constraint %s on %s disjoint with other dependers:\n", e.goal.Dep.Constraint.String(), e.goal.Dep.Ident.errString())
117+
for _, f := range e.failsib {
118+
fmt.Fprintf(&buf, "%s from %s at %s (no overlap)\n", f.Dep.Constraint.String(), f.Depender.Ident.LocalName, f.Depender.Version)
119+
}
120+
for _, f := range e.nofailsib {
121+
fmt.Fprintf(&buf, "%s from %s at %s (some overlap)\n", f.Dep.Constraint.String(), f.Depender.Ident.LocalName, f.Depender.Version)
87122
}
88123

89124
return buf.String()
@@ -102,6 +137,11 @@ func (e *constraintNotAllowedFailure) Error() string {
102137
return fmt.Sprintf(str, e.goal.Depender.Ident.errString(), e.goal.Depender.Version, e.goal.Dep.Ident.errString(), e.goal.Dep.Constraint, e.v)
103138
}
104139

140+
func (e *constraintNotAllowedFailure) traceString() string {
141+
str := "%s at %s depends on %s with %s, but that's already selected at %s"
142+
return fmt.Sprintf(str, e.goal.Depender.Ident.LocalName, e.goal.Depender.Version, e.goal.Dep.Ident.LocalName, e.goal.Dep.Constraint, e.v)
143+
}
144+
105145
type versionNotAllowedFailure struct {
106146
goal ProjectAtom
107147
failparent []Dependency
@@ -111,16 +151,27 @@ type versionNotAllowedFailure struct {
111151
func (e *versionNotAllowedFailure) Error() string {
112152
if len(e.failparent) == 1 {
113153
str := "Could not introduce %s at %s, as it is not allowed by constraint %s from project %s."
114-
return fmt.Sprintf(str, e.goal.Ident, e.goal.Version, e.failparent[0].Dep.Constraint.String(), e.failparent[0].Depender.Ident)
154+
return fmt.Sprintf(str, e.goal.Ident.errString(), e.goal.Version, e.failparent[0].Dep.Constraint.String(), e.failparent[0].Depender.Ident.errString())
115155
}
116156

117157
var buf bytes.Buffer
118158

119159
str := "Could not introduce %s at %s, as it is not allowed by constraints from the following projects:\n"
120-
fmt.Fprintf(&buf, str, e.goal.Ident, e.goal.Version)
160+
fmt.Fprintf(&buf, str, e.goal.Ident.errString(), e.goal.Version)
161+
162+
for _, f := range e.failparent {
163+
fmt.Fprintf(&buf, "\t%s from %s at %s\n", f.Dep.Constraint.String(), f.Depender.Ident.errString(), f.Depender.Version)
164+
}
165+
166+
return buf.String()
167+
}
121168

169+
func (e *versionNotAllowedFailure) traceString() string {
170+
var buf bytes.Buffer
171+
172+
fmt.Fprintf(&buf, "%s at %s not allowed by constraint %s:\n", e.goal.Ident.LocalName, e.goal.Version, e.c.String())
122173
for _, f := range e.failparent {
123-
fmt.Fprintf(&buf, "\t%s at %s with constraint %s\n", f.Depender.Ident, f.Depender.Version, f.Dep.Constraint.String())
174+
fmt.Fprintf(&buf, " %s from %s at %s\n", f.Dep.Constraint.String(), f.Depender.Ident.LocalName, f.Depender.Version)
124175
}
125176

126177
return buf.String()
@@ -157,3 +208,15 @@ func (e *sourceMismatchFailure) Error() string {
157208
str := "Could not introduce %s at %s, as it depends on %s from %s, but %s is already marked as coming from %s by %s"
158209
return fmt.Sprintf(str, e.prob.Ident.errString(), e.prob.Version, e.shared, e.mismatch, e.shared, e.current, strings.Join(cur, ", "))
159210
}
211+
212+
func (e *sourceMismatchFailure) traceString() string {
213+
var buf bytes.Buffer
214+
fmt.Fprintf(&buf, "disagreement on network addr for %s:\n", e.shared)
215+
216+
fmt.Fprintf(&buf, " %s from %s\n", e.mismatch, e.prob.Ident.errString())
217+
for _, dep := range e.sel {
218+
fmt.Fprintf(&buf, " %s from %s\n", e.current, dep.Depender.Ident.errString())
219+
}
220+
221+
return buf.String()
222+
}

glide.lock

Lines changed: 3 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

glide.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ import:
44
version: 2.x
55
vtype: branch
66
vcs: git
7-
- package: github.com/Sirupsen/logrus
8-
version: 0.10.0
9-
vtype: semver
10-
vcs: git
117
- package: github.com/Masterminds/vcs
128
vcs: git
139
- package: github.com/termie/go-shutil

satisfy.go

Lines changed: 21 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package vsolver
22

3-
import "github.com/Sirupsen/logrus"
4-
53
// satisfiable is the main checking method. It determines if introducing a new
64
// project atom would result in a state where all solver requirements are still
75
// satisfied.
@@ -12,13 +10,6 @@ func (s *solver) satisfiable(pa ProjectAtom) error {
1210
panic("canary - checking version of empty ProjectAtom")
1311
}
1412

15-
if s.l.Level >= logrus.DebugLevel {
16-
s.l.WithFields(logrus.Fields{
17-
"name": pa.Ident,
18-
"version": pa.Version,
19-
}).Debug("Checking satisfiability of project atom against current constraints")
20-
}
21-
2213
if err := s.checkAtomAllowable(pa); err != nil {
2314
return err
2415
}
@@ -33,7 +24,6 @@ func (s *solver) satisfiable(pa ProjectAtom) error {
3324
if err := s.checkIdentMatches(pa, dep); err != nil {
3425
return err
3526
}
36-
// TODO dart skips "magic" deps here; do we need that?
3727
if err := s.checkDepsConstraintsAllowable(pa, dep); err != nil {
3828
return err
3929
}
@@ -44,13 +34,6 @@ func (s *solver) satisfiable(pa ProjectAtom) error {
4434
// TODO add check that fails if adding this atom would create a loop
4535
}
4636

47-
if s.l.Level >= logrus.DebugLevel {
48-
s.l.WithFields(logrus.Fields{
49-
"name": pa.Ident,
50-
"version": pa.Version,
51-
}).Debug("Project atom passed satisfiability test against current state")
52-
}
53-
5437
return nil
5538
}
5639

@@ -63,35 +46,23 @@ func (s *solver) checkAtomAllowable(pa ProjectAtom) error {
6346
}
6447
// TODO collect constraint failure reason
6548

66-
if s.l.Level >= logrus.InfoLevel {
67-
s.l.WithFields(logrus.Fields{
68-
"name": pa.Ident,
69-
"version": pa.Version,
70-
"curconstraint": constraint.String(),
71-
}).Info("Current constraints do not allow version")
72-
}
73-
7449
deps := s.sel.getDependenciesOn(pa.Ident)
7550
var failparent []Dependency
7651
for _, dep := range deps {
7752
if !dep.Dep.Constraint.Matches(pa.Version) {
78-
if s.l.Level >= logrus.DebugLevel {
79-
s.l.WithFields(logrus.Fields{
80-
"name": pa.Ident,
81-
"othername": dep.Depender.Ident,
82-
"constraint": dep.Dep.Constraint.String(),
83-
}).Debug("Marking other, selected project with conflicting constraint as failed")
84-
}
8553
s.fail(dep.Depender.Ident)
8654
failparent = append(failparent, dep)
8755
}
8856
}
8957

90-
return &versionNotAllowedFailure{
58+
err := &versionNotAllowedFailure{
9159
goal: pa,
9260
failparent: failparent,
9361
c: constraint,
9462
}
63+
64+
s.logSolve(err)
65+
return err
9566
}
9667

9768
// checkDepsConstraintsAllowable checks that the constraints of an atom on a
@@ -104,44 +75,27 @@ func (s *solver) checkDepsConstraintsAllowable(pa ProjectAtom, dep ProjectDep) e
10475
return nil
10576
}
10677

107-
if s.l.Level >= logrus.DebugLevel {
108-
s.l.WithFields(logrus.Fields{
109-
"name": pa.Ident,
110-
"version": pa.Version,
111-
"depname": dep.Ident,
112-
"curconstraint": constraint.String(),
113-
"newconstraint": dep.Constraint.String(),
114-
}).Debug("Project atom cannot be added; its constraints are disjoint with existing constraints")
115-
}
116-
11778
siblings := s.sel.getDependenciesOn(dep.Ident)
11879
// No admissible versions - visit all siblings and identify the disagreement(s)
11980
var failsib []Dependency
12081
var nofailsib []Dependency
12182
for _, sibling := range siblings {
12283
if !sibling.Dep.Constraint.MatchesAny(dep.Constraint) {
123-
if s.l.Level >= logrus.DebugLevel {
124-
s.l.WithFields(logrus.Fields{
125-
"name": pa.Ident,
126-
"version": pa.Version,
127-
"depname": sibling.Depender.Ident,
128-
"sibconstraint": sibling.Dep.Constraint.String(),
129-
"newconstraint": dep.Constraint.String(),
130-
}).Debug("Marking other, selected project as failed because its constraint is disjoint with our testee")
131-
}
13284
s.fail(sibling.Depender.Ident)
13385
failsib = append(failsib, sibling)
13486
} else {
13587
nofailsib = append(nofailsib, sibling)
13688
}
13789
}
13890

139-
return &disjointConstraintFailure{
91+
err := &disjointConstraintFailure{
14092
goal: Dependency{Depender: pa, Dep: dep},
14193
failsib: failsib,
14294
nofailsib: nofailsib,
14395
c: constraint,
14496
}
97+
s.logSolve(err)
98+
return err
14599
}
146100

147101
// checkDepsDisallowsSelected ensures that an atom's constraints on a particular
@@ -150,21 +104,14 @@ func (s *solver) checkDepsConstraintsAllowable(pa ProjectAtom, dep ProjectDep) e
150104
func (s *solver) checkDepsDisallowsSelected(pa ProjectAtom, dep ProjectDep) error {
151105
selected, exists := s.sel.selected(dep.Ident)
152106
if exists && !dep.Constraint.Matches(selected.Version) {
153-
if s.l.Level >= logrus.DebugLevel {
154-
s.l.WithFields(logrus.Fields{
155-
"name": pa.Ident,
156-
"version": pa.Version,
157-
"depname": dep.Ident,
158-
"curversion": selected.Version,
159-
"newconstraint": dep.Constraint.String(),
160-
}).Debug("Project atom cannot be added; a constraint it introduces does not allow a currently selected version")
161-
}
162107
s.fail(dep.Ident)
163108

164-
return &constraintNotAllowedFailure{
109+
err := &constraintNotAllowedFailure{
165110
goal: Dependency{Depender: pa, Dep: dep},
166111
v: selected.Version,
167112
}
113+
s.logSolve(err)
114+
return err
168115
}
169116
return nil
170117
}
@@ -174,18 +121,27 @@ func (s *solver) checkDepsDisallowsSelected(pa ProjectAtom, dep ProjectDep) erro
174121
// been selected).
175122
//
176123
// In other words, this ensures that the solver never simultaneously selects two
177-
// identifiers that disagree about where their upstream source is.
124+
// identifiers with the same local name, but that disagree about where their
125+
// network source is.
178126
func (s *solver) checkIdentMatches(pa ProjectAtom, dep ProjectDep) error {
179127
if cur, exists := s.names[dep.Ident.LocalName]; exists {
180128
if cur != dep.Ident.netName() {
181129
deps := s.sel.getDependenciesOn(pa.Ident)
182-
return &sourceMismatchFailure{
130+
// Fail all the other deps, as there's no way atom can ever be
131+
// compatible with them
132+
for _, d := range deps {
133+
s.fail(d.Depender.Ident)
134+
}
135+
136+
err := &sourceMismatchFailure{
183137
shared: dep.Ident.LocalName,
184138
sel: deps,
185139
current: cur,
186140
mismatch: dep.Ident.netName(),
187141
prob: pa,
188142
}
143+
s.logSolve(err)
144+
return err
189145
}
190146
}
191147

0 commit comments

Comments
 (0)