github.com/tiagovtristao/plz@v13.4.0+incompatible/src/scm/scm.go (about) 1 // Package scm abstracts operations on various tools like git 2 // Currently, only git 3 package scm 4 5 import ( 6 "github.com/thought-machine/please/src/core" 7 "os/exec" 8 "path" 9 "path/filepath" 10 "strings" 11 12 "gopkg.in/op/go-logging.v1" 13 ) 14 15 var log = logging.MustGetLogger("scm") 16 17 // CurrentRevIdentifier returns the string that specifies what the current revision is. 18 func CurrentRevIdentifier() string { 19 return "HEAD" 20 } 21 22 // ChangesIn returns a list of modified files in the given diffSpec. 23 func ChangesIn(diffSpec string, relativeTo string) []string { 24 if relativeTo == "" { 25 relativeTo = core.RepoRoot 26 } 27 files := make([]string, 0) 28 command := []string{"diff-tree", "--no-commit-id", "--name-only", "-r", diffSpec} 29 out, err := exec.Command("git", command...).CombinedOutput() 30 if err != nil { 31 log.Fatalf("unable to determine changes: %s", err) 32 } 33 output := strings.Split(string(out), "\n") 34 for _, o := range output { 35 files = append(files, fixGitRelativePath(strings.TrimSpace(o), relativeTo)) 36 } 37 return files 38 } 39 40 // ChangedFiles returns a list of modified files since the given commit, optionally including untracked files. 41 func ChangedFiles(fromCommit string, includeUntracked bool, relativeTo string) []string { 42 if relativeTo == "" { 43 relativeTo = core.RepoRoot 44 } 45 relSuffix := []string{"--", relativeTo} 46 command := []string{"diff", "--name-only", "HEAD"} 47 48 out, err := exec.Command("git", append(command, relSuffix...)...).CombinedOutput() 49 if err != nil { 50 log.Fatalf("unable to find changes: %s", err) 51 } 52 files := strings.Split(string(out), "\n") 53 54 if fromCommit != "" { 55 // Grab the diff from the merge-base to HEAD using ... syntax. This ensures we have just 56 // the changes that have occurred on the current branch. 57 command = []string{"diff", "--name-only", fromCommit + "...HEAD"} 58 out, err = exec.Command("git", append(command, relSuffix...)...).CombinedOutput() 59 if err != nil { 60 log.Fatalf("unable to check current branch: %s", err) 61 } 62 committedChanges := strings.Split(string(out), "\n") 63 files = append(files, committedChanges...) 64 } 65 if includeUntracked { 66 command = []string{"ls-files", "--other", "--exclude-standard"} 67 out, err = exec.Command("git", append(command, relSuffix...)...).CombinedOutput() 68 if err != nil { 69 log.Fatalf("unable to determine untracked files: %s", err) 70 } 71 untracked := strings.Split(string(out), "\n") 72 files = append(files, untracked...) 73 } 74 // git will report changed files relative to the worktree: re-relativize to relativeTo 75 normalized := make([]string, 0) 76 for _, f := range files { 77 normalized = append(normalized, fixGitRelativePath(strings.TrimSpace(f), relativeTo)) 78 } 79 return normalized 80 } 81 82 func fixGitRelativePath(worktreePath, relativeTo string) string { 83 p, err := filepath.Rel(relativeTo, path.Join(core.RepoRoot, worktreePath)) 84 if err != nil { 85 log.Fatalf("unable to determine relative path for %s and %s", core.RepoRoot, relativeTo) 86 } 87 return p 88 }