Skip to content

Commit 31691f0

Browse files
committed
Replace all repo uri strings with git.RepoSpec.
1 parent bb74a42 commit 31691f0

File tree

4 files changed

+84
-90
lines changed

4 files changed

+84
-90
lines changed

pkg/git/cloner.go

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,19 @@ import (
2525
)
2626

2727
// Cloner is a function that can clone a git repo.
28-
type Cloner func(url string) (*RepoSpec, error)
28+
type Cloner func(repoSpec *RepoSpec) error
2929

3030
// ClonerUsingGitExec uses a local git install, as opposed
3131
// to say, some remote API, to obtain a local clone of
3232
// a remote repo.
33-
func ClonerUsingGitExec(spec string) (*RepoSpec, error) {
33+
func ClonerUsingGitExec(repoSpec *RepoSpec) error {
3434
gitProgram, err := exec.LookPath("git")
3535
if err != nil {
36-
return nil, errors.Wrap(err, "no 'git' program on path")
37-
}
38-
repoSpec, err := NewRepoSpecFromUrl(spec)
39-
if err != nil {
40-
return nil, err
36+
return errors.Wrap(err, "no 'git' program on path")
4137
}
4238
repoSpec.cloneDir, err = fs.NewTmpConfirmedDir()
4339
if err != nil {
44-
return nil, err
40+
return err
4541
}
4642
cmd := exec.Command(
4743
gitProgram,
@@ -52,17 +48,28 @@ func ClonerUsingGitExec(spec string) (*RepoSpec, error) {
5248
cmd.Stdout = &out
5349
err = cmd.Run()
5450
if err != nil {
55-
return nil, errors.Wrapf(err, "trouble cloning %s", spec)
51+
return errors.Wrapf(err, "trouble cloning %s", repoSpec.raw)
5652
}
5753
if repoSpec.ref == "" {
58-
return repoSpec, nil
54+
return nil
5955
}
6056
cmd = exec.Command(gitProgram, "checkout", repoSpec.ref)
6157
cmd.Dir = repoSpec.cloneDir.String()
6258
err = cmd.Run()
6359
if err != nil {
64-
return nil, errors.Wrapf(
60+
return errors.Wrapf(
6561
err, "trouble checking out href %s", repoSpec.ref)
6662
}
67-
return repoSpec, nil
63+
return nil
64+
}
65+
66+
// DoNothingCloner returns a cloner that only sets
67+
// cloneDir field in the repoSpec. It's assumed that
68+
// the cloneDir is associated with some fake filesystem
69+
// used in a test.
70+
func DoNothingCloner(dir fs.ConfirmedDir) Cloner {
71+
return func(rs *RepoSpec) error {
72+
rs.cloneDir = dir
73+
return nil
74+
}
6875
}

pkg/loader/fileloader.go

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -114,44 +114,45 @@ func (l *fileLoader) Root() string {
114114
}
115115

116116
func newLoaderOrDie(fSys fs.FileSystem, path string) *fileLoader {
117-
l, err := newLoaderAtConfirmedDir(
118-
path, fSys, nil, git.ClonerUsingGitExec)
117+
root, err := demandDirectoryRoot(fSys, path)
119118
if err != nil {
120119
log.Fatalf("unable to make loader at '%s'; %v", path, err)
121120
}
122-
return l
121+
return newLoaderAtConfirmedDir(
122+
root, fSys, nil, git.ClonerUsingGitExec)
123123
}
124124

125125
// newLoaderAtConfirmedDir returns a new fileLoader with given root.
126126
func newLoaderAtConfirmedDir(
127-
possibleRoot string, fSys fs.FileSystem,
128-
referrer *fileLoader, cloner git.Cloner) (*fileLoader, error) {
129-
if possibleRoot == "" {
130-
return nil, fmt.Errorf(
127+
root fs.ConfirmedDir, fSys fs.FileSystem,
128+
referrer *fileLoader, cloner git.Cloner) *fileLoader {
129+
return &fileLoader{
130+
root: root,
131+
referrer: referrer,
132+
fSys: fSys,
133+
cloner: cloner,
134+
cleaner: func() error { return nil },
135+
}
136+
}
137+
138+
// Assure that the given path is in fact a directory.
139+
func demandDirectoryRoot(
140+
fSys fs.FileSystem, path string) (fs.ConfirmedDir, error) {
141+
if path == "" {
142+
return "", fmt.Errorf(
131143
"loader root cannot be empty")
132144
}
133-
root, f, err := fSys.CleanedAbs(possibleRoot)
145+
d, f, err := fSys.CleanedAbs(path)
134146
if err != nil {
135-
return nil, fmt.Errorf(
136-
"absolute path error in '%s' : %v", possibleRoot, err)
147+
return "", fmt.Errorf(
148+
"absolute path error in '%s' : %v", path, err)
137149
}
138150
if f != "" {
139-
return nil, fmt.Errorf(
151+
return "", fmt.Errorf(
140152
"got file '%s', but '%s' must be a directory to be a root",
141-
f, possibleRoot)
153+
f, path)
142154
}
143-
if referrer != nil {
144-
if err := referrer.errIfArgEqualOrHigher(root); err != nil {
145-
return nil, err
146-
}
147-
}
148-
return &fileLoader{
149-
root: root,
150-
referrer: referrer,
151-
fSys: fSys,
152-
cloner: cloner,
153-
cleaner: func() error { return nil },
154-
}, nil
155+
return d, nil
155156
}
156157

157158
// New returns a new Loader, rooted relative to current loader,
@@ -160,33 +161,45 @@ func (l *fileLoader) New(path string) (ifc.Loader, error) {
160161
if path == "" {
161162
return nil, fmt.Errorf("new root cannot be empty")
162163
}
163-
if git.IsRepoUrl(path) {
164-
// Avoid cycles.
165-
if err := l.errIfPreviouslySeenUri(path); err != nil {
164+
repoSpec, err := git.NewRepoSpecFromUrl(path)
165+
if err == nil {
166+
// Treat this as git repo clone request.
167+
if err := l.errIfRepoCycle(repoSpec); err != nil {
166168
return nil, err
167169
}
168-
return newLoaderAtGitClone(path, l.fSys, l.referrer, l.cloner)
170+
return newLoaderAtGitClone(repoSpec, l.fSys, l.referrer, l.cloner)
169171
}
170172
if filepath.IsAbs(path) {
171173
return nil, fmt.Errorf("new root '%s' cannot be absolute", path)
172174
}
175+
root, err := demandDirectoryRoot(l.fSys, l.root.Join(path))
176+
if err != nil {
177+
return nil, err
178+
}
179+
if err := l.errIfArgEqualOrHigher(root); err != nil {
180+
return nil, err
181+
}
173182
return newLoaderAtConfirmedDir(
174-
l.root.Join(path), l.fSys, l, l.cloner)
183+
root, l.fSys, l, l.cloner), nil
175184
}
176185

177186
// newLoaderAtGitClone returns a new Loader pinned to a temporary
178187
// directory holding a cloned git repo.
179188
func newLoaderAtGitClone(
180-
uri string, fSys fs.FileSystem,
189+
repoSpec *git.RepoSpec, fSys fs.FileSystem,
181190
referrer *fileLoader, cloner git.Cloner) (ifc.Loader, error) {
182-
repoSpec, err := cloner(uri)
191+
err := cloner(repoSpec)
183192
if err != nil {
184193
return nil, err
185194
}
186195
root, f, err := fSys.CleanedAbs(repoSpec.AbsPath())
187196
if err != nil {
188197
return nil, err
189198
}
199+
// We don't know that the path requested in repoSpec
200+
// is a directory until we actually clone it and look
201+
// inside. That just happened, hence the error check
202+
// is here.
190203
if f != "" {
191204
return nil, fmt.Errorf(
192205
"'%s' refers to file '%s'; expecting directory",
@@ -221,17 +234,17 @@ func (l *fileLoader) errIfArgEqualOrHigher(
221234
// I.e. Allow a distinction between git URI with
222235
// path foo and tag bar and a git URI with the same
223236
// path but a different tag?
224-
// TODO(monopole): Use parsed data instead of looking at Raw().
225-
func (l *fileLoader) errIfPreviouslySeenUri(uri string) error {
226-
if strings.HasPrefix(l.repoSpec.Raw(), uri) {
237+
func (l *fileLoader) errIfRepoCycle(newRepoSpec *git.RepoSpec) error {
238+
// TODO(monopole): Use parsed data instead of Raw().
239+
if strings.HasPrefix(l.repoSpec.Raw(), newRepoSpec.Raw()) {
227240
return fmt.Errorf(
228241
"cycle detected: URI '%s' referenced by previous URI '%s'",
229-
uri, l.repoSpec.Raw())
242+
newRepoSpec.Raw(), l.repoSpec.Raw())
230243
}
231244
if l.referrer == nil {
232245
return nil
233246
}
234-
return l.referrer.errIfPreviouslySeenUri(uri)
247+
return l.referrer.errIfRepoCycle(newRepoSpec)
235248
}
236249

237250
// Load returns content of file at the given relative path,

pkg/loader/fileloader_test.go

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,6 @@ func MakeFakeFs(td []testData) fs.FileSystem {
6464
return fSys
6565
}
6666

67-
func TestNewLoaderAtConfirmedDir_DemandsDirectory(t *testing.T) {
68-
fSys := MakeFakeFs(testCases)
69-
_, err := newLoaderAtConfirmedDir("/foo", fSys, nil, nil)
70-
if err != nil {
71-
t.Fatalf("Unexpected error - a directory should work.")
72-
}
73-
_, err = newLoaderAtConfirmedDir("/foo/project", fSys, nil, nil)
74-
if err != nil {
75-
t.Fatalf("Unexpected error - a directory should work.")
76-
}
77-
_, err = newLoaderAtConfirmedDir("/foo/project/fileA.yaml", fSys, nil, nil)
78-
if err == nil {
79-
t.Fatalf("Expected error - a file should not work.")
80-
}
81-
if !strings.Contains(err.Error(), "must be a directory to be a root") {
82-
t.Fatalf("unexpected err: %v", err)
83-
}
84-
}
85-
8667
func TestLoaderLoad(t *testing.T) {
8768
l1 := NewFileLoaderAtRoot(MakeFakeFs(testCases))
8869
if "/" != l1.Root() {
@@ -351,23 +332,6 @@ func TestSplit(t *testing.T) {
351332
}
352333
}
353334

354-
// makeFakeGitCloner returns a cloner that ignores the
355-
// URL argument and returns a path in a fake file system
356-
// that should already hold the 'repo' contents.
357-
func makeFakeGitCloner(t *testing.T, fSys fs.FileSystem, coRoot string) git.Cloner {
358-
if !fSys.IsDir(coRoot) {
359-
t.Fatalf("expecting a directory at '%s'", coRoot)
360-
}
361-
return func(url string) (*git.RepoSpec, error) {
362-
_, path := splitOnNthSlash(url, 3)
363-
if !fSys.IsDir(coRoot + "/" + path) {
364-
t.Fatalf("expecting a directory at '%s'/'%s'",
365-
coRoot, path)
366-
}
367-
return git.NewRepoSpec(url, fs.ConfirmedDir(coRoot), path), nil
368-
}
369-
}
370-
371335
func TestNewLoaderAtGitClone(t *testing.T) {
372336
rootUrl := "github.com/someOrg/someRepo"
373337
pathInRepo := "foo/base"
@@ -385,9 +349,14 @@ func TestNewLoaderAtGitClone(t *testing.T) {
385349
[]byte(`
386350
whatever
387351
`))
352+
353+
repoSpec, err := git.NewRepoSpecFromUrl(url)
354+
if err != nil {
355+
t.Fatalf("unexpected err: %v\n", err)
356+
}
388357
l, err := newLoaderAtGitClone(
389-
url, fSys, nil,
390-
makeFakeGitCloner(t, fSys, coRoot))
358+
repoSpec, fSys, nil,
359+
git.DoNothingCloner(fs.ConfirmedDir(coRoot)))
391360
if err != nil {
392361
t.Fatalf("unexpected err: %v\n", err)
393362
}

pkg/loader/loader.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,16 @@ import (
2424
)
2525

2626
// NewLoader returns a Loader.
27-
func NewLoader(root string, fSys fs.FileSystem) (ifc.Loader, error) {
28-
if git.IsRepoUrl(root) {
27+
func NewLoader(path string, fSys fs.FileSystem) (ifc.Loader, error) {
28+
repoSpec, err := git.NewRepoSpecFromUrl(path)
29+
if err == nil {
2930
return newLoaderAtGitClone(
30-
root, fSys, nil, git.ClonerUsingGitExec)
31+
repoSpec, fSys, nil, git.ClonerUsingGitExec)
32+
}
33+
root, err := demandDirectoryRoot(fSys, path)
34+
if err != nil {
35+
return nil, err
3136
}
3237
return newLoaderAtConfirmedDir(
33-
root, fSys, nil, git.ClonerUsingGitExec)
38+
root, fSys, nil, git.ClonerUsingGitExec), nil
3439
}

0 commit comments

Comments
 (0)