forked from vercel/turbo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
scm.go
53 lines (45 loc) · 1.99 KB
/
scm.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Package scm abstracts operations on various tools like git
// Currently, only git is supported.
//
// Adapted from https://github.com/thought-machine/please/tree/master/src/scm
// Copyright Thought Machine, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package scm
import (
"github.com/pkg/errors"
"github.com/vercel/turbo/cli/internal/turbopath"
)
var ErrFallback = errors.New("cannot find a .git folder. Falling back to manual file hashing (which may be slower). If you are running this build in a pruned directory, you can ignore this message. Otherwise, please initialize a git repository in the root of your monorepo")
// An SCM represents an SCM implementation that we can ask for various things.
type SCM interface {
// ChangedFiles returns a list of modified files since the given commit, including untracked files
ChangedFiles(fromCommit string, toCommit string, relativeTo string) ([]string, error)
// PreviousContent Returns the content of the file at fromCommit
PreviousContent(fromCommit string, filePath string) ([]byte, error)
}
// newGitSCM returns a new SCM instance for this repo root.
// It returns nil if there is no known implementation there.
func newGitSCM(repoRoot turbopath.AbsoluteSystemPath) SCM {
if repoRoot.UntypedJoin(".git").Exists() {
return &git{repoRoot: repoRoot}
}
return nil
}
// newFallback returns a new SCM instance for this repo root.
// If there is no known implementation it returns a stub.
func newFallback(repoRoot turbopath.AbsoluteSystemPath) (SCM, error) {
if scm := newGitSCM(repoRoot); scm != nil {
return scm, nil
}
return &stub{}, ErrFallback
}
// FromInRepo produces an SCM instance, given a path within a
// repository. It does not need to be a git repository, and if
// it is not, the given path is assumed to be the root.
func FromInRepo(repoRoot turbopath.AbsoluteSystemPath) (SCM, error) {
dotGitDir, err := repoRoot.Findup(".git")
if err != nil {
return nil, err
}
return newFallback(dotGitDir.Dir())
}