github.com/jdhenke/godel@v0.0.0-20161213181855-abeb3861bf0d/cmd/githubwiki/githubwiki_test.go (about) 1 // Copyright 2016 Palantir Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package githubwiki 16 17 import ( 18 "bytes" 19 "fmt" 20 "io/ioutil" 21 "os/exec" 22 "path" 23 "regexp" 24 "strings" 25 "testing" 26 27 "github.com/nmiyake/pkg/dirs" 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 31 "github.com/palantir/godel/apps/distgo/pkg/git/gittest" 32 ) 33 34 func TestSyncGitHubWiki(t *testing.T) { 35 tmpDir, cleanup, err := dirs.TempDir("", "") 36 defer cleanup() 37 require.NoError(t, err) 38 39 srcRepoParams := commitUserParam{ 40 authorName: "src-author", 41 authorEmail: "src-author@email.com", 42 committerName: "src-committer", 43 committerEmail: "src-committer@email.com", 44 } 45 46 for i, currCase := range []struct { 47 params commitUserParam 48 msg string 49 want commitUserParam 50 wantMessage func(docsDir string) string 51 }{ 52 // provided parameters are used 53 { 54 params: commitUserParam{ 55 authorName: "Author Name", 56 authorEmail: "author@email.com", 57 committerName: "Committer Name", 58 committerEmail: "committer@email.com", 59 }, 60 want: commitUserParam{ 61 authorName: "Author Name", 62 authorEmail: "author@email.com", 63 committerName: "Committer Name", 64 committerEmail: "committer@email.com", 65 }, 66 msg: "Unit test message", 67 wantMessage: func(docsDir string) string { 68 return "Unit test message" 69 }, 70 }, 71 // if parameters are empty, values from source commit are used 72 { 73 params: commitUserParam{}, 74 want: srcRepoParams, 75 msg: "Unit test message", 76 wantMessage: func(docsDir string) string { 77 return "Unit test message" 78 }, 79 }, 80 // templating commit message works 81 { 82 params: commitUserParam{}, 83 want: srcRepoParams, 84 msg: `CommitID: {{.CommitID}}, CommitTime: {{.CommitTime.Unix}}`, 85 wantMessage: func(docsDir string) string { 86 commitID := gitCommitID(t, docsDir) 87 commitTime := gitCommitTime(t, docsDir) 88 return fmt.Sprintf("CommitID: %s, CommitTime: %s", commitID, commitTime) 89 }, 90 }, 91 // invalid template message is used as string literal 92 { 93 params: commitUserParam{}, 94 want: srcRepoParams, 95 msg: "CommitID: {{.CommitID}", 96 wantMessage: func(docsDir string) string { 97 return "CommitID: {{.CommitID}" 98 }, 99 }, 100 } { 101 currCaseTmpDir, err := ioutil.TempDir(tmpDir, fmt.Sprintf("case-%d-", i)) 102 require.NoError(t, err) 103 104 // src repo 105 githubWikiSrcRepo, err := ioutil.TempDir(currCaseTmpDir, "github-wiki-") 106 require.NoError(t, err) 107 gittest.InitGitDir(t, githubWikiSrcRepo) 108 109 // add commit with specific user and committer 110 err = ioutil.WriteFile(path.Join(githubWikiSrcRepo, "foo.txt"), []byte("foo"), 0644) 111 require.NoError(t, err) 112 err = git(githubWikiSrcRepo).commitAll("Original commit message", srcRepoParams) 113 require.NoError(t, err) 114 115 // bare version of source repo 116 githubWikiBareRepo := gitCloneBare(t, githubWikiSrcRepo, currCaseTmpDir) 117 118 // docs directory 119 docsDir, err := ioutil.TempDir(tmpDir, "docs-") 120 require.NoError(t, err) 121 gittest.InitGitDir(t, docsDir) 122 err = ioutil.WriteFile(path.Join(docsDir, "page.md"), []byte("Test page"), 0644) 123 require.NoError(t, err) 124 gittest.CommitAllFiles(t, docsDir, "Initial docs directory commit") 125 126 err = SyncGitHubWiki(Params{ 127 DocsDir: docsDir, 128 Repo: githubWikiBareRepo, 129 AuthorName: currCase.params.authorName, 130 AuthorEmail: currCase.params.authorEmail, 131 CommitterName: currCase.params.committerName, 132 CommitterEmail: currCase.params.committerEmail, 133 Msg: currCase.msg, 134 }, ioutil.Discard) 135 require.NoError(t, err, "Case %d", i) 136 137 got := commitUserParamForRepo(t, git(githubWikiBareRepo)) 138 assert.Equal(t, currCase.wantMessage(docsDir), gitMessage(t, githubWikiBareRepo), "Case %d", i) 139 assert.Equal(t, currCase.want, got, "Case %d", i) 140 } 141 } 142 143 // Tests operations when documents directory being published is not in a Git repository. 144 func TestSyncGitHubWikiNonGitDocsDir(t *testing.T) { 145 tmpDir, cleanup, err := dirs.TempDir("", "") 146 defer cleanup() 147 require.NoError(t, err) 148 149 srcRepoParams := commitUserParam{ 150 authorName: "src-author", 151 authorEmail: "src-author@email.com", 152 committerName: "src-committer", 153 committerEmail: "src-committer@email.com", 154 } 155 156 for i, currCase := range []struct { 157 params commitUserParam 158 msg string 159 want commitUserParam 160 wantMessage func(docsDir string) string 161 wantStdoutRegexp string 162 }{ 163 // if input directory is not in a Git repository, templating will not work. Warning is printed to stdout, but operation still completes. 164 { 165 params: commitUserParam{}, 166 want: srcRepoParams, 167 msg: `CommitID: {{.CommitID}}, CommitTime: {{.CommitTime.Unix}}`, 168 wantMessage: func(docsDir string) string { 169 return `CommitID: {{.CommitID}}, CommitTime: {{.CommitTime.Unix}}` 170 }, 171 wantStdoutRegexp: "(?s).+Continuing with templating disabled. To fix this issue, ensure that the directory is in a Git repository.", 172 }, 173 } { 174 currCaseTmpDir, err := ioutil.TempDir(tmpDir, fmt.Sprintf("case-%d-", i)) 175 require.NoError(t, err) 176 177 // src repo 178 githubWikiSrcRepo, err := ioutil.TempDir(currCaseTmpDir, "github-wiki-") 179 require.NoError(t, err) 180 gittest.InitGitDir(t, githubWikiSrcRepo) 181 182 // add commit with specific user and committer 183 err = ioutil.WriteFile(path.Join(githubWikiSrcRepo, "foo.txt"), []byte("foo"), 0644) 184 require.NoError(t, err) 185 err = git(githubWikiSrcRepo).commitAll("Original commit message", srcRepoParams) 186 require.NoError(t, err) 187 188 // bare version of source repo 189 githubWikiBareRepo := gitCloneBare(t, githubWikiSrcRepo, currCaseTmpDir) 190 191 // docs directory 192 docsDir, err := ioutil.TempDir(tmpDir, "docs-") 193 require.NoError(t, err) 194 err = ioutil.WriteFile(path.Join(docsDir, "page.md"), []byte("Test page"), 0644) 195 require.NoError(t, err) 196 197 buf := &bytes.Buffer{} 198 err = SyncGitHubWiki(Params{ 199 DocsDir: docsDir, 200 Repo: githubWikiBareRepo, 201 AuthorName: currCase.params.authorName, 202 AuthorEmail: currCase.params.authorEmail, 203 CommitterName: currCase.params.committerName, 204 CommitterEmail: currCase.params.committerEmail, 205 Msg: currCase.msg, 206 }, buf) 207 require.NoError(t, err, "Case %d", i) 208 209 got := commitUserParamForRepo(t, git(githubWikiBareRepo)) 210 assert.Equal(t, currCase.wantMessage(docsDir), gitMessage(t, githubWikiBareRepo), "Case %d", i) 211 assert.Equal(t, currCase.want, got, "Case %d", i) 212 assert.Regexp(t, regexp.MustCompile(currCase.wantStdoutRegexp), buf.String(), "Case %d", i) 213 } 214 } 215 216 func commitUserParamForRepo(t *testing.T, g git) commitUserParam { 217 authorName, err := g.valueOr("", authorNameParam) 218 require.NoError(t, err) 219 authorEmail, err := g.valueOr("", authorEmailParam) 220 require.NoError(t, err) 221 committerName, err := g.valueOr("", committerNameParam) 222 require.NoError(t, err) 223 committerEmail, err := g.valueOr("", committerEmailParam) 224 require.NoError(t, err) 225 return commitUserParam{ 226 authorName: authorName, 227 authorEmail: authorEmail, 228 committerName: committerName, 229 committerEmail: committerEmail, 230 } 231 } 232 233 func gitCloneBare(t *testing.T, srcGitRepo, tmpDir string) string { 234 bareRepo, err := ioutil.TempDir(tmpDir, "bare-") 235 require.NoError(t, err) 236 cmd := exec.Command("git", "clone", "--bare", srcGitRepo, bareRepo) 237 output, err := cmd.CombinedOutput() 238 require.NoError(t, err, "Failed to execute %v: %v", cmd.Args, string(output)) 239 return bareRepo 240 } 241 242 func gitMessage(t *testing.T, gitRepo string) string { 243 return gitCommand(t, gitRepo, "show", "-s", "--format=%B") 244 } 245 246 func gitCommitID(t *testing.T, gitRepo string) string { 247 return gitCommand(t, gitRepo, "rev-parse", "HEAD") 248 } 249 250 func gitCommitTime(t *testing.T, gitRepo string) string { 251 return gitCommand(t, gitRepo, "show", "-s", "--format=%ct") 252 } 253 254 func gitCommand(t *testing.T, gitRepo string, args ...string) string { 255 cmd := exec.Command("git", args...) 256 cmd.Dir = gitRepo 257 output, err := cmd.CombinedOutput() 258 require.NoError(t, err, "Failed to execute %v: %v", cmd.Args, string(output)) 259 return strings.TrimSpace(string(output)) 260 }