cloner.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*
  2. Copyright 2018 The Kubernetes Authors.
  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. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package git
  14. import (
  15. "bytes"
  16. "os/exec"
  17. "github.com/pkg/errors"
  18. "sigs.k8s.io/kustomize/pkg/fs"
  19. )
  20. // Cloner is a function that can clone a git repo.
  21. type Cloner func(repoSpec *RepoSpec) error
  22. // ClonerUsingGitExec uses a local git install, as opposed
  23. // to say, some remote API, to obtain a local clone of
  24. // a remote repo.
  25. func ClonerUsingGitExec(repoSpec *RepoSpec) error {
  26. gitProgram, err := exec.LookPath("git")
  27. if err != nil {
  28. return errors.Wrap(err, "no 'git' program on path")
  29. }
  30. repoSpec.cloneDir, err = fs.NewTmpConfirmedDir()
  31. if err != nil {
  32. return err
  33. }
  34. cmd := exec.Command(
  35. gitProgram,
  36. "clone",
  37. repoSpec.CloneSpec(),
  38. repoSpec.cloneDir.String())
  39. var out bytes.Buffer
  40. cmd.Stdout = &out
  41. err = cmd.Run()
  42. if err != nil {
  43. return errors.Wrapf(err, "trouble cloning %s", repoSpec.raw)
  44. }
  45. if repoSpec.ref == "" {
  46. return nil
  47. }
  48. cmd = exec.Command(gitProgram, "checkout", repoSpec.ref)
  49. cmd.Dir = repoSpec.cloneDir.String()
  50. err = cmd.Run()
  51. if err != nil {
  52. return errors.Wrapf(
  53. err, "trouble checking out href %s", repoSpec.ref)
  54. }
  55. return nil
  56. }
  57. // DoNothingCloner returns a cloner that only sets
  58. // cloneDir field in the repoSpec. It's assumed that
  59. // the cloneDir is associated with some fake filesystem
  60. // used in a test.
  61. func DoNothingCloner(dir fs.ConfirmedDir) Cloner {
  62. return func(rs *RepoSpec) error {
  63. rs.cloneDir = dir
  64. return nil
  65. }
  66. }