Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binary dependencies are now downloaded and copied to Carthage/Checkout folder #2532

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 38 additions & 3 deletions Source/CarthageKit/Project.swift
Expand Up @@ -784,7 +784,42 @@ public final class Project { // swiftlint:disable:this type_body_length
self._projectEventsObserver.send(value: .checkingOut(dependency, revision))
})
}


///Checks out the given binary dependency into its intended working directory
private func checkoutBinaryDependency(
_ dependency: Dependency,
version: PinnedVersion,
binary: BinaryURL
) -> SignalProducer<(), CarthageError> {

return SignalProducer<SemanticVersion, ScannableError>(result: SemanticVersion.from(version))
.mapError { CarthageError(scannableError: $0) }
.combineLatest(with: self.downloadBinaryFrameworkDefinition(binary: binary))
.attemptMap { semanticVersion, binaryProject -> Result<(SemanticVersion, URL), CarthageError> in
guard let frameworkURL = binaryProject.versions[version] else {
return .failure(CarthageError.requiredVersionNotFound(Dependency.binary(binary), VersionSpecifier.exactly(semanticVersion)))
}

return .success((semanticVersion, frameworkURL))
}
.flatMap(.concat) { semanticVersion, frameworkURL in
return self.downloadBinary(dependency: Dependency.binary(binary), version: semanticVersion, url: frameworkURL)
}
.flatMap(.concat, unarchive(archive:))
.flatMap(.concat) { unarchiveContentsDirectory -> SignalProducer<URL, CarthageError> in
let checkoutFolderURL = self.directoryURL.appendingPathComponent(dependency.relativePath, isDirectory: true)
try? FileManager.default.removeItem(at: checkoutFolderURL)
return SignalProducer(value: unarchiveContentsDirectory)
}
.flatMap(.concat) { FileManager.default.reactive.enumerator(at: $0, includingPropertiesForKeys: nil, options: [.skipsSubdirectoryDescendants], catchErrors: false).map { _, url in url } }
.flatMap(.concat) { itemURL -> SignalProducer<URL, CarthageError> in

let checkoutFolderURL = self.directoryURL.appendingPathComponent(dependency.relativePath, isDirectory: true)
return SignalProducer(value: itemURL).copyFileURLsIntoDirectory(checkoutFolderURL)
}
.then(SignalProducer(value: ()))
}

public func buildOrderForResolvedCartfile(
_ cartfile: ResolvedCartfile,
dependenciesToInclude: [String]? = nil
Expand Down Expand Up @@ -855,8 +890,8 @@ public final class Project { // swiftlint:disable:this type_body_length
switch dependency {
case .git, .gitHub:
return self.checkoutOrCloneDependency(dependency, version: version, submodulesByPath: submodulesByPath)
case .binary:
return .empty
case .binary(let binary):
return self.checkoutBinaryDependency(dependency, version: version, binary: binary)
}
}
}
Expand Down
128 changes: 128 additions & 0 deletions Tests/CarthageKitTests/ProjectSpec.swift
Expand Up @@ -573,6 +573,134 @@ class ProjectSpec: QuickSpec {
expect(result?.value?.count) == 3
}
}

describe("checkoutResolvedDependencies") {

//setup the working directory
let projectTestWorkingDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!.appendingPathComponent(Constants.bundleIdentifier).appendingPathComponent("unit_tests").appendingPathComponent(UUID().uuidString)
try! FileManager.default.createDirectory(at: projectTestWorkingDirectory, withIntermediateDirectories: true, attributes: nil)

//add some content
let binaryDependencyMockResourceFileName = UUID().uuidString
let binaryDependencyMockResourceFile = projectTestWorkingDirectory.appendingPathComponent("\(binaryDependencyMockResourceFileName).txt")
let binaryDependencyMockResourceFileContents = UUID().uuidString
try! binaryDependencyMockResourceFileContents.write(to: binaryDependencyMockResourceFile, atomically: true, encoding: .utf8)

//produce the mock zip file
let binaryDependencyMockZipName = UUID().uuidString
let binaryDependencyMockZip = projectTestWorkingDirectory.appendingPathComponent("\(binaryDependencyMockZipName).zip")
_ = zip(paths: [binaryDependencyMockResourceFile.lastPathComponent], into: binaryDependencyMockZip, workingDirectory: projectTestWorkingDirectory.path).wait()

//make sure that the binaryDependencyZip file was created
it("should create the binary dependency mock arhive", closure: {

expect(FileManager.default.fileExists(atPath: binaryDependencyMockZip.path)).to(beTrue())
})

//create the binary dependency definition file
let binaryDependencyDefinitionName = UUID().uuidString
let binaryDependencyDefinitionURL = projectTestWorkingDirectory.appendingPathComponent("\(binaryDependencyDefinitionName).json")
try!
"""
{
"1.0.0": "file://\(binaryDependencyMockZip.path)"
}
"""
.write(to: binaryDependencyDefinitionURL, atomically: true, encoding: .utf8)

//create a Cartfile
let cartfileURL = projectTestWorkingDirectory.appendingPathComponent("Cartfile")
try!
"""
binary "file://\(binaryDependencyDefinitionURL.path)"
"""
.write(to: cartfileURL, atomically: true, encoding: .utf8)

//create the Cartfile.resolved
let cartfileResolvedURL = projectTestWorkingDirectory.appendingPathComponent("Cartfile.resolved")
try!
"""
binary "file://\(binaryDependencyDefinitionURL)" "1.0.0"
"""
.write(to: cartfileResolvedURL, atomically: true, encoding: .utf8)

//initialize the project
let project = Project(directoryURL: projectTestWorkingDirectory)
let checkoutDirectory = projectTestWorkingDirectory.appendingPathComponent("Carthage/Checkouts")

_ = project.checkoutResolvedDependencies(buildOptions: nil).wait()

it("should copy the binary depedencies to Carthage/Checkouts folder") {

let binaryDependencyMockResourceFile = checkoutDirectory.appendingPathComponent("\(binaryDependencyDefinitionName)/\(binaryDependencyMockResourceFileName).txt")
expect(FileManager.default.fileExists(atPath: binaryDependencyMockResourceFile.path)).to(beTrue())
expect(expression: { try String(contentsOf: binaryDependencyMockResourceFile) }).to(equal(binaryDependencyMockResourceFileContents))
}
}

