@@ -114,44 +114,45 @@ func (l *fileLoader) Root() string {
114
114
}
115
115
116
116
func newLoaderOrDie (fSys fs.FileSystem , path string ) * fileLoader {
117
- l , err := newLoaderAtConfirmedDir (
118
- path , fSys , nil , git .ClonerUsingGitExec )
117
+ root , err := demandDirectoryRoot (fSys , path )
119
118
if err != nil {
120
119
log .Fatalf ("unable to make loader at '%s'; %v" , path , err )
121
120
}
122
- return l
121
+ return newLoaderAtConfirmedDir (
122
+ root , fSys , nil , git .ClonerUsingGitExec )
123
123
}
124
124
125
125
// newLoaderAtConfirmedDir returns a new fileLoader with given root.
126
126
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 (
131
143
"loader root cannot be empty" )
132
144
}
133
- root , f , err := fSys .CleanedAbs (possibleRoot )
145
+ d , f , err := fSys .CleanedAbs (path )
134
146
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 )
137
149
}
138
150
if f != "" {
139
- return nil , fmt .Errorf (
151
+ return "" , fmt .Errorf (
140
152
"got file '%s', but '%s' must be a directory to be a root" ,
141
- f , possibleRoot )
153
+ f , path )
142
154
}
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
155
156
}
156
157
157
158
// New returns a new Loader, rooted relative to current loader,
@@ -160,33 +161,45 @@ func (l *fileLoader) New(path string) (ifc.Loader, error) {
160
161
if path == "" {
161
162
return nil , fmt .Errorf ("new root cannot be empty" )
162
163
}
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 {
166
168
return nil , err
167
169
}
168
- return newLoaderAtGitClone (path , l .fSys , l .referrer , l .cloner )
170
+ return newLoaderAtGitClone (repoSpec , l .fSys , l .referrer , l .cloner )
169
171
}
170
172
if filepath .IsAbs (path ) {
171
173
return nil , fmt .Errorf ("new root '%s' cannot be absolute" , path )
172
174
}
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
+ }
173
182
return newLoaderAtConfirmedDir (
174
- l . root . Join ( path ) , l .fSys , l , l .cloner )
183
+ root , l .fSys , l , l .cloner ), nil
175
184
}
176
185
177
186
// newLoaderAtGitClone returns a new Loader pinned to a temporary
178
187
// directory holding a cloned git repo.
179
188
func newLoaderAtGitClone (
180
- uri string , fSys fs.FileSystem ,
189
+ repoSpec * git. RepoSpec , fSys fs.FileSystem ,
181
190
referrer * fileLoader , cloner git.Cloner ) (ifc.Loader , error ) {
182
- repoSpec , err := cloner (uri )
191
+ err := cloner (repoSpec )
183
192
if err != nil {
184
193
return nil , err
185
194
}
186
195
root , f , err := fSys .CleanedAbs (repoSpec .AbsPath ())
187
196
if err != nil {
188
197
return nil , err
189
198
}
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.
190
203
if f != "" {
191
204
return nil , fmt .Errorf (
192
205
"'%s' refers to file '%s'; expecting directory" ,
@@ -221,17 +234,17 @@ func (l *fileLoader) errIfArgEqualOrHigher(
221
234
// I.e. Allow a distinction between git URI with
222
235
// path foo and tag bar and a git URI with the same
223
236
// 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 () ) {
227
240
return fmt .Errorf (
228
241
"cycle detected: URI '%s' referenced by previous URI '%s'" ,
229
- uri , l .repoSpec .Raw ())
242
+ newRepoSpec . Raw () , l .repoSpec .Raw ())
230
243
}
231
244
if l .referrer == nil {
232
245
return nil
233
246
}
234
- return l .referrer .errIfPreviouslySeenUri ( uri )
247
+ return l .referrer .errIfRepoCycle ( newRepoSpec )
235
248
}
236
249
237
250
// Load returns content of file at the given relative path,
0 commit comments