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  }