Skip to content

Commit a0e002f

Browse files
committed
it's alive! :rocket
1 parent 6297d76 commit a0e002f

File tree

55 files changed

+9891
-3
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+9891
-3
lines changed

patrol/repo.go

Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package patrol
33
import (
44
"go/parser"
55
"go/token"
6+
"io/ioutil"
67
"os"
78
"path/filepath"
89
"strings"
@@ -120,6 +121,11 @@ func (r *Repo) ChangesFrom(revision string) ([]string, error) {
120121
return nil, err
121122
}
122123

124+
err = r.detectGoModulesChanges(revision)
125+
if err != nil {
126+
return nil, err
127+
}
128+
123129
var changedOwnedPackages []string
124130
for _, pkg := range r.Packages {
125131
if pkg.PartOfModule && pkg.Changed {
@@ -173,13 +179,64 @@ func (r *Repo) detectInternalChangesFrom(revision string) error {
173179
continue
174180
}
175181

176-
pkgName := r.ModuleName() + "/" + filepath.Dir(change.From.Name)
182+
var pkgName string
183+
if strings.HasPrefix(change.From.Name, "vendor/") {
184+
pkgName = strings.TrimPrefix(filepath.Dir(change.From.Name), "vendor/")
185+
}
186+
187+
if pkgName == "" {
188+
pkgName = r.ModuleName() + "/" + filepath.Dir(change.From.Name)
189+
}
190+
177191
r.flagPackageAsChanged(pkgName)
178192
}
179193

180194
return nil
181195
}
182196

197+
func (r *Repo) detectGoModulesChanges(revision string) error {
198+
// get old go.mod
199+
// find differences with current one
200+
repo, err := git.PlainOpen(r.path)
201+
if err != nil {
202+
return err
203+
}
204+
205+
ref := plumbing.NewHash(revision)
206+
then, err := repo.CommitObject(ref)
207+
if err != nil {
208+
return err
209+
}
210+
211+
file, err := then.File("go.mod")
212+
if err != nil {
213+
return err
214+
}
215+
216+
reader, err := file.Reader()
217+
if err != nil {
218+
return err
219+
}
220+
defer reader.Close()
221+
222+
b, err := ioutil.ReadAll(reader)
223+
if err != nil {
224+
return err
225+
}
226+
227+
mod, err := modfile.Parse(filepath.Join(r.path, "go.mod"), b, nil)
228+
if err != nil {
229+
return err
230+
}
231+
232+
differentModules := goModDifferences(mod, r.Module)
233+
for _, module := range differentModules {
234+
r.flagPackageAsChanged(module)
235+
}
236+
237+
return nil
238+
}
239+
183240
func (r *Repo) flagPackageAsChanged(name string) {
184241
pkg, exists := r.Packages[name]
185242
if !exists {
@@ -192,10 +249,10 @@ func (r *Repo) flagPackageAsChanged(name string) {
192249
return
193250
}
194251

195-
pkg.Changed = true
196252
for _, d := range pkg.Dependants {
197-
d.Changed = true
253+
r.flagPackageAsChanged(d.Name)
198254
}
255+
pkg.Changed = true
199256
}
200257

201258
func (r *Repo) ModuleName() string {
@@ -216,3 +273,52 @@ type Package struct {
216273
func directoryShouldBeIgnored(path string) bool {
217274
return strings.Contains(path, ".git")
218275
}
276+
277+
// goModDifferences returns the list of packages name that were added, removed
278+
// and/or updated between the two go.mod files
279+
func goModDifferences(a, b *modfile.File) []string {
280+
differences := map[string]interface{}{} // keeping a map of unique differences
281+
// map is [package name]: version
282+
oldRequires := map[string]string{}
283+
for _, r := range a.Require {
284+
oldRequires[r.Mod.Path] = r.Mod.Version
285+
}
286+
287+
newRequires := map[string]string{}
288+
for _, r := range b.Require {
289+
newRequires[r.Mod.Path] = r.Mod.Version
290+
}
291+
292+
for oldPkg, oldVersion := range oldRequires {
293+
newVersion, exists := newRequires[oldPkg]
294+
if !exists {
295+
differences[oldPkg] = struct{}{}
296+
continue
297+
}
298+
299+
if oldVersion != newVersion {
300+
differences[oldPkg] = struct{}{}
301+
continue
302+
}
303+
}
304+
305+
for newPkg, newVersion := range newRequires {
306+
oldVersion, exists := oldRequires[newPkg]
307+
if !exists {
308+
differences[newPkg] = struct{}{}
309+
continue
310+
}
311+
312+
if oldVersion != newVersion {
313+
differences[newPkg] = struct{}{}
314+
continue
315+
}
316+
}
317+
318+
var results []string
319+
for pkg := range differences {
320+
results = append(results, pkg)
321+
}
322+
323+
return results
324+
}

patrol/repo_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ func TestRepo(t *testing.T) {
1313
ExpectedChangedPackages: []string{
1414
"github.com/utilitywarehouse/internalchange/internal/bar",
1515
"github.com/utilitywarehouse/internalchange/pkg/foo",
16+
"github.com/utilitywarehouse/internalchange/pkg/cat",
1617
},
1718
},
1819
RepoTest{
@@ -25,6 +26,16 @@ func TestRepo(t *testing.T) {
2526
"github.com/utilitywarehouse/modules",
2627
},
2728
},
29+
RepoTest{
30+
TestdataFolder: "vendoring",
31+
Name: "change in vendored dependencies",
32+
Description: "A change to a vendored dependency\n" +
33+
"should flag depending packages as changed",
34+
TestAgainstRevision: "HEAD~1",
35+
ExpectedChangedPackages: []string{
36+
"github.com/utilitywarehouse/vendoring",
37+
},
38+
},
2839
}
2940

3041
tests.Run(t)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package cat
2+
3+
import "github.com/utilitywarehouse/internalchange/pkg/foo"
4+
5+
type Cat struct {
6+
foo foo.Foo
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package cat
2+
3+
import "github.com/utilitywarehouse/internalchange/pkg/foo"
4+
5+
type Cat struct {
6+
foo foo.Foo
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package cat
2+
3+
import "github.com/utilitywarehouse/internalchange/pkg/foo"
4+
5+
type Cat struct {
6+
foo foo.Foo
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module github.com/utilitywarehouse/vendoring
2+
3+
go 1.17
4+
5+
require golang.org/x/mod v0.5.1
6+
7+
require golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
2+
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
3+
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
4+
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package main
2+
3+
import "golang.org/x/mod/modfile"
4+
5+
func main() {
6+
modfile.Comment
7+
}

patrol/testdata/vendoring/commits/1/vendor/golang.org/x/mod/LICENSE

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

patrol/testdata/vendoring/commits/1/vendor/golang.org/x/mod/PATENTS

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

0 commit comments

Comments
 (0)