From 7e70eec4227e8d9f6caef60aee9a4df238e48396 Mon Sep 17 00:00:00 2001 From: Phil Winder Date: Mon, 28 Aug 2017 15:25:24 +0100 Subject: [PATCH] Add method to list revisions with notes This method uses git notes list to get all notes for a given note ref. We then turn the list into an array and take the second field from the results (which corresponds to the object reference - the commit id in our case). Finally, the result is placed in a map to make it easier to do "if note is in" type queries later. --- git/operations.go | 19 +++++++++ git/operations_test.go | 95 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/git/operations.go b/git/operations.go index 10644ec7f2..f3f1660f3f 100644 --- a/git/operations.go +++ b/git/operations.go @@ -119,6 +119,25 @@ func getNote(workingDir, notesRef, rev string) (*Note, error) { return ¬e, nil } +// Get all revisions with a note (NB: DO NOT RELY ON THE ORDERING) +// It appears to be ordered by ascending git object ref, not by time. +// Return a map to make it easier to do "if in" type queries. +func noteRevList(workingDir, notesRef string) (map[string]bool, error) { + out := &bytes.Buffer{} + if err := execGitCmd(workingDir, nil, out, "notes", "--ref", notesRef, "list"); err != nil { + return nil, err + } + noteList := splitList(out.String()) + result := make(map[string]bool, len(noteList)) + for _, l := range noteList { + split := strings.Fields(l) + if len(split) > 0 { + result[split[1]] = true // First field contains the object ref (commit id in our case) + } + } + return result, nil +} + // Get the commit hash for a reference func refRevision(path, ref string) (string, error) { out := &bytes.Buffer{} diff --git a/git/operations_test.go b/git/operations_test.go index d451d530e7..e3040821e8 100644 --- a/git/operations_test.go +++ b/git/operations_test.go @@ -1,13 +1,96 @@ package git import ( + "fmt" "github.com/weaveworks/flux/cluster/kubernetes/testfiles" + "github.com/weaveworks/flux/job" + "github.com/weaveworks/flux/update" "io/ioutil" "os/exec" "path" "testing" ) +const ( + testNoteRef = "flux-sync" +) + +var ( + noteIdCounter = 1 +) + +func TestListNotes_2Notes(t *testing.T) { + newDir, cleanup := testfiles.TempDir(t) + defer cleanup() + + err := createRepo(newDir, "") + if err != nil { + t.Fatal(err) + } + + idHEAD_1 := testNote(newDir, "HEAD~1") + idHEAD := testNote(newDir, "HEAD") + + notes, err := noteRevList(newDir, testNoteRef) + if err != nil { + t.Fatal(err) + } + + // Now check that these commits actually have a note + if len(notes) != 2 { + t.Fatal("expected two notes") + } + for n := range notes { + note, err := getNote(newDir, testNoteRef, n) + if err != nil { + t.Fatal(err) + } + if note == nil { + t.Fatal("note is nil") + } + if note.JobID != idHEAD_1 && note.JobID != idHEAD { + t.Fatal("Note id didn't match expected", note.JobID) + } + } +} + +func TestListNotes_0Notes(t *testing.T) { + newDir, cleanup := testfiles.TempDir(t) + defer cleanup() + + err := createRepo(newDir, "") + if err != nil { + t.Fatal(err) + } + + notes, err := noteRevList(newDir, testNoteRef) + if err != nil { + t.Fatal(err) + } + + if len(notes) != 0 { + t.Fatal("expected two notes") + } +} + +func testNote(dir, rev string) job.ID { + id := job.ID(fmt.Sprintf("%v", noteIdCounter)) + noteIdCounter += 1 + addNote(dir, rev, testNoteRef, &Note{ + id, + update.Spec{ + update.Auto, + update.Cause{ + "message", + "user", + }, + update.Automated{}, + }, + update.Result{}, + }) + return id +} + func TestChangedFiles_SlashPath(t *testing.T) { newDir, cleanup := testfiles.TempDir(t) defer cleanup() @@ -77,6 +160,18 @@ func createRepo(dir string, nestedDir string) error { if err = execCommand("git", "-C", dir, "commit", "-m", "'Initial revision'"); err != nil { return err } + if err := execCommand("mkdir", "-p", path.Join(fullPath, "another")); err != nil { + return err + } + if err = testfiles.WriteTestFiles(path.Join(fullPath, "another")); err != nil { + return err + } + if err = execCommand("git", "-C", dir, "add", "--all"); err != nil { + return err + } + if err = execCommand("git", "-C", dir, "commit", "-m", "'Second revision'"); err != nil { + return err + } return nil }