Skip to content

Commit 69f564a

Browse files
committed
Allow project-level cycles involving root project
Fixes golang#151. ♬ : Anna Kendrick / Cups (Pitch Perfect’s “When I’m Gone”)
1 parent 9b38990 commit 69f564a

File tree

5 files changed

+21
-20
lines changed

5 files changed

+21
-20
lines changed

bridge.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ func (b *bridge) vtu(id ProjectIdentifier, v Version) versionTypeUnion {
284284
// responsible for that code.
285285
func (b *bridge) ListPackages(id ProjectIdentifier, v Version) (PackageTree, error) {
286286
if b.s.rd.isRoot(id.ProjectRoot) {
287-
panic("should never call ListPackages on root project")
287+
return b.s.rd.rpt, nil
288288
}
289289

290290
b.s.mtr.push("b-list-pkgs")

rootdata.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,20 +141,27 @@ func (rd rootdata) combineConstraints() []workingConstraint {
141141

142142
// needVersionListFor indicates whether we need a version list for a given
143143
// project root, based solely on general solver inputs (no constraint checking
144-
// required). This will be true if any of the following conditions hold:
144+
// required). Assuming the argument is not the root project itself, this will be
145+
// true if any of the following conditions hold:
145146
//
146147
// - ChangeAll is on
147148
// - The project is not in the lock
148149
// - The project is in the lock, but is also in the list of projects to change
149150
func (rd rootdata) needVersionsFor(pr ProjectRoot) bool {
151+
if rd.isRoot(pr) {
152+
return false
153+
}
154+
150155
if rd.chngall {
151156
return true
152157
}
153158

154159
if _, has := rd.rlm[pr]; !has {
155160
// not in the lock
156161
return true
157-
} else if _, has := rd.chng[pr]; has {
162+
}
163+
164+
if _, has := rd.chng[pr]; has {
158165
// in the lock, but marked for change
159166
return true
160167
}

selection.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,7 @@ func (s *selection) getRequiredPackagesIn(id ProjectIdentifier) map[string]int {
8282
uniq := make(map[string]int)
8383
for _, dep := range s.deps[id.ProjectRoot] {
8484
for _, pkg := range dep.dep.pl {
85-
if count, has := uniq[pkg]; has {
86-
count++
87-
uniq[pkg] = count
88-
} else {
89-
uniq[pkg] = 1
90-
}
85+
uniq[pkg] = uniq[pkg] + 1
9186
}
9287
}
9388

@@ -105,12 +100,7 @@ func (s *selection) getSelectedPackagesIn(id ProjectIdentifier) map[string]int {
105100
for _, p := range s.projects {
106101
if p.a.a.id.eq(id) {
107102
for _, pkg := range p.a.pl {
108-
if count, has := uniq[pkg]; has {
109-
count++
110-
uniq[pkg] = count
111-
} else {
112-
uniq[pkg] = 1
113-
}
103+
uniq[pkg] = uniq[pkg] + 1
114104
}
115105
}
116106
}

solve_bimodal_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,16 +291,15 @@ var bimodalFixtures = map[string]bimodalFixture{
291291
pkg("root", "a"),
292292
),
293293
dsp(mkDepspec("a 1.0.0"),
294-
pkg("a"),
294+
pkg("a", "b"),
295295
pkg("a/foo"),
296296
),
297297
dsp(mkDepspec("b 1.0.0"),
298-
pkg("b", "b/baz"),
299-
pkg("b/baz", "a/foo"),
298+
pkg("b", "a/foo"),
300299
),
301300
},
302301
r: mksolution(
303-
"a 1.0.0",
302+
mklp("a 1.0.0", ".", "foo"),
304303
"b 1.0.0",
305304
),
306305
},

solver.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,6 @@ func (s *solver) solve() (map[atom]map[string]struct{}, error) {
455455
func (s *solver) selectRoot() error {
456456
s.mtr.push("select-root")
457457
// Push the root project onto the queue.
458-
// TODO(sdboyer) maybe it'd just be better to skip this?
459458
awp := s.rd.rootAtom()
460459
s.sel.pushSelection(awp, true)
461460

@@ -1063,6 +1062,12 @@ func (s *solver) selectAtom(a atomWithPackages, pkgonly bool) {
10631062
}
10641063

10651064
for _, dep := range deps {
1065+
// Root can come back up here if there's a project-level cycle.
1066+
// Satisfiability checks have already ensured invariants are maintained,
1067+
// so we know we can just skip it here.
1068+
if s.rd.isRoot(dep.Ident.ProjectRoot) {
1069+
continue
1070+
}
10661071
// If this is dep isn't in the lock, do some prefetching. (If it is, we
10671072
// might be able to get away with zero network activity for it, so don't
10681073
// prefetch). This provides an opportunity for some parallelism wins, on

0 commit comments

Comments
 (0)