Skip to content

Commit f60ca06

Browse files
committed
Detect local changes
1 parent 6cb3b25 commit f60ca06

File tree

3 files changed

+93
-6
lines changed

3 files changed

+93
-6
lines changed

patrol/patrol_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ func (test *RepoTest) Run(t *testing.T) {
5252
versions, err := os.ReadDir(commitsDir)
5353
require.NoError(t, err)
5454

55+
var revisions []string
56+
5557
for i, v := range versions {
5658
// copy all files from a "commit"
5759
err = copy(filepath.Join(commitsDir, v.Name()), tmp)
@@ -64,22 +66,24 @@ func (test *RepoTest) Run(t *testing.T) {
6466
require.NoError(t, err)
6567

6668
// make a new commit
67-
_, err = worktree.Commit(fmt.Sprintf("commit #%v", i+1), &git.CommitOptions{
69+
commit, err := worktree.Commit(fmt.Sprintf("commit #%v", i+1), &git.CommitOptions{
6870
Author: &object.Signature{
6971
Name: "patrol test",
7072
7173
When: time.Now(),
7274
},
7375
})
7476
require.NoError(t, err)
77+
78+
revisions = append(revisions, commit.String())
7579
}
7680

7781
r, err := patrol.NewRepo(tmp)
7882
require.NoError(t, err)
7983

80-
changes, err := r.ChangesFrom(test.TestAgainstRevision)
84+
changes, err := r.ChangesFrom(revisions[0])
8185
require.NoError(t, err)
82-
assert.Equal(t, test.ExpectedChangedPackages, changes)
86+
assert.Equal(t, test.ExpectedChangedPackages, changes, test.Name+": expected changes do not match")
8387
}
8488

8589
type RepoTests []RepoTest

patrol/repo.go

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"path/filepath"
88
"strings"
99

10+
"github.com/go-git/go-git/v5"
11+
"github.com/go-git/go-git/v5/plumbing"
1012
"golang.org/x/mod/modfile"
1113
)
1214

@@ -84,7 +86,7 @@ func (r *Repo) AddPackage(path string, imports []string) {
8486
if !exists {
8587
pkg = &Package{
8688
Name: pkgName,
87-
PartOfModule: r.OwnsPackage(path),
89+
PartOfModule: r.OwnsPackage(pkgName),
8890
}
8991
r.Packages[pkgName] = pkg
9092
}
@@ -113,7 +115,87 @@ func (r *Repo) AddDependant(dependant *Package, dependencyName string) {
113115
}
114116

115117
func (r *Repo) ChangesFrom(revision string) ([]string, error) {
116-
return nil, nil
118+
err := r.detectInternalChangesFrom(revision)
119+
if err != nil {
120+
return nil, err
121+
}
122+
123+
var changedOwnedPackages []string
124+
for _, pkg := range r.Packages {
125+
if pkg.PartOfModule && pkg.Changed {
126+
changedOwnedPackages = append(changedOwnedPackages, pkg.Name)
127+
}
128+
}
129+
130+
return changedOwnedPackages, nil
131+
}
132+
133+
func (r *Repo) detectInternalChangesFrom(revision string) error {
134+
// git diff go files
135+
repo, err := git.PlainOpen(r.path)
136+
if err != nil {
137+
return err
138+
}
139+
140+
head, err := repo.Head()
141+
if err != nil {
142+
return err
143+
}
144+
145+
now, err := repo.CommitObject(head.Hash())
146+
if err != nil {
147+
return err
148+
}
149+
150+
nowTree, err := now.Tree()
151+
if err != nil {
152+
return err
153+
}
154+
155+
ref := plumbing.NewHash(revision)
156+
then, err := repo.CommitObject(ref)
157+
if err != nil {
158+
return err
159+
}
160+
161+
thenTree, err := then.Tree()
162+
if err != nil {
163+
return err
164+
}
165+
166+
diff, err := nowTree.Diff(thenTree)
167+
if err != nil {
168+
return err
169+
}
170+
171+
for _, change := range diff {
172+
if !strings.HasSuffix(change.From.Name, ".go") {
173+
continue
174+
}
175+
176+
pkgName := r.ModuleName() + "/" + filepath.Dir(change.From.Name)
177+
r.flagPackageAsChanged(pkgName)
178+
}
179+
180+
return nil
181+
}
182+
183+
func (r *Repo) flagPackageAsChanged(name string) {
184+
pkg, exists := r.Packages[name]
185+
if !exists {
186+
return
187+
}
188+
189+
if pkg.Changed {
190+
// assume change was already acked and save
191+
// some computation
192+
return
193+
}
194+
195+
pkg.Changed = true
196+
for _, d := range pkg.Dependants {
197+
d.Changed = true
198+
}
117199
}
118200

119201
func (r *Repo) ModuleName() string {
@@ -128,6 +210,7 @@ type Package struct {
128210
Name string
129211
PartOfModule bool
130212
Dependants []*Package
213+
Changed bool
131214
}
132215

133216
func directoryShouldBeIgnored(path string) bool {

patrol/repo_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func TestRepo(t *testing.T) {
1212
TestAgainstRevision: "HEAD~1",
1313
ExpectedChangedPackages: []string{
1414
"github.com/utilitywarehouse/internalchange/internal/bar",
15-
"github.com/utilitywarehouse/internalchange/internal/foo",
15+
"github.com/utilitywarehouse/internalchange/pkg/foo",
1616
},
1717
},
1818
}

0 commit comments

Comments
 (0)