Created
December 25, 2015 07:14
-
-
Save ikesyo/008ab1915c327e82abd9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Source/CarthageKit/Errors.swift b/Source/CarthageKit/Errors.swift | |
index f15cc3b..07ac87f 100644 | |
--- a/Source/CarthageKit/Errors.swift | |
+++ b/Source/CarthageKit/Errors.swift | |
@@ -28,6 +28,9 @@ public enum CarthageError: ErrorType, Equatable { | |
/// a dependency. | |
case RequiredVersionNotFound(ProjectIdentifier, VersionSpecifier) | |
+ /// A git submodule didn't exist which is listed in `.gitmodules` entries. | |
+ case SubmoduleNotFound(String) | |
+ | |
/// Failed to check out a repository. | |
case RepositoryCheckoutFailed(workingDirectoryURL: NSURL, reason: String, underlyingError: NSError?) | |
@@ -94,7 +97,10 @@ public func == (lhs: CarthageError, rhs: CarthageError) -> Bool { | |
case let (.RequiredVersionNotFound(left, leftVersion), .RequiredVersionNotFound(right, rightVersion)): | |
return left == right && leftVersion == rightVersion | |
- | |
+ | |
+ case let (.SubmoduleNotFound(left), .SubmoduleNotFound(right)): | |
+ return left == right | |
+ | |
case let (.RepositoryCheckoutFailed(la, lb, lc), .RepositoryCheckoutFailed(ra, rb, rc)): | |
return la == ra && lb == rb && lc == rc | |
@@ -176,6 +182,9 @@ extension CarthageError: CustomStringConvertible { | |
case let .RequiredVersionNotFound(dependency, specifier): | |
return "No available version for \(dependency) satisfies the requirement: \(specifier)" | |
+ case let .SubmoduleNotFound(submodulePath): | |
+ return "Submodule \(submodulePath) does not exist listed in `.gitmodules`" | |
+ | |
case let .RepositoryCheckoutFailed(workingDirectoryURL, reason, underlyingError): | |
var description = "Failed to check out repository into \(workingDirectoryURL.path!): \(reason)" | |
diff --git a/Source/CarthageKit/Git.swift b/Source/CarthageKit/Git.swift | |
index 06c98e7..959c1ae 100644 | |
--- a/Source/CarthageKit/Git.swift | |
+++ b/Source/CarthageKit/Git.swift | |
@@ -250,6 +250,7 @@ public func checkoutRepositoryToDirectory(repositoryFileURL: NSURL, _ workingDir | |
/// revision, into the given working directory. | |
public func cloneSubmodulesForRepository(repositoryFileURL: NSURL, _ workingDirectoryURL: NSURL, revision: String = "HEAD", shouldCloneSubmodule: Submodule -> Bool = { _ in true }) -> SignalProducer<(), CarthageError> { | |
return submodulesInRepository(repositoryFileURL, revision: revision) | |
+ .flatMap(.Concat) { result in SignalProducer(result: result) } | |
.flatMap(.Concat) { submodule -> SignalProducer<(), CarthageError> in | |
if shouldCloneSubmodule(submodule) { | |
return cloneSubmoduleInWorkingDirectory(submodule, workingDirectoryURL) | |
@@ -360,23 +361,24 @@ private func parseConfigEntries(contents: String, keyPrefix: String = "", keySuf | |
/// Determines the SHA that the submodule at the given path is pinned to, in the | |
/// revision of the parent repository specified. | |
-public func submoduleSHAForPath(repositoryFileURL: NSURL, _ path: String, revision: String = "HEAD") -> SignalProducer<String, CarthageError> { | |
+public func submoduleSHAForPath(repositoryFileURL: NSURL, _ path: String, revision: String = "HEAD") -> SignalProducer<String?, CarthageError> { | |
return launchGitTask([ "ls-tree", "-z", revision, path ], repositoryFileURL: repositoryFileURL) | |
- .attemptMap { string in | |
+ .map { string in | |
// Example: | |
// 160000 commit 083fd81ecf00124cbdaa8f86ef10377737f6325a External/ObjectiveGit | |
let components = string.characters.split(3, allowEmptySlices: false) { $0 == " " || $0 == "\t" } | |
if components.count >= 3 { | |
- return .Success(String(components[2])) | |
+ return String(components[2]) | |
} else { | |
- return .Failure(CarthageError.ParseError(description: "expected submodule commit SHA in ls-tree output: \(string)")) | |
+ // See https://github.com/Carthage/Carthage/issues/135. | |
+ return nil | |
} | |
} | |
} | |
/// Returns each submodule found in the given repository revision, or an empty | |
/// signal if none exist. | |
-public func submodulesInRepository(repositoryFileURL: NSURL, revision: String = "HEAD") -> SignalProducer<Submodule, CarthageError> { | |
+public func submodulesInRepository(repositoryFileURL: NSURL, revision: String = "HEAD") -> SignalProducer<Submodule?, CarthageError> { | |
let modulesObject = "\(revision):.gitmodules" | |
let baseArguments = [ "config", "--blob", modulesObject, "-z" ] | |
@@ -384,11 +386,11 @@ public func submodulesInRepository(repositoryFileURL: NSURL, revision: String = | |
.flatMapError { _ in SignalProducer<String, NoError>.empty } | |
.flatMap(.Concat) { value in parseConfigEntries(value, keyPrefix: "submodule.", keySuffix: ".path") } | |
.promoteErrors(CarthageError.self) | |
- .flatMap(.Concat) { name, path -> SignalProducer<Submodule, CarthageError> in | |
+ .flatMap(.Concat) { name, path -> SignalProducer<Submodule?, CarthageError> in | |
return launchGitTask(baseArguments + [ "--get", "submodule.\(name).url" ], repositoryFileURL: repositoryFileURL) | |
.map { GitURL($0) } | |
.zipWith(submoduleSHAForPath(repositoryFileURL, path, revision: revision)) | |
- .map { URL, SHA in Submodule(name: name, path: path, URL: URL, SHA: SHA) } | |
+ .map { URL, SHA in SHA.map { Submodule(name: name, path: path, URL: URL, SHA: $0) } } | |
} | |
} | |
diff --git a/Source/CarthageKit/Project.swift b/Source/CarthageKit/Project.swift | |
index 1093aff..c01ab54 100644 | |
--- a/Source/CarthageKit/Project.swift | |
+++ b/Source/CarthageKit/Project.swift | |
@@ -95,6 +95,8 @@ public let CarthageProjectBinaryAssetContentTypes = [ | |
/// Describes an event occurring to or with a project. | |
public enum ProjectEvent { | |
+ case SubmoduleNotFound(ProjectIdentifier?, String) | |
+ | |
/// The project is beginning to clone. | |
case Cloning(ProjectIdentifier) | |
@@ -534,7 +536,19 @@ public final class Project { | |
let submodulesSignal = submodulesInRepository(self.directoryURL) | |
.reduce([:]) { (submodulesByPath: [String: Submodule], submodule) in | |
var submodulesByPath = submodulesByPath | |
- submodulesByPath[submodule.path] = submodule | |
+ | |
+ submodule.analysis(ifSuccess: { submodule in | |
+ submodulesByPath[submodule.path] = submodule | |
+ }, ifFailure: { error in | |
+ switch error { | |
+ case let .SubmoduleNotFound(path): | |
+ sendNext(self._projectEventsObserver, .SubmoduleNotFound(nil, path)) | |
+ | |
+ default: | |
+ break | |
+ } | |
+ }) | |
+ | |
return submodulesByPath | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment