github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/git/localgit/localgit.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // Package localgit creates a local git repo that can be used for testing code 18 // that uses a git.Client. 19 package localgit 20 21 import ( 22 "fmt" 23 "io/ioutil" 24 "os" 25 "os/exec" 26 "path/filepath" 27 "strings" 28 29 "k8s.io/test-infra/prow/git" 30 ) 31 32 // LocalGit stores the repos in a temp dir. Create with New and delete with 33 // Clean. 34 type LocalGit struct { 35 // Dir is the path to the base temp dir. Repos are at Dir/org/repo. 36 Dir string 37 // Git is the location of the git binary. 38 Git string 39 } 40 41 // New creates a LocalGit and a git.Client pointing at it. 42 func New() (*LocalGit, *git.Client, error) { 43 g, err := exec.LookPath("git") 44 if err != nil { 45 return nil, nil, err 46 } 47 t, err := ioutil.TempDir("", "localgit") 48 if err != nil { 49 return nil, nil, err 50 } 51 c, err := git.NewClient() 52 if err != nil { 53 os.RemoveAll(t) 54 return nil, nil, err 55 } 56 57 getSecret := func() []byte { 58 return []byte("") 59 } 60 61 c.SetCredentials("", getSecret) 62 63 c.SetRemote(t) 64 return &LocalGit{ 65 Dir: t, 66 Git: g, 67 }, c, nil 68 } 69 70 // Clean deletes the local git dir. 71 func (lg *LocalGit) Clean() error { 72 return os.RemoveAll(lg.Dir) 73 } 74 75 func runCmd(cmd, dir string, arg ...string) error { 76 c := exec.Command(cmd, arg...) 77 c.Dir = dir 78 if b, err := c.CombinedOutput(); err != nil { 79 return fmt.Errorf("%s %v: %v, %s", cmd, arg, err, string(b)) 80 } 81 return nil 82 } 83 84 func runCmdOutput(cmd, dir string, arg ...string) (string, error) { 85 c := exec.Command(cmd, arg...) 86 c.Dir = dir 87 b, err := c.CombinedOutput() 88 if err != nil { 89 return "", fmt.Errorf("%s %v: %v, %s", cmd, arg, err, string(b)) 90 } 91 return strings.TrimSpace(string(b)), nil 92 } 93 94 // MakeFakeRepo creates the given repo and makes an initial commit. 95 func (lg *LocalGit) MakeFakeRepo(org, repo string) error { 96 rdir := filepath.Join(lg.Dir, org, repo) 97 if err := os.MkdirAll(rdir, os.ModePerm); err != nil { 98 return err 99 } 100 101 if err := runCmd(lg.Git, rdir, "init"); err != nil { 102 return err 103 } 104 if err := runCmd(lg.Git, rdir, "config", "user.email", "test@test.test"); err != nil { 105 return err 106 } 107 if err := runCmd(lg.Git, rdir, "config", "user.name", "test test"); err != nil { 108 return err 109 } 110 if err := runCmd(lg.Git, rdir, "config", "commit.gpgsign", "false"); err != nil { 111 return err 112 } 113 if err := lg.AddCommit(org, repo, map[string][]byte{"initial": {}}); err != nil { 114 return err 115 } 116 117 return nil 118 } 119 120 // AddCommit adds the files to a new commit in the repo. 121 func (lg *LocalGit) AddCommit(org, repo string, files map[string][]byte) error { 122 rdir := filepath.Join(lg.Dir, org, repo) 123 for f, b := range files { 124 path := filepath.Join(rdir, f) 125 if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil { 126 return err 127 } 128 if err := ioutil.WriteFile(path, b, os.ModePerm); err != nil { 129 return err 130 } 131 if err := runCmd(lg.Git, rdir, "add", f); err != nil { 132 return err 133 } 134 } 135 return runCmd(lg.Git, rdir, "commit", "-m", "wow") 136 } 137 138 // CheckoutNewBranch does git checkout -b. 139 func (lg *LocalGit) CheckoutNewBranch(org, repo, branch string) error { 140 rdir := filepath.Join(lg.Dir, org, repo) 141 return runCmd(lg.Git, rdir, "checkout", "-b", branch) 142 } 143 144 // Checkout does git checkout. 145 func (lg *LocalGit) Checkout(org, repo, commitlike string) error { 146 rdir := filepath.Join(lg.Dir, org, repo) 147 return runCmd(lg.Git, rdir, "checkout", commitlike) 148 } 149 150 // RevParse does git rev-parse. 151 func (lg *LocalGit) RevParse(org, repo, commitlike string) (string, error) { 152 rdir := filepath.Join(lg.Dir, org, repo) 153 return runCmdOutput(lg.Git, rdir, "rev-parse", commitlike) 154 }