Browse Source

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

Brendan Abolivier 6 years ago
parent
commit
ea5674cb5e
Signed by: Brendan Abolivier <contact@brendanabolivier.com> GPG key ID: 8EF1500759F70623
4 changed files with 61 additions and 29 deletions
  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 View File

4
 	"io/ioutil"
4
 	"io/ioutil"
5
 	"os"
5
 	"os"
6
 	"strings"
6
 	"strings"
7
-	"time"
8
 
7
 
9
 	gogit "gopkg.in/src-d/go-git.v4"
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
 	"golang.org/x/crypto/ssh"
10
 	"golang.org/x/crypto/ssh"
14
 	gitssh "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh"
11
 	gitssh "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh"
94
 	return true, err
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
 func Push(r *gogit.Repository, keyPath string) error {
94
 func Push(r *gogit.Repository, keyPath string) error {
108
 	auth, err := getAuth(keyPath)
95
 	auth, err := getAuth(keyPath)
109
 	if err != nil {
96
 	if err != nil {

+ 1
- 1
src/puller/main.go View File

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

+ 27
- 11
src/puller/puller.go View File

12
 	gogit "gopkg.in/src-d/go-git.v4"
12
 	gogit "gopkg.in/src-d/go-git.v4"
13
 )
13
 )
14
 
14
 
15
+// diffVersion represents a dashboard version diff.
15
 type diffVersion struct {
16
 type diffVersion struct {
16
 	oldVersion int
17
 	oldVersion int
17
 	newVersion int
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
 	dv := make(map[string]diffVersion)
25
 	dv := make(map[string]diffVersion)
22
 
26
 
23
 	dbVersions, err := getDashboardsVersions()
27
 	dbVersions, err := getDashboardsVersions()
48
 
52
 
49
 		version, ok := dbVersions[dashboard.Slug]
53
 		version, ok := dbVersions[dashboard.Slug]
50
 		if !ok || dashboard.Version > version {
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
 				return err
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
 	return nil
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
 func addDashboardChangesToRepo(
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
 ) error {
89
 ) error {
81
 	slugExt := dashboard.Slug + ".json"
90
 	slugExt := dashboard.Slug + ".json"
82
 	if err := rewriteFile(
91
 	if err := rewriteFile(
90
 		return err
99
 		return err
91
 	}
100
 	}
92
 
101
 
93
-	(*dv)[dashboard.Slug] = diffVersion{
94
-		oldVersion: oldVersion,
95
-		newVersion: dashboard.Version,
96
-	}
97
-
98
 	return nil
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
 func rewriteFile(filename string, content []byte) error {
113
 func rewriteFile(filename string, content []byte) error {
102
 	if err := os.Remove(filename); err != nil {
114
 	if err := os.Remove(filename); err != nil {
103
 		pe, ok := err.(*os.PathError)
115
 		pe, ok := err.(*os.PathError)
114
 	return ioutil.WriteFile(filename, indentedContent, 0644)
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
 func indent(srcJSON []byte) (indentedJSON []byte, err error) {
133
 func indent(srcJSON []byte) (indentedJSON []byte, err error) {
118
 	buf := bytes.NewBuffer(nil)
134
 	buf := bytes.NewBuffer(nil)
119
 	if err = json.Indent(buf, srcJSON, "", "\t"); err != nil {
135
 	if err = json.Indent(buf, srcJSON, "", "\t"); err != nil {

+ 33
- 4
src/puller/versions.go View File

5
 	"fmt"
5
 	"fmt"
6
 	"io/ioutil"
6
 	"io/ioutil"
7
 	"os"
7
 	"os"
8
-
9
-	"git"
8
+	"time"
10
 
9
 
11
 	gogit "gopkg.in/src-d/go-git.v4"
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
 func getDashboardsVersions() (versions map[string]int, err error) {
19
 func getDashboardsVersions() (versions map[string]int, err error) {
15
 	versions = make(map[string]int)
20
 	versions = make(map[string]int)
16
 
21
 
30
 	return
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
 func writeVersions(versions map[string]int, dv map[string]diffVersion) (err error) {
46
 func writeVersions(versions map[string]int, dv map[string]diffVersion) (err error) {
34
 	for slug, diff := range dv {
47
 	for slug, diff := range dv {
35
 		versions[slug] = diff.newVersion
48
 		versions[slug] = diff.newVersion
49
 	return rewriteFile(filename, indentedJSON)
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
 func commitNewVersions(
70
 func commitNewVersions(
53
 	versions map[string]int, dv map[string]diffVersion, worktree *gogit.Worktree,
71
 	versions map[string]int, dv map[string]diffVersion, worktree *gogit.Worktree,
54
 ) (err error) {
72
 ) (err error) {
60
 		return err
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
 	return
89
 	return
65
 }
90
 }
66
 
91
 
92
+// getCommitMessage creates a commit message that summarises the version updates
93
+// included in the commit.
67
 func getCommitMessage(dv map[string]diffVersion) string {
94
 func getCommitMessage(dv map[string]diffVersion) string {
68
 	message := "Updated dashboards\n"
95
 	message := "Updated dashboards\n"
69
 
96
 
70
 	for slug, diff := range dv {
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
 	return message
103
 	return message