ソースを参照

Doc puller code, fix build and use go-git Commit() function directly

Brendan Abolivier 6 年 前
コミット
ea5674cb5e
署名者: Brendan Abolivier <contact@brendanabolivier.com> GPGキーID: 8EF1500759F70623
共有4 個のファイルを変更した61 個の追加29 個の削除を含む
  1. 0
    13
      src/git/git.go
  2. 1
    1
      src/puller/main.go
  3. 27
    11
      src/puller/puller.go
  4. 33
    4
      src/puller/versions.go

+ 0
- 13
src/git/git.go ファイルの表示

@@ -4,11 +4,8 @@ import (
4 4
 	"io/ioutil"
5 5
 	"os"
6 6
 	"strings"
7
-	"time"
8 7
 
9 8
 	gogit "gopkg.in/src-d/go-git.v4"
10
-	"gopkg.in/src-d/go-git.v4/plumbing"
11
-	"gopkg.in/src-d/go-git.v4/plumbing/object"
12 9
 
13 10
 	"golang.org/x/crypto/ssh"
14 11
 	gitssh "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh"
@@ -94,16 +91,6 @@ func dirExists(path string) (bool, error) {
94 91
 	return true, err
95 92
 }
96 93
 
97
-func Commit(message string, w *gogit.Worktree) (plumbing.Hash, error) {
98
-	return w.Commit(message, &gogit.CommitOptions{
99
-		Author: &object.Signature{
100
-			Name:  "Grafana Dashboard Manager",
101
-			Email: "grafana@cozycloud.cc",
102
-			When:  time.Now(),
103
-		},
104
-	})
105
-}
106
-
107 94
 func Push(r *gogit.Repository, keyPath string) error {
108 95
 	auth, err := getAuth(keyPath)
109 96
 	if err != nil {

+ 1
- 1
src/puller/main.go ファイルの表示

@@ -40,7 +40,7 @@ func main() {
40 40
 	}
41 41
 
42 42
 	client := grafana.NewClient(*grafanaURL, *grafanaAPIKey)
43
-	if err := Pull(client); err != nil {
43
+	if err := PullGrafanaAndCommit(client); err != nil {
44 44
 		panic(err)
45 45
 	}
46 46
 }

+ 27
- 11
src/puller/puller.go ファイルの表示

@@ -12,12 +12,16 @@ import (
12 12
 	gogit "gopkg.in/src-d/go-git.v4"
13 13
 )
14 14
 
15
+// diffVersion represents a dashboard version diff.
15 16
 type diffVersion struct {
16 17
 	oldVersion int
17 18
 	newVersion int
18 19
 }
19 20
 
20
-func Pull(client *grafana.Client) error {
21
+// PullGrafanaAndCommit pulls all the dashboards from Grafana then commits each
22
+// of them to Git except for those that have a newer or equal version number
23
+// already versionned in the repo
24
+func PullGrafanaAndCommit(client *grafana.Client) error {
21 25
 	dv := make(map[string]diffVersion)
22 26
 
23 27
 	dbVersions, err := getDashboardsVersions()
@@ -48,11 +52,14 @@ func Pull(client *grafana.Client) error {
48 52
 
49 53
 		version, ok := dbVersions[dashboard.Slug]
50 54
 		if !ok || dashboard.Version > version {
51
-			if err = addDashboardChangesToRepo(
52
-				dashboard, version, w, &dv,
53
-			); err != nil {
55
+			if err = addDashboardChangesToRepo(dashboard, w); err != nil {
54 56
 				return err
55 57
 			}
58
+
59
+			dv[dashboard.Slug] = diffVersion{
60
+				oldVersion: version,
61
+				newVersion: dashboard.Version,
62
+			}
56 63
 		}
57 64
 	}
58 65
 
@@ -74,9 +81,11 @@ func Pull(client *grafana.Client) error {
74 81
 	return nil
75 82
 }
76 83
 
84
+// addDashboardChangesToRepo writes a dashboard content in a file, then adds the
85
+// file to the git index so it can be comitted afterwards.
86
+// Returns an error if there was an issue with either of the steps.
77 87
 func addDashboardChangesToRepo(
78
-	dashboard *grafana.Dashboard, oldVersion int, worktree *gogit.Worktree,
79
-	dv *map[string]diffVersion,
88
+	dashboard *grafana.Dashboard, worktree *gogit.Worktree,
80 89
 ) error {
81 90
 	slugExt := dashboard.Slug + ".json"
82 91
 	if err := rewriteFile(
@@ -90,14 +99,17 @@ func addDashboardChangesToRepo(
90 99
 		return err
91 100
 	}
92 101
 
93
-	(*dv)[dashboard.Slug] = diffVersion{
94
-		oldVersion: oldVersion,
95
-		newVersion: dashboard.Version,
96
-	}
97
-
98 102
 	return nil
99 103
 }
100 104
 
105
+// rewriteFile removes a given file and re-creates it with a new content. The
106
+// content is provided as JSON, and is then indented before being written down.
107
+// We need the whole "remove then recreate" thing because, if the file already
108
+// exists, ioutil.WriteFile will append the content to it. However, we want to
109
+// replace the oldest version with another (so git can diff it), so we re-create
110
+// the file with the changed content.
111
+// Returns an error if there was an issue when removing or writing the file, or
112
+// indenting the JSON content.
101 113
 func rewriteFile(filename string, content []byte) error {
102 114
 	if err := os.Remove(filename); err != nil {
103 115
 		pe, ok := err.(*os.PathError)
@@ -114,6 +126,10 @@ func rewriteFile(filename string, content []byte) error {
114 126
 	return ioutil.WriteFile(filename, indentedContent, 0644)
115 127
 }
116 128
 
129
+// indent indents a given JSON content with tabs.
130
+// We need to indent the content as the Grafana API returns a one-lined JSON
131
+// string, which isn't great to work with.
132
+// Returns an error if there was an issue with the process.
117 133
 func indent(srcJSON []byte) (indentedJSON []byte, err error) {
118 134
 	buf := bytes.NewBuffer(nil)
119 135
 	if err = json.Indent(buf, srcJSON, "", "\t"); err != nil {

+ 33
- 4
src/puller/versions.go ファイルの表示

@@ -5,12 +5,17 @@ import (
5 5
 	"fmt"
6 6
 	"io/ioutil"
7 7
 	"os"
8
-
9
-	"git"
8
+	"time"
10 9
 
11 10
 	gogit "gopkg.in/src-d/go-git.v4"
11
+	"gopkg.in/src-d/go-git.v4/plumbing/object"
12 12
 )
13 13
 
14
+// getDashboardsVersions reads the "versions.json" file at the root of the git
15
+// repository and returns its content as a map.
16
+// If the file doesn't exist, returns an empty map.
17
+// Return an error if there was an issue looking for the file (except when the
18
+// file doesn't exist), reading it or formatting its content into a map.
14 19
 func getDashboardsVersions() (versions map[string]int, err error) {
15 20
 	versions = make(map[string]int)
16 21
 
@@ -30,6 +35,14 @@ func getDashboardsVersions() (versions map[string]int, err error) {
30 35
 	return
31 36
 }
32 37
 
38
+// writeVersions updates or creates the "versions.json" file at the root of the
39
+// git repository. It takes as parameter a map of versions computed by
40
+// getDashboardsVersions and a map linking a dashboard slug to an instance of
41
+// diffVersion instance, and uses them both to compute an updated map of
42
+// versions that it will convert to JSON, indent and write down into the
43
+// "versions.json" file.
44
+// Returns an error if there was an issue when conerting to JSON, indenting or
45
+// writing on disk.
33 46
 func writeVersions(versions map[string]int, dv map[string]diffVersion) (err error) {
34 47
 	for slug, diff := range dv {
35 48
 		versions[slug] = diff.newVersion
@@ -49,6 +62,11 @@ func writeVersions(versions map[string]int, dv map[string]diffVersion) (err erro
49 62
 	return rewriteFile(filename, indentedJSON)
50 63
 }
51 64
 
65
+// commitNewVersions creates a git commit from updated dashboard files (that
66
+// have previously been added to the git index) and an updated "versions.json"
67
+// file that it creates (with writeVersions) and add to the index.
68
+// Returns an error if there was an issue when creating the "versions.json"
69
+// file, adding it to the index or creating the commit.
52 70
 func commitNewVersions(
53 71
 	versions map[string]int, dv map[string]diffVersion, worktree *gogit.Worktree,
54 72
 ) (err error) {
@@ -60,15 +78,26 @@ func commitNewVersions(
60 78
 		return err
61 79
 	}
62 80
 
63
-	_, err = git.Commit(getCommitMessage(dv), worktree)
81
+	_, err = worktree.Commit(getCommitMessage(dv), &gogit.CommitOptions{
82
+		Author: &object.Signature{
83
+			Name:  "Grafana Dashboard Manager",
84
+			Email: "grafana@cozycloud.cc",
85
+			When:  time.Now(),
86
+		},
87
+	})
88
+
64 89
 	return
65 90
 }
66 91
 
92
+// getCommitMessage creates a commit message that summarises the version updates
93
+// included in the commit.
67 94
 func getCommitMessage(dv map[string]diffVersion) string {
68 95
 	message := "Updated dashboards\n"
69 96
 
70 97
 	for slug, diff := range dv {
71
-		message += fmt.Sprintf("%s: %d => %d\n", slug, diff.oldVersion, diff.newVersion)
98
+		message += fmt.Sprintf(
99
+			"%s: %d => %d\n", slug, diff.oldVersion, diff.newVersion,
100
+		)
72 101
 	}
73 102
 
74 103
 	return message