Skip to content

Commit af628fd

Browse files
authored
Merge pull request #627 from abertelrud/SR-2261
Improve the error message that's shown when trying to access a package by a broken local path
2 parents 2a4b91c + 84425a9 commit af628fd

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

Sources/Get/Error.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import Utility
1212

13+
/// Errors that can result from trying to fetch a package from a repository.
1314
enum Error: Swift.Error {
1415

1516
typealias ClonePath = String
@@ -21,6 +22,10 @@ enum Error: Swift.Error {
2122
case updateRequired(ClonePath)
2223
case unversioned(ClonePath)
2324
case invalidDependencyGraphMissingTag(package: String, requestedTag: String, existingTags: String)
25+
/// A package is referenced using a `file` URL (i.e. a local file system reference), but there is no package at that path.
26+
case missingLocalFileURL(URL)
27+
/// A package is referenced using a `file` URL (i.e. a local file system reference), but the file system entity at that path isn't a cloned repository (a situation that is not currently supported).
28+
case nonRepoLocalFileURL(URL)
2429
}
2530

2631
extension Error: CustomStringConvertible {
@@ -38,6 +43,10 @@ extension Error: CustomStringConvertible {
3843
return "No version tag found in (\(package)) package. Add a version tag with \"git tag\" command. Example: \"git tag 0.1.0\""
3944
case .noManifest(let clonePath, let version):
4045
return "The package at `\(clonePath)' has no Package.swift for the specific version: \(version)"
46+
case .missingLocalFileURL(let url):
47+
return "No package at path \(url)"
48+
case .nonRepoLocalFileURL(let url):
49+
return "Directory at path \(url) is not a Git repository"
4150
}
4251
}
4352
}

Sources/Get/PackagesDirectory.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,19 @@ extension PackagesDirectory: Fetcher {
123123
let manifestParser = { try self.manifestLoader.load(packagePath: $0, baseURL: $1, version: $2) }
124124
let basename = url.components(separatedBy: "/").last!
125125
let dstdir = packagesPath.appending(component: basename)
126+
// If it's a local URL, do some preliminary checking. The reason we don't just give it a try and then do forensics if it fails is to avoid spurious successes (not sure if that can happen.
127+
// FIXME: We should also support `file` URLs in addition to "no scheme" URLs to mean a file path.
128+
if URL.scheme(url) == nil {
129+
// It's a local path -- by the time we get here we currently always have an absolute path (this is spelled out it ManifestLoader's `loadFile(path:,baseURL:,version:,fileSystem:)` method, albeit with a note that it should doesn't belong in that method).
130+
let path = AbsolutePath(url)
131+
guard localFileSystem.exists(path) else {
132+
throw Error.missingLocalFileURL(url)
133+
}
134+
// FIXME: We should not be baking in the assumption about ".git" at this point.
135+
guard localFileSystem.isDirectory(path.appending(component: ".git")) else {
136+
throw Error.nonRepoLocalFileURL(url)
137+
}
138+
}
126139
if let repo = Git.Repo(path: dstdir), repo.origin == url {
127140
//TODO need to canonicalize the URL need URL struct
128141
return try RawClone(path: dstdir, manifestParser: manifestParser)

0 commit comments

Comments
 (0)