describe("updateDependencies should checkout the binary dependencies") {

//setup the working directory
let projectTestWorkingDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!.appendingPathComponent(Constants.bundleIdentifier).appendingPathComponent("unit_tests").appendingPathComponent(UUID().uuidString)
try! FileManager.default.createDirectory(at: projectTestWorkingDirectory, withIntermediateDirectories: true, attributes: nil)

//add some content
let binaryDependencyMockResourceFileName = UUID().uuidString
let binaryDependencyMockResourceFile = projectTestWorkingDirectory.appendingPathComponent("\(binaryDependencyMockResourceFileName).txt")
let binaryDependencyMockResourceFileContents = UUID().uuidString
try! binaryDependencyMockResourceFileContents.write(to: binaryDependencyMockResourceFile, atomically: true, encoding: .utf8)

//produce the mock zip file
let binaryDependencyMockZipName = UUID().uuidString
let binaryDependencyMockZip = projectTestWorkingDirectory.appendingPathComponent("\(binaryDependencyMockZipName).zip")
_ = zip(paths: [binaryDependencyMockResourceFile.lastPathComponent], into: binaryDependencyMockZip, workingDirectory: projectTestWorkingDirectory.path).wait()

//make sure that the binaryDependencyZip file was created
it("should create the binary dependency mock arhive", closure: {

expect(FileManager.default.fileExists(atPath: binaryDependencyMockZip.path)).to(beTrue())
})

//create the binary dependency definition file
let binaryDependencyDefinitionName = UUID().uuidString
let binaryDependencyDefinitionURL = projectTestWorkingDirectory.appendingPathComponent("\(binaryDependencyDefinitionName).json")
try!
"""
{
"1.0.0": "file://\(binaryDependencyMockZip.path)"
}
"""
.write(to: binaryDependencyDefinitionURL, atomically: true, encoding: .utf8)

//create a Cartfile
let cartfileURL = projectTestWorkingDirectory.appendingPathComponent("Cartfile")
try!
"""
binary "file://\(binaryDependencyDefinitionURL.path)"
"""
.write(to: cartfileURL, atomically: true, encoding: .utf8)

//create the Cartfile.resolved
let cartfileResolvedURL = projectTestWorkingDirectory.appendingPathComponent("Cartfile.resolved")
try!
"""
binary "file://\(binaryDependencyDefinitionURL)" "1.0.0"
"""
.write(to: cartfileResolvedURL, atomically: true, encoding: .utf8)

//initialize the project
let project = Project(directoryURL: projectTestWorkingDirectory)
let checkoutDirectory = projectTestWorkingDirectory.appendingPathComponent("Carthage/Checkouts")

_ = project.updateDependencies(shouldCheckout: true, useNewResolver: true, buildOptions: BuildOptions(configuration: "Release"), dependenciesToUpdate: nil).wait()

it("should copy the binary depedencies to Carthage/Checkouts folder") {

let binaryDependencyMockResourceFile = checkoutDirectory.appendingPathComponent("\(binaryDependencyDefinitionName)/\(binaryDependencyMockResourceFileName).txt")
expect(FileManager.default.fileExists(atPath: binaryDependencyMockResourceFile.path)).to(beTrue())
expect(expression: { try String(contentsOf: binaryDependencyMockResourceFile) }).to(equal(binaryDependencyMockResourceFileContents))
}
}
}
}

Expand Down