Dependencies.swift - Add XCFramework option for Carthage (#2532)
* [carthage-xcframeworks] add - `CarthageController` * [carthage-xcframeworks] add - `MockCarthageController` * [carthage-xcframeworks] change - use `TusitSupport.CarthageController` in `TuistDependencies.CarthageInteractor` * [carthage-xcframeworks] add - `produceXCFrameworks` argument to `CarthageCommandGenerating.command` method * [carthage-xcframeworks] change - redesign `Depedencies` model (ProjectDescription&TuistGraph) * [carthage-xcframeworks] change - adapt `app_with_framework_and_tests_and_dependencies` to changes * [carthage-xcframeworks] change - update docs * [carthage-xcframeworks] change - produce XCFrameworks when required * [carthage-xcframeworks] add - more logs * [carthage-xcframeworks] fix - acceptance test * [carthage-xcframeworks] add - documentation * [carthage-xcframeworks] change - typos * [carthage-xcframeworks] change - run `bundle exec rake style_correct` * [carthage-xcframeworks] fix - swiftlint violations * [carthage-xcframeworks] change - update changelog * [carthage-xcframeworks] change - redesign `ProjectDescription.Dependencies` model * [carthage-xcframeworks] fix - acceptance tests * [carthage-xcframeworks] change - update documentation * [carthage-xcframeworks] change - run `bundle exec rake style_correct` * [carthage-xcframeworks] fix - typos * [carthage-xcframeworks] change - update docs * [carthage-xcframeworks] change - run `bundle exec rake style_correct` * [carthage-xcframeworks] fix - typos
This commit is contained in:
parent
34a0c82492
commit
31f3aba514
|
@ -4,7 +4,10 @@ Please, check out guidelines: https://keepachangelog.com/en/1.0.0/
|
|||
|
||||
## Next
|
||||
|
||||
### Added
|
||||
|
||||
- Enable Main Thread Checker by default [#2549](https://github.com/tuist/tuist/pull/2549) by [@myihsan](https://github.com/myihsan)
|
||||
- Add option for enabling XCFrameworks production for Carthage in `Dependencies.swift`. [#2532](https://github.com/tuist/tuist/pull/2532) by [@laxmorek](https://github.com/laxmorek)
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
import Foundation
|
||||
|
||||
/// A `Dependencies` manifest allows for defining external dependencies for Tuist.
|
||||
public struct Dependencies: Codable, Equatable {
|
||||
/// List of dependencies.
|
||||
public let dependencies: [Dependency]
|
||||
|
||||
/// Initializes a new `Dependencies` manifest instance.
|
||||
/// - Parameter dependencies: List of dependencies.
|
||||
public init(_ dependencies: [Dependency] = []) {
|
||||
self.dependencies = dependencies
|
||||
dumpIfNeeded(self)
|
||||
}
|
||||
}
|
|
@ -1,76 +1,120 @@
|
|||
import Foundation
|
||||
|
||||
/// Contains the description of external dependency that can by installed using Tuist.
|
||||
public enum Dependency: Codable, Equatable {
|
||||
/// Origin of the Carthage dependency
|
||||
public enum CarthageOrigin: Codable, Equatable {
|
||||
/// Mimics `github` keyword from `Cartfile`. GitHub repositories (both GitHub.com and GitHub Enterprise).
|
||||
case github(path: String)
|
||||
/// Mimics `git` keyword from `Cartfile`. Other Git repositories.
|
||||
case git(path: String)
|
||||
/// Mimics `binary` keyword from `Cartfile`. Dependencies that are only available as compiled binary `.frameworks`.
|
||||
case binary(path: String)
|
||||
/// Contains the description of a dependency that can be installed using Carthage.
|
||||
public struct CarthageDependencies: Codable, Equatable {
|
||||
/// List of depedencies that can be installed using Carthage.
|
||||
public let dependencies: [Dependency]
|
||||
/// List of platforms for which you want to install depedencies. Refers to `--platform` Carthage flag.
|
||||
public let platforms: Set<Platform>
|
||||
/// Indicates whether Carthage produces XCFrameworks or regular frameworks. Refers to `--use-xcframeworks` Carthage flag.
|
||||
/// Note: It requires Carthage in version at least 0.37.0.
|
||||
public let useXCFrameworks: Bool
|
||||
|
||||
/// Initializes a new `CarthageDependencies` instance.
|
||||
/// - Parameters:
|
||||
/// - dependencies: List of depedencies that can be installed using Carthage.
|
||||
/// - platforms: List of platforms for which you want to install depedencies. Refers to `--platform` Carthage flag.
|
||||
/// - useXCFrameworks: Indicates whether Carthage produces XCFrameworks or regular frameworks. Refers to `--use-xcframeworks` Carthage flag. Note: It requires Carthage in version at least 0.37.0.
|
||||
init(
|
||||
dependencies: [Dependency],
|
||||
platforms: Set<Platform> = Set(Platform.allCases),
|
||||
useXCFrameworks: Bool = false
|
||||
) {
|
||||
self.dependencies = dependencies
|
||||
self.platforms = platforms
|
||||
self.useXCFrameworks = useXCFrameworks
|
||||
}
|
||||
|
||||
/// Requirement for the Carthage dependency
|
||||
public enum CarthageRequirement: Codable, Equatable {
|
||||
/// Mimics `== 1.0` from `Cartfile`.
|
||||
case exact(Version)
|
||||
/// Mimics `~> 1.0` from `Cartfile`.
|
||||
case upToNext(Version)
|
||||
/// Mimics `>= 1.0` from `Cartfile`.
|
||||
case atLeast(Version)
|
||||
/// Mimics `"branch"` from `Cartfile`.
|
||||
case branch(String)
|
||||
/// Mimics `"revision"` from `Cartfile`.
|
||||
case revision(String)
|
||||
/// Creates `CarthageDependencies` instance.
|
||||
/// - Parameters:
|
||||
/// - dependencies: List of depedencies that can be installed using Carthage.
|
||||
/// - platforms: List of platforms for which you want to install depedencies. Refers to `--platform` Carthage flag.
|
||||
/// - useXCFrameworks: Indicates whether Carthage produces XCFrameworks or regular frameworks. Refers to `--use-xcframeworks` Carthage flag. Note: It requires Carthage in version at least 0.37.0.
|
||||
public static func carthage(
|
||||
_ dependencies: [Dependency],
|
||||
platforms: Set<Platform> = Set(Platform.allCases),
|
||||
useXCFrameworks: Bool = false
|
||||
) -> Self {
|
||||
.init(dependencies: dependencies, platforms: platforms, useXCFrameworks: useXCFrameworks)
|
||||
}
|
||||
|
||||
/// Contains the description of dependency that can by installed using Carthage. More: https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md
|
||||
case carthage(origin: CarthageOrigin, requirement: CarthageRequirement, platforms: Set<Platform>)
|
||||
}
|
||||
|
||||
// MARK: - Dependency: Codable
|
||||
// MARK: - CarthageDependencies.Dependency & CarthageDependencies.Requirement
|
||||
|
||||
extension Dependency {
|
||||
public extension CarthageDependencies {
|
||||
/// Specifies origin of Carthage dependency.
|
||||
enum Dependency: Codable, Equatable {
|
||||
case github(path: String, requirement: Requirement)
|
||||
case git(path: String, requirement: Requirement)
|
||||
case binary(path: String, requirement: Requirement)
|
||||
}
|
||||
|
||||
/// Specifies version requirement for Carthage depedency.
|
||||
enum Requirement: Codable, Equatable {
|
||||
case exact(Version)
|
||||
case upToNext(Version)
|
||||
case atLeast(Version)
|
||||
case branch(String)
|
||||
case revision(String)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - CarthageDependencies.Dependency: Codable
|
||||
|
||||
extension CarthageDependencies.Dependency {
|
||||
private enum Kind: String, Codable {
|
||||
case carthage
|
||||
case github
|
||||
case git
|
||||
case binary
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case kind
|
||||
case origin
|
||||
case path
|
||||
case requirement
|
||||
case platforms
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
let kind = try container.decode(Kind.self, forKey: .kind)
|
||||
switch kind {
|
||||
case .carthage:
|
||||
let origin = try container.decode(CarthageOrigin.self, forKey: .origin)
|
||||
let requirement = try container.decode(CarthageRequirement.self, forKey: .requirement)
|
||||
let platforms = try container.decode(Set<Platform>.self, forKey: .platforms)
|
||||
self = .carthage(origin: origin, requirement: requirement, platforms: platforms)
|
||||
case .github:
|
||||
let path = try container.decode(String.self, forKey: .path)
|
||||
let requirement = try container.decode(CarthageDependencies.Requirement.self, forKey: .requirement)
|
||||
self = .github(path: path, requirement: requirement)
|
||||
case .git:
|
||||
let path = try container.decode(String.self, forKey: .path)
|
||||
let requirement = try container.decode(CarthageDependencies.Requirement.self, forKey: .requirement)
|
||||
self = .git(path: path, requirement: requirement)
|
||||
case .binary:
|
||||
let path = try container.decode(String.self, forKey: .path)
|
||||
let requirement = try container.decode(CarthageDependencies.Requirement.self, forKey: .requirement)
|
||||
self = .binary(path: path, requirement: requirement)
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
switch self {
|
||||
case let .carthage(origin, requirement, platforms):
|
||||
try container.encode(Kind.carthage, forKey: .kind)
|
||||
try container.encode(origin, forKey: .origin)
|
||||
case let .github(path, requirement):
|
||||
try container.encode(Kind.github, forKey: .kind)
|
||||
try container.encode(path, forKey: .path)
|
||||
try container.encode(requirement, forKey: .requirement)
|
||||
case let .git(path, requirement):
|
||||
try container.encode(Kind.git, forKey: .kind)
|
||||
try container.encode(path, forKey: .path)
|
||||
try container.encode(requirement, forKey: .requirement)
|
||||
case let .binary(path, requirement):
|
||||
try container.encode(Kind.binary, forKey: .kind)
|
||||
try container.encode(path, forKey: .path)
|
||||
try container.encode(requirement, forKey: .requirement)
|
||||
try container.encode(platforms, forKey: .platforms)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Dependency.CarthageRequirement: Codable
|
||||
// MARK: - CarthageDependencies.Requirement: Codoable
|
||||
|
||||
extension Dependency.CarthageRequirement {
|
||||
extension CarthageDependencies.Requirement {
|
||||
private enum Kind: String, Codable {
|
||||
case exact
|
||||
case upToNext
|
||||
|
@ -129,49 +173,3 @@ extension Dependency.CarthageRequirement {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Dependency.CarthageOrigin: Codable
|
||||
|
||||
extension Dependency.CarthageOrigin {
|
||||
private enum Kind: String, Codable {
|
||||
case github
|
||||
case git
|
||||
case binary
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case kind
|
||||
case path
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
let kind = try container.decode(Kind.self, forKey: .kind)
|
||||
switch kind {
|
||||
case .github:
|
||||
let path = try container.decode(String.self, forKey: .path)
|
||||
self = .github(path: path)
|
||||
case .git:
|
||||
let path = try container.decode(String.self, forKey: .path)
|
||||
self = .git(path: path)
|
||||
case .binary:
|
||||
let path = try container.decode(String.self, forKey: .path)
|
||||
self = .binary(path: path)
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
switch self {
|
||||
case let .github(path):
|
||||
try container.encode(Kind.github, forKey: .kind)
|
||||
try container.encode(path, forKey: .path)
|
||||
case let .git(path):
|
||||
try container.encode(Kind.git, forKey: .kind)
|
||||
try container.encode(path, forKey: .path)
|
||||
case let .binary(path):
|
||||
try container.encode(Kind.binary, forKey: .kind)
|
||||
try container.encode(path, forKey: .path)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import Foundation
|
||||
|
||||
/// A `Dependencies` manifest allows for defining external dependencies for Tuist.
|
||||
public struct Dependencies: Codable, Equatable {
|
||||
/// The description of dependency that can be installed using Carthage.
|
||||
public let carthage: CarthageDependencies?
|
||||
|
||||
/// Initializes a new `Dependencies` manifest instance.
|
||||
/// - Parameter carthage: The description of dependencies that can be installed using Carthage. Pass `nil` if you don't have dependencies from Carthage.
|
||||
public init(carthage: CarthageDependencies? = nil) {
|
||||
self.carthage = carthage
|
||||
dumpIfNeeded(self)
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ import Foundation
|
|||
|
||||
// MARK: - Platform
|
||||
|
||||
public enum Platform: String, Codable, Equatable {
|
||||
public enum Platform: String, Codable, Equatable, CaseIterable {
|
||||
case iOS = "ios"
|
||||
case macOS = "macos"
|
||||
case watchOS = "watchos"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import RxBlocking
|
||||
import TSCBasic
|
||||
import TSCUtility
|
||||
import TuistCore
|
||||
import TuistGraph
|
||||
import TuistSupport
|
||||
|
@ -13,11 +14,16 @@ enum CarthageInteractorError: FatalError, Equatable {
|
|||
case cartfileNotFound
|
||||
/// Thrown when `Carthage/Build` directory cannont be found in temporary directory after Carthage installation.
|
||||
case buildDirectoryNotFound
|
||||
/// Thrown when version of Carthage installed in environment does not support XCFrameworks production.
|
||||
case xcFrameworksProductionNotSupported
|
||||
|
||||
/// Error type.
|
||||
var type: ErrorType {
|
||||
switch self {
|
||||
case .carthageNotFound, .cartfileNotFound, .buildDirectoryNotFound:
|
||||
case .carthageNotFound,
|
||||
.cartfileNotFound,
|
||||
.buildDirectoryNotFound,
|
||||
.xcFrameworksProductionNotSupported:
|
||||
return .abort
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +37,11 @@ enum CarthageInteractorError: FatalError, Equatable {
|
|||
return "Cartfile was not found after Carthage installation."
|
||||
case .buildDirectoryNotFound:
|
||||
return "Carthage/Build directory was not found after Carthage installation."
|
||||
case .xcFrameworksProductionNotSupported:
|
||||
return """
|
||||
The version of Carthage installed in your environment doesn't suppport production of XCFrameworks.
|
||||
Update the tool or disbale XCFrameworks in your Dependencies.swift manifest.
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,38 +53,34 @@ public protocol CarthageInteracting {
|
|||
/// - Parameter dependenciesDirectory: The path to the directory that contains the `Tuist/Dependencies/` directory.
|
||||
/// - Parameter method: Installation method.
|
||||
/// - Parameter dependencies: List of dependencies to intall using `Carthage`.
|
||||
func fetch(dependenciesDirectory: AbsolutePath, dependencies: [CarthageDependency]) throws
|
||||
func fetch(dependenciesDirectory: AbsolutePath, dependencies: CarthageDependencies) throws
|
||||
}
|
||||
|
||||
// MARK: - Carthage Interactor
|
||||
|
||||
public final class CarthageInteractor: CarthageInteracting {
|
||||
private let fileHandler: FileHandling
|
||||
private let carthageController: CarthageControlling
|
||||
private let carthageCommandGenerator: CarthageCommandGenerating
|
||||
private let cartfileContentGenerator: CartfileContentGenerating
|
||||
|
||||
public init(
|
||||
fileHandler: FileHandling = FileHandler.shared,
|
||||
carthageCommandGenerator: CarthageCommandGenerating = CarthageCommandGenerator(),
|
||||
cartfileContentGenerator: CartfileContentGenerating = CartfileContentGenerator()
|
||||
carthageController: CarthageControlling = CarthageController.shared,
|
||||
carthageCommandGenerator: CarthageCommandGenerating = CarthageCommandGenerator()
|
||||
) {
|
||||
self.fileHandler = fileHandler
|
||||
self.carthageController = carthageController
|
||||
self.carthageCommandGenerator = carthageCommandGenerator
|
||||
self.cartfileContentGenerator = cartfileContentGenerator
|
||||
}
|
||||
|
||||
public func fetch(dependenciesDirectory: AbsolutePath, dependencies: [CarthageDependency]) throws {
|
||||
public func fetch(dependenciesDirectory: AbsolutePath, dependencies: CarthageDependencies) throws {
|
||||
logger.info("We are starting to fetch the Carthage dependencies.", metadata: .section)
|
||||
|
||||
// check availability of `carthage`
|
||||
guard canUseSystemCarthage() else {
|
||||
guard carthageController.canUseSystemCarthage() else {
|
||||
throw CarthageInteractorError.carthageNotFound
|
||||
}
|
||||
|
||||
// determine platforms
|
||||
let platforms: Set<Platform> = dependencies
|
||||
.reduce(Set<Platform>()) { platforms, dependency in platforms.union(dependency.platforms) }
|
||||
|
||||
try fileHandler.inTemporaryDirectory { temporaryDirectoryPath in
|
||||
// prepare paths
|
||||
let pathsProvider = CarthagePathsProvider(dependenciesDirectory: dependenciesDirectory, temporaryDirectoryPath: temporaryDirectoryPath)
|
||||
|
@ -82,30 +89,43 @@ public final class CarthageInteractor: CarthageInteracting {
|
|||
try prepareForInstallation(pathsProvider: pathsProvider, dependencies: dependencies)
|
||||
|
||||
// create `carthage` shell command
|
||||
let command = carthageCommandGenerator.command(path: temporaryDirectoryPath, platforms: platforms)
|
||||
let command = carthageCommandGenerator.command(
|
||||
path: temporaryDirectoryPath,
|
||||
produceXCFrameworks: try shouldProduceXCFrameworks(dependencies: dependencies),
|
||||
platforms: dependencies.platforms
|
||||
)
|
||||
|
||||
// log
|
||||
logger.info("Command:", metadata: .subsection)
|
||||
logger.info("\(command.joined(separator: " "))")
|
||||
|
||||
// run `carthage`
|
||||
logger.info("Carthage:", metadata: .subsection)
|
||||
try System.shared.runAndPrint(command)
|
||||
|
||||
// post intallation actions
|
||||
try postInstallationActions(pathsProvider: pathsProvider)
|
||||
}
|
||||
|
||||
logger.info("Carthage dependencies were fetched successfully.", metadata: .success)
|
||||
logger.info("Carthage dependencies were fetched successfully.", metadata: .subsection)
|
||||
}
|
||||
|
||||
// MARK: - Installation
|
||||
|
||||
private func prepareForInstallation(pathsProvider: CarthagePathsProvider, dependencies: [CarthageDependency]) throws {
|
||||
private func prepareForInstallation(pathsProvider: CarthagePathsProvider, dependencies: CarthageDependencies) throws {
|
||||
// copy build directory from previous run if exist
|
||||
if fileHandler.exists(pathsProvider.destinationCarthageDirectory) {
|
||||
try copyDirectory(from: pathsProvider.destinationCarthageDirectory, to: pathsProvider.temporaryCarthageBuildDirectory)
|
||||
}
|
||||
|
||||
// create `Cartfile`
|
||||
let cartfileContent = cartfileContentGenerator.cartfileContent(for: dependencies)
|
||||
let cartfileContent = dependencies.cartfileValue()
|
||||
let cartfilePath = pathsProvider.temporaryDirectoryPath.appending(component: "Cartfile")
|
||||
try fileHandler.write(cartfileContent, path: cartfilePath, atomically: true)
|
||||
|
||||
// log
|
||||
logger.info("Cartfile:", metadata: .subsection)
|
||||
logger.info("\(cartfileContent)")
|
||||
}
|
||||
|
||||
private func postInstallationActions(pathsProvider: CarthagePathsProvider) throws {
|
||||
|
@ -125,6 +145,17 @@ public final class CarthageInteractor: CarthageInteracting {
|
|||
|
||||
// MARK: - Helpers
|
||||
|
||||
private func shouldProduceXCFrameworks(dependencies: CarthageDependencies) throws -> Bool {
|
||||
guard dependencies.useXCFrameworks else {
|
||||
return false
|
||||
}
|
||||
guard try carthageController.isXCFrameworksProductionSupported() else {
|
||||
throw CarthageInteractorError.xcFrameworksProductionNotSupported
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private func copyFile(from fromPath: AbsolutePath, to toPath: AbsolutePath) throws {
|
||||
try fileHandler.createFolder(toPath.removingLastComponent())
|
||||
|
||||
|
@ -144,17 +175,6 @@ public final class CarthageInteractor: CarthageInteracting {
|
|||
|
||||
try fileHandler.copy(from: fromPath, to: toPath)
|
||||
}
|
||||
|
||||
/// Returns true if Carthage is avaiable in the environment.
|
||||
/// - Returns: True if Carthege is available globally in the system.
|
||||
private func canUseSystemCarthage() -> Bool {
|
||||
do {
|
||||
_ = try System.shared.which("carthage")
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Models
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
import TSCBasic
|
||||
import TuistCore
|
||||
import TuistGraph
|
||||
import TuistSupport
|
||||
|
||||
// MARK: - Cartfile Content Generating
|
||||
|
||||
public protocol CartfileContentGenerating {
|
||||
/// Generates content for `Cartfile`.
|
||||
/// - Parameter dependencies: The dependencies whose will be installed.
|
||||
func cartfileContent(for dependencies: [CarthageDependency]) -> String
|
||||
}
|
||||
|
||||
// MARK: - Cartfile Content Generator
|
||||
|
||||
public final class CartfileContentGenerator: CartfileContentGenerating {
|
||||
public init() {}
|
||||
|
||||
public func cartfileContent(for dependencies: [CarthageDependency]) -> String {
|
||||
dependencies
|
||||
.map(\.cartfileValue)
|
||||
.joined(separator: "\n")
|
||||
}
|
||||
}
|
|
@ -9,8 +9,9 @@ public protocol CarthageCommandGenerating {
|
|||
/// Builds `Carthage` command.
|
||||
/// - Parameters:
|
||||
/// - path: Directory whose project's dependencies will be installed.
|
||||
/// - produceXCFrameworks: Indicates whether `Carthage` produces XCFrameworks instead of regular frameworks.
|
||||
/// - platforms: The platforms to build for.
|
||||
func command(path: AbsolutePath, platforms: Set<Platform>?) -> [String]
|
||||
func command(path: AbsolutePath, produceXCFrameworks: Bool, platforms: Set<Platform>?) -> [String]
|
||||
}
|
||||
|
||||
// MARK: - Carthage Command Generator
|
||||
|
@ -18,7 +19,7 @@ public protocol CarthageCommandGenerating {
|
|||
public final class CarthageCommandGenerator: CarthageCommandGenerating {
|
||||
public init() {}
|
||||
|
||||
public func command(path: AbsolutePath, platforms: Set<Platform>?) -> [String] {
|
||||
public func command(path: AbsolutePath, produceXCFrameworks: Bool, platforms: Set<Platform>?) -> [String] {
|
||||
var commandComponents: [String] = []
|
||||
commandComponents.append("carthage")
|
||||
commandComponents.append("bootstrap")
|
||||
|
@ -35,6 +36,7 @@ public final class CarthageCommandGenerator: CarthageCommandGenerating {
|
|||
commandComponents.append(
|
||||
platforms
|
||||
.map(\.caseValue)
|
||||
.sorted()
|
||||
.joined(separator: ",")
|
||||
)
|
||||
}
|
||||
|
@ -45,6 +47,10 @@ public final class CarthageCommandGenerator: CarthageCommandGenerating {
|
|||
commandComponents.append("--cache-builds")
|
||||
commandComponents.append("--new-resolver")
|
||||
|
||||
if produceXCFrameworks {
|
||||
commandComponents.append("--use-xcframeworks")
|
||||
}
|
||||
|
||||
// Return
|
||||
|
||||
return commandComponents
|
||||
|
|
|
@ -39,6 +39,8 @@ public final class DependenciesController: DependenciesControlling {
|
|||
.appending(component: Constants.tuistDirectoryName)
|
||||
.appending(component: Constants.DependenciesDirectory.name)
|
||||
|
||||
try carthageInteractor.fetch(dependenciesDirectory: dependenciesDirectory, dependencies: dependencies.carthageDependencies)
|
||||
if let depedencies = dependencies.carthage {
|
||||
try carthageInteractor.fetch(dependenciesDirectory: dependenciesDirectory, dependencies: depedencies)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
import TSCBasic
|
||||
import TuistGraph
|
||||
|
||||
@testable import TuistDependencies
|
||||
|
||||
public final class MockCartfileContentGenerator: CartfileContentGenerating {
|
||||
public init() {}
|
||||
|
||||
var invokedCartfileContent = false
|
||||
var invokedCartfileContentCount = 0
|
||||
var invokedCartfileContentParameters: [CarthageDependency]?
|
||||
var invokedCartfileContentParametersList = [[CarthageDependency]]()
|
||||
var cartfileContentStub: (([CarthageDependency]) -> String)?
|
||||
|
||||
public func cartfileContent(for dependencies: [CarthageDependency]) -> String {
|
||||
invokedCartfileContent = true
|
||||
invokedCartfileContentCount += 1
|
||||
invokedCartfileContentParameters = dependencies
|
||||
invokedCartfileContentParametersList.append(dependencies)
|
||||
if let stub = cartfileContentStub {
|
||||
return stub(dependencies)
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,17 +8,17 @@ public final class MockCarthageCommandGenerator: CarthageCommandGenerating {
|
|||
|
||||
var invokedCommand = false
|
||||
var invokedCommandCount = 0
|
||||
var invokedCommandParameters: (path: AbsolutePath, platforms: Set<Platform>?)?
|
||||
var invokedCommandParametersList = [(path: AbsolutePath, platforms: Set<Platform>?)]()
|
||||
var commandStub: ((AbsolutePath, Set<Platform>?) -> [String])?
|
||||
var invokedCommandParameters: (path: AbsolutePath, produceXCFrameworks: Bool, platforms: Set<Platform>?)?
|
||||
var invokedCommandParametersList = [(path: AbsolutePath, produceXCFrameworks: Bool, platforms: Set<Platform>?)]()
|
||||
var commandStub: ((AbsolutePath, Bool, Set<Platform>?) -> [String])?
|
||||
|
||||
public func command(path: AbsolutePath, platforms: Set<Platform>?) -> [String] {
|
||||
public func command(path: AbsolutePath, produceXCFrameworks: Bool, platforms: Set<Platform>?) -> [String] {
|
||||
invokedCommand = true
|
||||
invokedCommandCount += 1
|
||||
invokedCommandParameters = (path, platforms)
|
||||
invokedCommandParametersList.append((path, platforms))
|
||||
invokedCommandParameters = (path, produceXCFrameworks, platforms)
|
||||
invokedCommandParametersList.append((path, produceXCFrameworks, platforms))
|
||||
if let stub = commandStub {
|
||||
return stub(path, platforms)
|
||||
return stub(path, produceXCFrameworks, platforms)
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
|
|
|
@ -8,11 +8,11 @@ public final class MockCarthageInteractor: CarthageInteracting {
|
|||
|
||||
var invokedFetch = false
|
||||
var invokedFetchCount = 0
|
||||
var invokedFetchParameters: (dependenciesDirectory: AbsolutePath, dependencies: [CarthageDependency])?
|
||||
var invokedFetchParametersList = [(dependenciesDirectory: AbsolutePath, dependencies: [CarthageDependency])]()
|
||||
var invokedFetchParameters: (dependenciesDirectory: AbsolutePath, dependencies: CarthageDependencies)?
|
||||
var invokedFetchParametersList = [(dependenciesDirectory: AbsolutePath, dependencies: CarthageDependencies)]()
|
||||
var stubbedFetchError: Error?
|
||||
|
||||
public func fetch(dependenciesDirectory: AbsolutePath, dependencies: [CarthageDependency]) throws {
|
||||
public func fetch(dependenciesDirectory: AbsolutePath, dependencies: CarthageDependencies) throws {
|
||||
invokedFetch = true
|
||||
invokedFetchCount += 1
|
||||
invokedFetchParameters = (dependenciesDirectory, dependencies)
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import Foundation
|
||||
|
||||
/// Contains descriptions of dependencies to be fetched with Carthage.
|
||||
public struct CarthageDependencies: Equatable {
|
||||
/// List of depedencies that can be installed using Carthage.
|
||||
public let dependencies: [Dependency]
|
||||
/// List of platforms for which you want to install depedencies.
|
||||
public let platforms: Set<Platform>
|
||||
/// Indicates whether Carthage produces XCFrameworks or regular frameworks.
|
||||
public let useXCFrameworks: Bool
|
||||
|
||||
/// Initializes the carthage dependency with its attributes.
|
||||
public init(_ dependencies: [Dependency], platforms: Set<Platform>, useXCFrameworks: Bool) {
|
||||
self.dependencies = dependencies
|
||||
self.platforms = platforms
|
||||
self.useXCFrameworks = useXCFrameworks
|
||||
}
|
||||
|
||||
/// Returns `Cartfile` representation.
|
||||
public func cartfileValue() -> String {
|
||||
dependencies
|
||||
.map(\.cartfileValue)
|
||||
.joined(separator: "\n")
|
||||
}
|
||||
}
|
||||
|
||||
public extension CarthageDependencies {
|
||||
enum Dependency: Equatable {
|
||||
case github(path: String, requirement: Requirement)
|
||||
case git(path: String, requirement: Requirement)
|
||||
case binary(path: String, requirement: Requirement)
|
||||
|
||||
/// Returns `Cartfile` representation.
|
||||
public var cartfileValue: String {
|
||||
switch self {
|
||||
case let .github(path, requirement):
|
||||
return #"github "\#(path)" \#(requirement.cartfileValue)"#
|
||||
case let .git(path, requirement):
|
||||
return #"git "\#(path)" \#(requirement.cartfileValue)"#
|
||||
case let .binary(path, requirement):
|
||||
return #"binary "\#(path)" \#(requirement.cartfileValue)"#
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Requirement: Equatable {
|
||||
case exact(String)
|
||||
case upToNext(String)
|
||||
case atLeast(String)
|
||||
case branch(String)
|
||||
case revision(String)
|
||||
|
||||
/// Returns `Cartfile` representation.
|
||||
public var cartfileValue: String {
|
||||
switch self {
|
||||
case let .exact(version):
|
||||
return "== \(version)"
|
||||
case let .upToNext(version):
|
||||
return "~> \(version)"
|
||||
case let .atLeast(version):
|
||||
return ">= \(version)"
|
||||
case let .branch(branch):
|
||||
return #""\#(branch)""#
|
||||
case let .revision(revision):
|
||||
return #""\#(revision)""#
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
import Foundation
|
||||
|
||||
// MARK: - Carthage Dependency
|
||||
|
||||
/// CarthageDependency contains the description of a dependency to be fetched with Carthage.
|
||||
public struct CarthageDependency: Equatable {
|
||||
/// Origin of the dependency
|
||||
public let origin: Origin
|
||||
|
||||
/// Type of requirement for the given dependency
|
||||
public let requirement: Requirement
|
||||
|
||||
/// Set of platforms for the given dependency
|
||||
public let platforms: Set<Platform>
|
||||
|
||||
/// Initializes the carthage dependency with its attributes.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - origin: Origin of the dependency
|
||||
/// - requirement: Type of requirement for the given dependency
|
||||
/// - platforms: Set of platforms for the given dependency
|
||||
public init(
|
||||
origin: Origin,
|
||||
requirement: Requirement,
|
||||
platforms: Set<Platform>
|
||||
) {
|
||||
self.origin = origin
|
||||
self.requirement = requirement
|
||||
self.platforms = platforms
|
||||
}
|
||||
|
||||
/// Returns `Cartfile` representation.
|
||||
public var cartfileValue: String {
|
||||
origin.cartfileValue + " " + requirement.cartfileValue
|
||||
}
|
||||
}
|
||||
|
||||
public extension CarthageDependency {
|
||||
enum Origin: Equatable {
|
||||
case github(path: String)
|
||||
case git(path: String)
|
||||
case binary(path: String)
|
||||
|
||||
/// Returns `Cartfile` representation.
|
||||
public var cartfileValue: String {
|
||||
switch self {
|
||||
case let .github(path):
|
||||
return #"github "\#(path)""#
|
||||
case let .git(path):
|
||||
return #"git "\#(path)""#
|
||||
case let .binary(path):
|
||||
return #"binary "\#(path)""#
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Requirement
|
||||
|
||||
public extension CarthageDependency {
|
||||
enum Requirement: Equatable {
|
||||
case exact(String)
|
||||
case upToNext(String)
|
||||
case atLeast(String)
|
||||
case branch(String)
|
||||
case revision(String)
|
||||
|
||||
/// Returns `Cartfile` representation.
|
||||
public var cartfileValue: String {
|
||||
switch self {
|
||||
case let .exact(version):
|
||||
return "== \(version)"
|
||||
case let .upToNext(version):
|
||||
return "~> \(version)"
|
||||
case let .atLeast(version):
|
||||
return ">= \(version)"
|
||||
case let .branch(branch):
|
||||
return #""\#(branch)""#
|
||||
case let .revision(revision):
|
||||
return #""\#(revision)""#
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
import Foundation
|
||||
|
||||
public struct Dependencies: Equatable {
|
||||
public let carthageDependencies: [CarthageDependency]
|
||||
public let carthage: CarthageDependencies?
|
||||
|
||||
public init(
|
||||
carthageDependencies: [CarthageDependency]
|
||||
) {
|
||||
self.carthageDependencies = carthageDependencies
|
||||
public init(carthage: CarthageDependencies?) {
|
||||
self.carthage = carthage
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ final class DependenciesFetchService {
|
|||
}
|
||||
|
||||
func run(path: String?) throws {
|
||||
logger.info("We are starting to fetch/update the dependencies.", metadata: .section)
|
||||
logger.info("We are starting to fetch the dependencies.", metadata: .section)
|
||||
|
||||
let path = self.path(path)
|
||||
let dependencies = try dependenciesModelLoader.loadDependencies(at: path)
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import Foundation
|
||||
import ProjectDescription
|
||||
import TSCBasic
|
||||
import TuistCore
|
||||
import TuistGraph
|
||||
import TuistSupport
|
||||
|
||||
extension TuistGraph.CarthageDependencies {
|
||||
/// Creates `TuistGraph.CarthageDependencies` instance from `ProjectDescription.CarthageDependencies` instance.
|
||||
static func from(manifest: ProjectDescription.CarthageDependencies) throws -> Self {
|
||||
let dependencies = manifest.dependencies.map { TuistGraph.CarthageDependencies.Dependency.from(manifest: $0) }
|
||||
let platforms = try manifest.platforms.map { try TuistGraph.Platform.from(manifest: $0) }
|
||||
return .init(dependencies, platforms: Set(platforms), useXCFrameworks: manifest.useXCFrameworks)
|
||||
}
|
||||
}
|
||||
|
||||
extension TuistGraph.CarthageDependencies.Dependency {
|
||||
/// Creates `TuistGraph.CarthageDependencies.Dependency` instance from `ProjectDescription.CarthageDependencies.Dependency` instance.
|
||||
static func from(manifest: ProjectDescription.CarthageDependencies.Dependency) -> Self {
|
||||
switch manifest {
|
||||
case let .github(path, requirement):
|
||||
return .github(path: path, requirement: .from(manifest: requirement))
|
||||
case let .git(path, requirement):
|
||||
return .git(path: path, requirement: .from(manifest: requirement))
|
||||
case let .binary(path, requirement):
|
||||
return .binary(path: path, requirement: .from(manifest: requirement))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension TuistGraph.CarthageDependencies.Requirement {
|
||||
/// Creates `TuistGraph.CarthageDependencies.Requirement` instance from `ProjectDescription.CarthageDependencies.Requirement` instance.
|
||||
static func from(manifest: ProjectDescription.CarthageDependencies.Requirement) -> Self {
|
||||
switch manifest {
|
||||
case let .exact(version):
|
||||
return .exact(version.description)
|
||||
case let .upToNext(version):
|
||||
return .upToNext(version.description)
|
||||
case let .atLeast(version):
|
||||
return .atLeast(version.description)
|
||||
case let .branch(branch):
|
||||
return .branch(branch)
|
||||
case let .revision(revision):
|
||||
return .revision(revision)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
import Foundation
|
||||
import ProjectDescription
|
||||
import TSCBasic
|
||||
import TuistCore
|
||||
import TuistGraph
|
||||
import TuistSupport
|
||||
|
||||
extension TuistGraph.CarthageDependency.Origin {
|
||||
static func from(manifest: ProjectDescription.Dependency.CarthageOrigin) throws -> Self {
|
||||
switch manifest {
|
||||
case let .github(path):
|
||||
return .github(path: path)
|
||||
case let .git(path):
|
||||
return .git(path: path)
|
||||
case let .binary(path):
|
||||
return .binary(path: path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension TuistGraph.CarthageDependency.Requirement {
|
||||
static func from(manifest: ProjectDescription.Dependency.CarthageRequirement) throws -> Self {
|
||||
switch manifest {
|
||||
case let .exact(version):
|
||||
return .exact(version.description)
|
||||
case let .upToNext(version):
|
||||
return .upToNext(version.description)
|
||||
case let .atLeast(version):
|
||||
return .atLeast(version.description)
|
||||
case let .branch(branch):
|
||||
return .branch(branch)
|
||||
case let .revision(revision):
|
||||
return .revision(revision)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,16 +7,13 @@ import TuistSupport
|
|||
|
||||
extension TuistGraph.Dependencies {
|
||||
static func from(manifest: ProjectDescription.Dependencies) throws -> Self {
|
||||
let carthageDependencies = try manifest.dependencies.reduce(into: [CarthageDependency]()) { result, dependency in
|
||||
switch dependency {
|
||||
case let .carthage(origin, requirement, platforms):
|
||||
let origin = try TuistGraph.CarthageDependency.Origin.from(manifest: origin)
|
||||
let requirement = try TuistGraph.CarthageDependency.Requirement.from(manifest: requirement)
|
||||
let platforms = try platforms.map { try TuistGraph.Platform.from(manifest: $0) }
|
||||
result.append(CarthageDependency(origin: origin, requirement: requirement, platforms: Set(platforms)))
|
||||
let carthage: TuistGraph.CarthageDependencies? = try {
|
||||
guard let carthage = manifest.carthage else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return try TuistGraph.CarthageDependencies.from(manifest: carthage)
|
||||
}()
|
||||
|
||||
return Self(carthageDependencies: carthageDependencies)
|
||||
return Self(carthage: carthage)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public class MockDependenciesModelLoader: DependenciesModelLoading {
|
|||
if let stub = loadDependenciesStub {
|
||||
return try stub(path)
|
||||
} else {
|
||||
return Dependencies(carthageDependencies: [])
|
||||
return Dependencies(carthage: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,8 +163,8 @@ extension Arguments {
|
|||
}
|
||||
|
||||
extension Dependencies {
|
||||
public static func test(dependencies: [Dependency] = []) -> Dependencies {
|
||||
Dependencies(dependencies)
|
||||
public static func test(carthageDependencies: CarthageDependencies? = nil) -> Dependencies {
|
||||
Dependencies(carthage: carthageDependencies)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
import Foundation
|
||||
import TSCBasic
|
||||
import TSCUtility
|
||||
|
||||
// MARK: - Carthage Controller Error
|
||||
|
||||
enum CarthageControllerError: FatalError, Equatable {
|
||||
/// Thrown when Carthage cannot be found in the environment.
|
||||
case carthageNotFound
|
||||
/// Thrown when version of Carthage cannot be determined.
|
||||
case unrecognizedCarthageVersion
|
||||
|
||||
/// Error type.
|
||||
var type: ErrorType {
|
||||
switch self {
|
||||
case .carthageNotFound,
|
||||
.unrecognizedCarthageVersion:
|
||||
return .abort
|
||||
}
|
||||
}
|
||||
|
||||
/// Error description.
|
||||
var description: String {
|
||||
switch self {
|
||||
case .carthageNotFound:
|
||||
return "Carthage was not found in the environment. It's possible that the tool is not installed or hasn't been exposed to your environment."
|
||||
case .unrecognizedCarthageVersion:
|
||||
return "Version of Carthage cannot be determined. It's possible that the tool is not installed or hasn't been exposed to your environment."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Carthage Controlling
|
||||
|
||||
/// Controls `Carthage` that can be found in the environment.
|
||||
public protocol CarthageControlling {
|
||||
/// Returns true if Carthage is available in the environment.
|
||||
func canUseSystemCarthage() -> Bool
|
||||
|
||||
/// Return version of Carthage that is available in the environment.
|
||||
func carthageVersion() throws -> Version
|
||||
|
||||
/// Returns true if version of Carthage available in the environment supports producing XCFrameworks.
|
||||
func isXCFrameworksProductionSupported() throws -> Bool
|
||||
}
|
||||
|
||||
// MARK: - Carthage Controller
|
||||
|
||||
public final class CarthageController: CarthageControlling {
|
||||
/// Shared instance.
|
||||
public static var shared: CarthageControlling = CarthageController()
|
||||
|
||||
/// Cached response of `carthage version` command.
|
||||
@Atomic
|
||||
private var cachedCarthageVersion: Version?
|
||||
|
||||
public func canUseSystemCarthage() -> Bool {
|
||||
do {
|
||||
_ = try System.shared.which("carthage")
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
public func carthageVersion() throws -> Version {
|
||||
// Return cached value if available
|
||||
if let cached = cachedCarthageVersion {
|
||||
return cached
|
||||
}
|
||||
|
||||
guard let output = try? System.shared.capture("/usr/bin/env", "carthage", "version").spm_chomp() else {
|
||||
throw CarthageControllerError.carthageNotFound
|
||||
}
|
||||
|
||||
guard let version = Version(string: output) else {
|
||||
throw CarthageControllerError.unrecognizedCarthageVersion
|
||||
}
|
||||
|
||||
cachedCarthageVersion = version
|
||||
return version
|
||||
}
|
||||
|
||||
public func isXCFrameworksProductionSupported() throws -> Bool {
|
||||
// Carthage has supported XCFrameworks production since 0.37.0
|
||||
// More info here: https://github.com/Carthage/Carthage/releases/tag/0.37.0
|
||||
try carthageVersion() >= Version(0, 37, 0)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import Foundation
|
||||
import TSCUtility
|
||||
@testable import TuistSupport
|
||||
|
||||
public final class MockCarthageController: CarthageControlling {
|
||||
public init() {}
|
||||
|
||||
var invokedCanUseSystemCarthage = false
|
||||
var invokedCanUseSystemCarthageCount = 0
|
||||
var canUseSystemCarthageStub: (() -> Bool)?
|
||||
|
||||
public func canUseSystemCarthage() -> Bool {
|
||||
invokedCanUseSystemCarthage = true
|
||||
invokedCanUseSystemCarthageCount += 1
|
||||
if let stub = canUseSystemCarthageStub {
|
||||
return stub()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var invokedCarthageVersion = false
|
||||
var invokedCarthageVersionCount = 0
|
||||
var carthageVersionStub: (() throws -> Version)?
|
||||
|
||||
public func carthageVersion() throws -> Version {
|
||||
invokedCarthageVersion = true
|
||||
invokedCarthageVersionCount += 1
|
||||
if let stub = carthageVersionStub {
|
||||
return try stub()
|
||||
} else {
|
||||
return Version(0, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
var invokedIsXCFrameworksProductionSupported = false
|
||||
var invokedIsXCFrameworksProductionSupportedCount = 0
|
||||
var isXCFrameworksProductionSupportedStub: (() -> Bool)?
|
||||
|
||||
public func isXCFrameworksProductionSupported() throws -> Bool {
|
||||
invokedIsXCFrameworksProductionSupported = true
|
||||
invokedIsXCFrameworksProductionSupportedCount += 1
|
||||
if let stub = isXCFrameworksProductionSupportedStub {
|
||||
return stub()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
import Foundation
|
||||
import XCTest
|
||||
|
||||
@testable import ProjectDescription
|
||||
|
||||
final class CarthageDependenciesTests: XCTestCase {
|
||||
func test_carthageDependencies_codable() throws {
|
||||
let subject: CarthageDependencies = .carthage(
|
||||
[
|
||||
.github(path: "Dependency/Dependency", requirement: .revision("xyz")),
|
||||
.git(path: "Git/Git", requirement: .atLeast("1.2.3")),
|
||||
],
|
||||
platforms: [.iOS, .macOS, .tvOS, .watchOS],
|
||||
useXCFrameworks: true
|
||||
)
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
// MARK: - Carthage Origin tests
|
||||
|
||||
func test_carthageDependency_github_codable() throws {
|
||||
let subject: CarthageDependencies.Dependency = .github(path: "Path/Path", requirement: .branch("branch_name"))
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageDependency_git_codable() throws {
|
||||
let subject: CarthageDependencies.Dependency = .git(path: "Git/Git", requirement: .exact("1.5.123"))
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageDependency_binary_codable() throws {
|
||||
let subject: CarthageDependencies.Dependency = .binary(path: "file:///some/Path/MyFramework.json", requirement: .upToNext("5.6.9"))
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
// MARK: - Carthage Requirement tests
|
||||
|
||||
func test_carthageRequirement_exact_codable() throws {
|
||||
let subject: CarthageDependencies.Requirement = .exact("1.0.0")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageRequirement_upToNext_codable() throws {
|
||||
let subject: CarthageDependencies.Requirement = .upToNext("3.2.0")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageRequirement_atLeast_codable() throws {
|
||||
let subject: CarthageDependencies.Requirement = .atLeast("3.2.0")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageRequirement_branch_codable() throws {
|
||||
let subject: CarthageDependencies.Requirement = .branch("branch")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageRequirement_revision_codable() throws {
|
||||
let subject: CarthageDependencies.Requirement = .revision("revision")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import Foundation
|
||||
import XCTest
|
||||
|
||||
@testable import ProjectDescription
|
||||
|
||||
final class DependenciesTests: XCTestCase {
|
||||
func test_dependencies_codable() throws {
|
||||
let subject = Dependencies(
|
||||
carthage: .carthage(
|
||||
[
|
||||
.github(path: "Dependency1/Dependency1", requirement: .branch("BranchName")),
|
||||
.git(path: "Dependency2/Dependency2", requirement: .upToNext("1.2.3")),
|
||||
],
|
||||
platforms: [.iOS, .macOS],
|
||||
useXCFrameworks: true
|
||||
)
|
||||
)
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
import Foundation
|
||||
import XCTest
|
||||
|
||||
@testable import ProjectDescription
|
||||
|
||||
final class DependenciesTests: XCTestCase {
|
||||
func test_dependencies_codable() throws {
|
||||
let subject = Dependencies([
|
||||
.carthage(origin: .github(path: "Dependency1/Dependency1"), requirement: .branch("BranchName"), platforms: [.iOS]),
|
||||
.carthage(origin: .git(path: "Dependency2/Dependency2"), requirement: .upToNext("1.2.3"), platforms: [.tvOS, .macOS]),
|
||||
])
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
import Foundation
|
||||
import XCTest
|
||||
|
||||
@testable import ProjectDescription
|
||||
|
||||
final class DependencyTests: XCTestCase {
|
||||
func test_dependency_carthage_codable() throws {
|
||||
let subject: Dependency = .carthage(origin: .github(path: "Dependency/Dependency"), requirement: .revision("xyz"), platforms: [.iOS, .macOS, .tvOS, .watchOS])
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
// MARK: - Carthage Origin tests
|
||||
|
||||
func test_carthageOrigin_github_codable() throws {
|
||||
let subject: Dependency.CarthageOrigin = .github(path: "Path/Path")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageOrigin_git_codable() throws {
|
||||
let subject: Dependency.CarthageOrigin = .git(path: "Git/Git")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageOrigin_binary_codable() throws {
|
||||
let subject: Dependency.CarthageOrigin = .binary(path: "file:///some/Path/MyFramework.json")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
// MARK: - Carthage Requirement tests
|
||||
|
||||
func test_carthageRequirement_exact_codable() throws {
|
||||
let subject: Dependency.CarthageRequirement = .exact("1.0.0")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageRequirement_upToNext_codable() throws {
|
||||
let subject: Dependency.CarthageRequirement = .upToNext("3.2.0")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageRequirement_atLeast_codable() throws {
|
||||
let subject: Dependency.CarthageRequirement = .atLeast("3.2.0")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageRequirement_branch_codable() throws {
|
||||
let subject: Dependency.CarthageRequirement = .branch("branch")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
|
||||
func test_carthageRequirement_revision_codable() throws {
|
||||
let subject: Dependency.CarthageRequirement = .revision("revision")
|
||||
XCTAssertCodable(subject)
|
||||
}
|
||||
}
|
|
@ -12,8 +12,8 @@ final class CarthageInteractorTests: TuistUnitTestCase {
|
|||
private var subject: CarthageInteractor!
|
||||
|
||||
private var fileHandlerMock: MockFileHandler!
|
||||
private var carthageController: MockCarthageController!
|
||||
private var carthageCommandGenerator: MockCarthageCommandGenerator!
|
||||
private var cartfileContentGenerator: MockCartfileContentGenerator!
|
||||
|
||||
private var temporaryDirectoryPath: AbsolutePath!
|
||||
|
||||
|
@ -27,18 +27,18 @@ final class CarthageInteractorTests: TuistUnitTestCase {
|
|||
}
|
||||
|
||||
fileHandlerMock = MockFileHandler(temporaryDirectory: { self.temporaryDirectoryPath })
|
||||
carthageController = MockCarthageController()
|
||||
carthageCommandGenerator = MockCarthageCommandGenerator()
|
||||
cartfileContentGenerator = MockCartfileContentGenerator()
|
||||
|
||||
subject = CarthageInteractor(fileHandler: fileHandlerMock,
|
||||
carthageCommandGenerator: carthageCommandGenerator,
|
||||
cartfileContentGenerator: cartfileContentGenerator)
|
||||
carthageController: carthageController,
|
||||
carthageCommandGenerator: carthageCommandGenerator)
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
fileHandlerMock = nil
|
||||
carthageController = nil
|
||||
carthageCommandGenerator = nil
|
||||
cartfileContentGenerator = nil
|
||||
|
||||
temporaryDirectoryPath = nil
|
||||
|
||||
|
@ -47,8 +47,54 @@ final class CarthageInteractorTests: TuistUnitTestCase {
|
|||
super.tearDown()
|
||||
}
|
||||
|
||||
func test_fetch_all_for_platforms() throws {
|
||||
func test_fetch_throws_when_carthageUnavailableInEnvironment() throws {
|
||||
// Given
|
||||
carthageController.canUseSystemCarthageStub = { false }
|
||||
|
||||
let rootPath = try temporaryPath()
|
||||
let dependenciesDirectory = rootPath
|
||||
.appending(component: Constants.DependenciesDirectory.name)
|
||||
let dependencies = CarthageDependencies(
|
||||
[
|
||||
.github(path: "Moya", requirement: .exact("1.1.1")),
|
||||
],
|
||||
platforms: [.iOS],
|
||||
useXCFrameworks: false
|
||||
)
|
||||
|
||||
// When / Then
|
||||
XCTAssertThrowsSpecific(
|
||||
try subject.fetch(dependenciesDirectory: dependenciesDirectory, dependencies: dependencies),
|
||||
CarthageInteractorError.carthageNotFound
|
||||
)
|
||||
}
|
||||
|
||||
func test_fetch_throws_when_xcFrameworkdProductionUnsupported_and_useXCFrameworksSpecifiedInOptions() throws {
|
||||
// Given
|
||||
carthageController.canUseSystemCarthageStub = { true }
|
||||
carthageController.isXCFrameworksProductionSupportedStub = { false }
|
||||
|
||||
let rootPath = try temporaryPath()
|
||||
let dependenciesDirectory = rootPath
|
||||
.appending(component: Constants.DependenciesDirectory.name)
|
||||
let dependencies = CarthageDependencies(
|
||||
[
|
||||
.github(path: "Moya", requirement: .exact("1.1.1")),
|
||||
],
|
||||
platforms: [.iOS],
|
||||
useXCFrameworks: true
|
||||
)
|
||||
|
||||
XCTAssertThrowsSpecific(
|
||||
try subject.fetch(dependenciesDirectory: dependenciesDirectory, dependencies: dependencies),
|
||||
CarthageInteractorError.xcFrameworksProductionNotSupported
|
||||
)
|
||||
}
|
||||
|
||||
func test_fetch_allPlatforms() throws {
|
||||
// Given
|
||||
carthageController.canUseSystemCarthageStub = { true }
|
||||
|
||||
let rootPath = try temporaryPath()
|
||||
let temporaryDependenciesDirectory = temporaryDirectoryPath
|
||||
.appending(component: Constants.DependenciesDirectory.carthageDirectoryName)
|
||||
|
@ -70,12 +116,18 @@ final class CarthageInteractorTests: TuistUnitTestCase {
|
|||
try fileHandler.touch(temporaryDependenciesDirectory.appending(components: "tvOS", "ReactiveMoya.framework", "Info.plist"))
|
||||
try fileHandler.touch(temporaryDependenciesDirectory.appending(components: "tvOS", "RxMoya.framework", "Info.plist"))
|
||||
|
||||
let stubbedDependencies = [
|
||||
CarthageDependency(origin: .github(path: "Moya"), requirement: .exact("1.1.1"), platforms: [.iOS]),
|
||||
]
|
||||
let stubbedCommand = ["carthage", "bootstrap", "--project-directory", temporaryDirectoryPath.pathString, "--platform iOS", "--cache-builds", "--new-resolver"]
|
||||
let platforms = Set<Platform>([.iOS, .watchOS, .macOS, .tvOS])
|
||||
let useXCFrameworks = false
|
||||
let stubbedDependencies = CarthageDependencies(
|
||||
[
|
||||
.github(path: "Moya", requirement: .exact("1.1.1")),
|
||||
],
|
||||
platforms: platforms,
|
||||
useXCFrameworks: useXCFrameworks
|
||||
)
|
||||
let stubbedCommand = ["carthage", "bootstrap", "--project-directory", temporaryDirectoryPath.pathString, "--platform iOS,macOS,tvOS,watchOS", "--cache-builds", "--new-resolver"]
|
||||
|
||||
carthageCommandGenerator.commandStub = { _, _ in stubbedCommand }
|
||||
carthageCommandGenerator.commandStub = { _, _, _ in stubbedCommand }
|
||||
|
||||
system.whichStub = { _ in "1.0.0" }
|
||||
system.succeedCommand(stubbedCommand)
|
||||
|
@ -106,14 +158,14 @@ final class CarthageInteractorTests: TuistUnitTestCase {
|
|||
|
||||
XCTAssertTrue(carthageCommandGenerator.invokedCommand)
|
||||
XCTAssertEqual(carthageCommandGenerator.invokedCommandParameters?.path, temporaryDirectoryPath)
|
||||
XCTAssertEqual(carthageCommandGenerator.invokedCommandParameters?.platforms, [.iOS])
|
||||
|
||||
XCTAssertTrue(cartfileContentGenerator.invokedCartfileContent)
|
||||
XCTAssertEqual(cartfileContentGenerator.invokedCartfileContentParameters, stubbedDependencies)
|
||||
XCTAssertEqual(carthageCommandGenerator.invokedCommandParameters?.platforms, platforms)
|
||||
XCTAssertEqual(carthageCommandGenerator.invokedCommandParameters?.produceXCFrameworks, useXCFrameworks)
|
||||
}
|
||||
|
||||
func test_fetch_only_one_platform() throws {
|
||||
func test_fetch_onePlatform() throws {
|
||||
// Given
|
||||
carthageController.canUseSystemCarthageStub = { true }
|
||||
|
||||
let rootPath = try temporaryPath()
|
||||
let temporaryDependenciesDirectory = temporaryDirectoryPath
|
||||
.appending(component: Constants.DependenciesDirectory.carthageDirectoryName)
|
||||
|
@ -126,12 +178,18 @@ final class CarthageInteractorTests: TuistUnitTestCase {
|
|||
try fileHandler.touch(temporaryDependenciesDirectory.appending(components: "iOS", "ReactiveMoya.framework", "Info.plist"))
|
||||
try fileHandler.touch(temporaryDependenciesDirectory.appending(components: "iOS", "RxMoya.framework", "Info.plist"))
|
||||
|
||||
let stubbedDependencies = [
|
||||
CarthageDependency(origin: .github(path: "Moya"), requirement: .exact("1.1.1"), platforms: [.iOS]),
|
||||
]
|
||||
let platforms = Set<Platform>([.iOS])
|
||||
let useXCFrameworks = false
|
||||
let stubbedDependencies = CarthageDependencies(
|
||||
[
|
||||
.github(path: "Moya", requirement: .exact("1.1.1")),
|
||||
],
|
||||
platforms: platforms,
|
||||
useXCFrameworks: useXCFrameworks
|
||||
)
|
||||
let stubbedCommand = ["carthage", "bootstrap", "--project-directory", temporaryDirectoryPath.pathString, "--platform iOS", "--cache-builds", "--new-resolver"]
|
||||
|
||||
carthageCommandGenerator.commandStub = { _, _ in stubbedCommand }
|
||||
carthageCommandGenerator.commandStub = { _, _, _ in stubbedCommand }
|
||||
|
||||
system.whichStub = { _ in "1.0.0" }
|
||||
system.succeedCommand(stubbedCommand)
|
||||
|
@ -162,9 +220,7 @@ final class CarthageInteractorTests: TuistUnitTestCase {
|
|||
|
||||
XCTAssertTrue(carthageCommandGenerator.invokedCommand)
|
||||
XCTAssertEqual(carthageCommandGenerator.invokedCommandParameters?.path, temporaryDirectoryPath)
|
||||
XCTAssertEqual(carthageCommandGenerator.invokedCommandParameters?.platforms, [.iOS])
|
||||
|
||||
XCTAssertTrue(cartfileContentGenerator.invokedCartfileContent)
|
||||
XCTAssertEqual(cartfileContentGenerator.invokedCartfileContentParameters, stubbedDependencies)
|
||||
XCTAssertEqual(carthageCommandGenerator.invokedCommandParameters?.platforms, platforms)
|
||||
XCTAssertEqual(carthageCommandGenerator.invokedCommandParameters?.produceXCFrameworks, useXCFrameworks)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
import TuistCore
|
||||
import TuistGraph
|
||||
import TuistSupport
|
||||
import XCTest
|
||||
@testable import TuistDependencies
|
||||
@testable import TuistSupportTesting
|
||||
|
||||
final class CartfileContentGenetatorTests: TuistUnitTestCase {
|
||||
private var subject: CartfileContentGenerator!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
subject = CartfileContentGenerator()
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
subject = nil
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func test_build_no_dependencies() throws {
|
||||
// Given
|
||||
let dependencies: [CarthageDependency] = []
|
||||
let expected = """
|
||||
"""
|
||||
|
||||
// When
|
||||
let got = subject.cartfileContent(for: dependencies)
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_build_single_dependency() throws {
|
||||
// Given
|
||||
let dependencies: [CarthageDependency] = [
|
||||
.init(origin: .github(path: "Dependency/Dependency"), requirement: .exact("1.1.1"), platforms: [.iOS]),
|
||||
]
|
||||
let expected = """
|
||||
github "Dependency/Dependency" == 1.1.1
|
||||
"""
|
||||
|
||||
// When
|
||||
let got = subject.cartfileContent(for: dependencies)
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_build_multiple_dependencies() throws {
|
||||
// Given
|
||||
let dependencies: [CarthageDependency] = [
|
||||
.init(origin: .github(path: "Dependency/Dependency"), requirement: .exact("2.1.1"), platforms: [.iOS]),
|
||||
.init(origin: .github(path: "XYZ/Foo"), requirement: .revision("revision"), platforms: [.tvOS, .macOS]),
|
||||
.init(origin: .git(path: "Foo/Bar"), requirement: .atLeast("1.0.1"), platforms: [.iOS]),
|
||||
.init(origin: .github(path: "Qwerty/bar"), requirement: .branch("develop"), platforms: [.watchOS]),
|
||||
.init(origin: .github(path: "XYZ/Bar"), requirement: .upToNext("1.1.1"), platforms: [.iOS]),
|
||||
.init(origin: .binary(path: "https://my.domain.com/release/MyFramework.json"), requirement: .upToNext("1.0.1"), platforms: [.iOS]),
|
||||
.init(origin: .binary(path: "file:///some/local/path/MyFramework.json"), requirement: .atLeast("1.1.0"), platforms: [.iOS]),
|
||||
]
|
||||
let expected = """
|
||||
github "Dependency/Dependency" == 2.1.1
|
||||
github "XYZ/Foo" "revision"
|
||||
git "Foo/Bar" >= 1.0.1
|
||||
github "Qwerty/bar" "develop"
|
||||
github "XYZ/Bar" ~> 1.1.1
|
||||
binary "https://my.domain.com/release/MyFramework.json" ~> 1.0.1
|
||||
binary "file:///some/local/path/MyFramework.json" >= 1.1.0
|
||||
"""
|
||||
|
||||
// When
|
||||
let got = subject.cartfileContent(for: dependencies)
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ final class CarthageCommandGeneratorTests: TuistUnitTestCase {
|
|||
|
||||
// When
|
||||
let got = subject
|
||||
.command(path: stubbedPath, platforms: nil)
|
||||
.command(path: stubbedPath, produceXCFrameworks: false, platforms: nil)
|
||||
.joined(separator: " ")
|
||||
|
||||
// Then
|
||||
|
@ -39,7 +39,21 @@ final class CarthageCommandGeneratorTests: TuistUnitTestCase {
|
|||
|
||||
// When
|
||||
let got = subject
|
||||
.command(path: stubbedPath, platforms: [.iOS])
|
||||
.command(path: stubbedPath, produceXCFrameworks: false, platforms: [.iOS])
|
||||
.joined(separator: " ")
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_command_with_platforms_and_xcframeworks() throws {
|
||||
// Given
|
||||
let stubbedPath = try temporaryPath()
|
||||
let expected = "carthage bootstrap --project-directory \(stubbedPath.pathString) --platform iOS,macOS,tvOS,watchOS --use-netrc --cache-builds --new-resolver --use-xcframeworks"
|
||||
|
||||
// When
|
||||
let got = subject
|
||||
.command(path: stubbedPath, produceXCFrameworks: true, platforms: [.iOS, .tvOS, .macOS, .watchOS])
|
||||
.joined(separator: " ")
|
||||
|
||||
// Then
|
||||
|
|
|
@ -43,11 +43,15 @@ final class DependenciesControllerTests: TuistUnitTestCase {
|
|||
.appending(component: Constants.tuistDirectoryName)
|
||||
.appending(component: Constants.DependenciesDirectory.name)
|
||||
|
||||
let stubbedCarthageDependencies = [
|
||||
CarthageDependency(origin: .github(path: "Moya"), requirement: .exact("1.1.1"), platforms: [.iOS]),
|
||||
CarthageDependency(origin: .github(path: "RxSwift"), requirement: .exact("2.0.0"), platforms: [.iOS]),
|
||||
]
|
||||
let stubbedDependencies = Dependencies(carthageDependencies: stubbedCarthageDependencies)
|
||||
let stubbedCarthageDependencies = CarthageDependencies(
|
||||
[
|
||||
.github(path: "Moya", requirement: .exact("1.1.1")),
|
||||
.github(path: "RxSwift", requirement: .exact("2.0.0")),
|
||||
],
|
||||
platforms: [.iOS],
|
||||
useXCFrameworks: true
|
||||
)
|
||||
let stubbedDependencies = Dependencies(carthage: stubbedCarthageDependencies)
|
||||
|
||||
// When
|
||||
try subject.fetch(at: rootPath, dependencies: stubbedDependencies)
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
import Foundation
|
||||
import XCTest
|
||||
@testable import TuistGraph
|
||||
@testable import TuistSupportTesting
|
||||
|
||||
final class CarthageDependenciesTests: TuistUnitTestCase {
|
||||
func test_cartfileValue_singleDependency() {
|
||||
// Given
|
||||
let carthageDependencies: CarthageDependencies = .init(
|
||||
[
|
||||
.github(path: "Dependency/Dependency", requirement: .exact("1.1.1")),
|
||||
],
|
||||
platforms: [.iOS],
|
||||
useXCFrameworks: false
|
||||
)
|
||||
let expected = """
|
||||
github "Dependency/Dependency" == 1.1.1
|
||||
"""
|
||||
|
||||
// When
|
||||
let got = carthageDependencies.cartfileValue()
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_cartfileValue_multipleDependencies() {
|
||||
// Given
|
||||
let carthageDependencies: CarthageDependencies = .init(
|
||||
[
|
||||
.github(path: "Dependency/Dependency", requirement: .exact("2.1.1")),
|
||||
.github(path: "XYZ/Foo", requirement: .revision("revision")),
|
||||
.git(path: "Foo/Bar", requirement: .atLeast("1.0.1")),
|
||||
.github(path: "Qwerty/bar", requirement: .branch("develop")),
|
||||
.github(path: "XYZ/Bar", requirement: .upToNext("1.1.1")),
|
||||
.binary(path: "https://my.domain.com/release/MyFramework.json", requirement: .upToNext("1.0.1")),
|
||||
.binary(path: "file:///some/local/path/MyFramework.json", requirement: .atLeast("1.1.0")),
|
||||
],
|
||||
platforms: [.iOS],
|
||||
useXCFrameworks: false
|
||||
)
|
||||
let expected = """
|
||||
github "Dependency/Dependency" == 2.1.1
|
||||
github "XYZ/Foo" "revision"
|
||||
git "Foo/Bar" >= 1.0.1
|
||||
github "Qwerty/bar" "develop"
|
||||
github "XYZ/Bar" ~> 1.1.1
|
||||
binary "https://my.domain.com/release/MyFramework.json" ~> 1.0.1
|
||||
binary "file:///some/local/path/MyFramework.json" >= 1.1.0
|
||||
"""
|
||||
|
||||
// When
|
||||
let got = carthageDependencies.cartfileValue()
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
// MARK: - CarthageDependency.Dependency tests
|
||||
|
||||
func test_dependency_cartfileValue_github() {
|
||||
// Given
|
||||
let origin: CarthageDependencies.Dependency = .github(path: "Alamofire/Alamofire", requirement: .exact("1.2.3"))
|
||||
let expected = #"github "Alamofire/Alamofire" == 1.2.3"#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_dependency_cartfileValue_git() {
|
||||
// Given
|
||||
let origin: CarthageDependencies.Dependency = .git(path: "https://enterprise.local/desktop/git-error-translations2.git", requirement: .atLeast("5.4.3"))
|
||||
let expected = #"git "https://enterprise.local/desktop/git-error-translations2.git" >= 5.4.3"#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_dependency_cartfileValue_binary() {
|
||||
// Given
|
||||
let origin: CarthageDependencies.Dependency = .binary(path: "file:///some/local/path/MyFramework.json", requirement: .upToNext("5.0.0"))
|
||||
let expected = #"binary "file:///some/local/path/MyFramework.json" ~> 5.0.0"#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
// MARK: - CarthageDependencies.Requirement tests
|
||||
|
||||
func test_requirement_cartfileValue_exact() {
|
||||
// Given
|
||||
let origin: CarthageDependencies.Requirement = .exact("1.2.3")
|
||||
let expected = #"== 1.2.3"#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_requirement_cartfileValue_upToNext() {
|
||||
// Given
|
||||
let origin: CarthageDependencies.Requirement = .upToNext("3.2.3")
|
||||
let expected = #"~> 3.2.3"#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_requirement_cartfileValue_atLeast() {
|
||||
// Given
|
||||
let origin: CarthageDependencies.Requirement = .atLeast("1.2.1")
|
||||
let expected = #">= 1.2.1"#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_requirement_cartfileValue_branch() {
|
||||
// Given
|
||||
let origin: CarthageDependencies.Requirement = .branch("develop")
|
||||
let expected = #""develop""#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_requirement_cartfileValue_revision() {
|
||||
// Given
|
||||
let origin: CarthageDependencies.Requirement = .revision("1234567898765432qwerty")
|
||||
let expected = #""1234567898765432qwerty""#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
import Foundation
|
||||
import XCTest
|
||||
@testable import TuistGraph
|
||||
@testable import TuistSupportTesting
|
||||
|
||||
final class CarthageDependencyTests: TuistUnitTestCase {
|
||||
func test_cartfileValue_github_exact() throws {
|
||||
// Given
|
||||
let dependency = CarthageDependency(origin: .github(path: "Alamofire/Alamofire"), requirement: .exact("1.2.3"), platforms: [.iOS])
|
||||
let expected = #"github "Alamofire/Alamofire" == 1.2.3"#
|
||||
|
||||
// When
|
||||
let got = dependency.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
// MARK: - CarthageDependency.Origin tests
|
||||
|
||||
func test_origin_cartfileValue_github() {
|
||||
// Given
|
||||
let origin: CarthageDependency.Origin = .github(path: "Alamofire/Alamofire")
|
||||
let expected = #"github "Alamofire/Alamofire""#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_origin_cartfileValue_git() {
|
||||
// Given
|
||||
let origin: CarthageDependency.Origin = .git(path: "https://enterprise.local/desktop/git-error-translations2.git")
|
||||
let expected = #"git "https://enterprise.local/desktop/git-error-translations2.git""#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_origin_cartfileValue_binary() {
|
||||
// Given
|
||||
let origin: CarthageDependency.Origin = .binary(path: "file:///some/local/path/MyFramework.json")
|
||||
let expected = #"binary "file:///some/local/path/MyFramework.json""#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
// MARK: - CarthageDependency.Requirement tests
|
||||
|
||||
func test_requirement_cartfileValue_exact() {
|
||||
// Given
|
||||
let origin: CarthageDependency.Requirement = .exact("1.2.3")
|
||||
let expected = #"== 1.2.3"#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_requirement_cartfileValue_upToNext() {
|
||||
// Given
|
||||
let origin: CarthageDependency.Requirement = .upToNext("3.2.3")
|
||||
let expected = #"~> 3.2.3"#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_requirement_cartfileValue_atLeast() {
|
||||
// Given
|
||||
let origin: CarthageDependency.Requirement = .atLeast("1.2.1")
|
||||
let expected = #">= 1.2.1"#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_requirement_cartfileValue_branch() {
|
||||
// Given
|
||||
let origin: CarthageDependency.Requirement = .branch("develop")
|
||||
let expected = #""develop""#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
|
||||
func test_requirement_cartfileValue_revision() {
|
||||
// Given
|
||||
let origin: CarthageDependency.Requirement = .revision("1234567898765432qwerty")
|
||||
let expected = #""1234567898765432qwerty""#
|
||||
|
||||
// When
|
||||
let got = origin.cartfileValue
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(got, expected)
|
||||
}
|
||||
}
|
|
@ -40,9 +40,13 @@ final class DependenciesFetchServiceTests: TuistUnitTestCase {
|
|||
// Given
|
||||
let stubbedPath = try temporaryPath()
|
||||
let stubbedDependencies = Dependencies(
|
||||
carthageDependencies: [
|
||||
CarthageDependency(origin: .github(path: "Dependency1"), requirement: .exact("1.1.1"), platforms: [.iOS, .macOS]),
|
||||
]
|
||||
carthage: .init(
|
||||
[
|
||||
.github(path: "Dependency1", requirement: .exact("1.1.1")),
|
||||
],
|
||||
platforms: [.iOS, .macOS],
|
||||
useXCFrameworks: false
|
||||
)
|
||||
)
|
||||
dependenciesModelLoader.loadDependenciesStub = { _ in stubbedDependencies }
|
||||
|
||||
|
|
|
@ -40,9 +40,13 @@ final class DependenciesUpdateServiceTests: TuistUnitTestCase {
|
|||
// Given
|
||||
let stubbedPath = try temporaryPath()
|
||||
let stubbedDependencies = Dependencies(
|
||||
carthageDependencies: [
|
||||
CarthageDependency(origin: .github(path: "Dependency1"), requirement: .exact("1.1.1"), platforms: [.iOS, .macOS]),
|
||||
]
|
||||
carthage: .init(
|
||||
[
|
||||
.git(path: "Dependency1", requirement: .exact("1.1.1")),
|
||||
],
|
||||
platforms: [.iOS, .macOS],
|
||||
useXCFrameworks: false
|
||||
)
|
||||
)
|
||||
dependenciesModelLoader.loadDependenciesStub = { _ in stubbedDependencies }
|
||||
|
||||
|
|
|
@ -34,22 +34,32 @@ final class DependenciesModelLoaderTests: TuistUnitTestCase {
|
|||
// Given
|
||||
let stubbedPath = try temporaryPath()
|
||||
manifestLoader.loadDependenciesStub = { _ in
|
||||
Dependencies([
|
||||
.carthage(origin: .github(path: "Dependency1"), requirement: .exact("1.1.1"), platforms: [.iOS]),
|
||||
.carthage(origin: .git(path: "Dependency1"), requirement: .exact("2.3.4"), platforms: [.macOS, .tvOS]),
|
||||
])
|
||||
Dependencies(
|
||||
carthage: .carthage(
|
||||
[
|
||||
.github(path: "Dependency1", requirement: .exact("1.1.1")),
|
||||
.git(path: "Dependency1", requirement: .exact("2.3.4")),
|
||||
],
|
||||
platforms: [.iOS, .macOS],
|
||||
useXCFrameworks: true
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// When
|
||||
let model = try subject.loadDependencies(at: stubbedPath)
|
||||
|
||||
// Then
|
||||
let expectedCarthageModels: [TuistGraph.CarthageDependency] = [
|
||||
CarthageDependency(origin: .github(path: "Dependency1"), requirement: .exact("1.1.1"), platforms: Set([.iOS])),
|
||||
CarthageDependency(origin: .git(path: "Dependency1"), requirement: .exact("2.3.4"), platforms: Set([.macOS, .tvOS])),
|
||||
]
|
||||
let expectedDependenciesModel = TuistGraph.Dependencies(carthageDependencies: expectedCarthageModels)
|
||||
|
||||
XCTAssertEqual(model, expectedDependenciesModel)
|
||||
let expected: TuistGraph.Dependencies = .init(
|
||||
carthage: .init(
|
||||
[
|
||||
.github(path: "Dependency1", requirement: .exact("1.1.1")),
|
||||
.git(path: "Dependency1", requirement: .exact("2.3.4")),
|
||||
],
|
||||
platforms: [.iOS, .macOS],
|
||||
useXCFrameworks: true
|
||||
)
|
||||
)
|
||||
XCTAssertEqual(model, expected)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,22 +10,35 @@ import XCTest
|
|||
@testable import TuistSupportTesting
|
||||
|
||||
final class DependenciesManifestMapperTests: TuistUnitTestCase {
|
||||
func test_dependencies() throws {
|
||||
func test_from() throws {
|
||||
// Given
|
||||
let manifest: ProjectDescription.Dependencies = Dependencies([
|
||||
.carthage(origin: .github(path: "Dependency1"), requirement: .exact("1.1.1"), platforms: [.iOS]),
|
||||
.carthage(origin: .git(path: "Dependency.git"), requirement: .branch("BranchName"), platforms: [.macOS]),
|
||||
.carthage(origin: .binary(path: "DependencyXYZ"), requirement: .atLeast("2.3.1"), platforms: [.tvOS]),
|
||||
])
|
||||
let manifest: ProjectDescription.Dependencies = Dependencies(
|
||||
carthage: .carthage(
|
||||
[
|
||||
.github(path: "Dependency1", requirement: .exact("1.1.1")),
|
||||
.git(path: "Dependency.git", requirement: .branch("BranchName")),
|
||||
.binary(path: "DependencyXYZ", requirement: .atLeast("2.3.1")),
|
||||
],
|
||||
platforms: [.iOS, .macOS, .tvOS],
|
||||
useXCFrameworks: true
|
||||
)
|
||||
)
|
||||
|
||||
// When
|
||||
let model = try TuistGraph.Dependencies.from(manifest: manifest)
|
||||
|
||||
// Then
|
||||
XCTAssertEqual(model.carthageDependencies, [
|
||||
TuistGraph.CarthageDependency(origin: .github(path: "Dependency1"), requirement: .exact("1.1.1"), platforms: Set([.iOS])),
|
||||
TuistGraph.CarthageDependency(origin: .git(path: "Dependency.git"), requirement: .branch("BranchName"), platforms: Set([.macOS])),
|
||||
TuistGraph.CarthageDependency(origin: .binary(path: "DependencyXYZ"), requirement: .atLeast("2.3.1"), platforms: Set([.tvOS])),
|
||||
])
|
||||
let expected: TuistGraph.Dependencies = .init(
|
||||
carthage: .init(
|
||||
[
|
||||
.github(path: "Dependency1", requirement: .exact("1.1.1")),
|
||||
.git(path: "Dependency.git", requirement: .branch("BranchName")),
|
||||
.binary(path: "DependencyXYZ", requirement: .atLeast("2.3.1")),
|
||||
],
|
||||
platforms: [.iOS, .macOS, .tvOS],
|
||||
useXCFrameworks: true
|
||||
)
|
||||
)
|
||||
XCTAssertEqual(model, expected)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
import Foundation
|
||||
import struct TSCUtility.Version
|
||||
import XCTest
|
||||
|
||||
@testable import TuistSupport
|
||||
@testable import TuistSupportTesting
|
||||
|
||||
final class CarthageControllerTests: TuistUnitTestCase {
|
||||
private var subject: CarthageController!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
subject = CarthageController()
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
subject = nil
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func test_canUseSystemCarthage_available() {
|
||||
// Given
|
||||
system.whichStub = { _ in "path" }
|
||||
|
||||
// When / Then
|
||||
XCTAssertTrue(subject.canUseSystemCarthage())
|
||||
}
|
||||
|
||||
func test_canUseSystemCarthage_unavailable() {
|
||||
// Given
|
||||
system.whichStub = { _ in throw NSError.test() }
|
||||
|
||||
// When / Then
|
||||
XCTAssertFalse(subject.canUseSystemCarthage())
|
||||
}
|
||||
|
||||
func test_carthageVersion_carthageNotFound() {
|
||||
// Given
|
||||
system.errorCommand("/usr/bin/env", "carthage", "version")
|
||||
|
||||
// When / Then
|
||||
XCTAssertThrowsSpecific(try subject.carthageVersion(), CarthageControllerError.carthageNotFound)
|
||||
}
|
||||
|
||||
func test_carthageVersion_success() {
|
||||
// Given
|
||||
system.stubs["/usr/bin/env carthage version"] = (stderror: nil, stdout: "0.37.0", exitstatus: 0)
|
||||
|
||||
// When / Then
|
||||
XCTAssertEqual(try subject.carthageVersion(), Version(0, 37, 0))
|
||||
}
|
||||
|
||||
func test_isXCFrameworksProductionSupported_notSupported() {
|
||||
// Given
|
||||
system.stubs["/usr/bin/env carthage version"] = (stderror: nil, stdout: "0.36.1", exitstatus: 0)
|
||||
|
||||
// When / Then
|
||||
XCTAssertFalse(try subject.isXCFrameworksProductionSupported())
|
||||
}
|
||||
|
||||
func test_isXCFrameworksProductionSupported_supported() {
|
||||
// Given
|
||||
system.stubs["/usr/bin/env carthage version"] = (stderror: nil, stdout: "0.37.0", exitstatus: 0)
|
||||
|
||||
// When / Then
|
||||
XCTAssertTrue(try subject.isXCFrameworksProductionSupported())
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ Feature: Install dependencies Tuist.
|
|||
And I have a working directory
|
||||
Then I copy the fixture app_with_framework_and_tests_and_dependencies into the working directory
|
||||
Then tuist fetches dependencies
|
||||
Then a directory Tuist/Dependencies/Carthage/Mac/Alamofire.framework exists
|
||||
Then a directory Tuist/Dependencies/Carthage/Alamofire.xcframework exists
|
||||
Then a file Tuist/Dependencies/Carthage/.Alamofire.version exists
|
||||
Then a file Tuist/Dependencies/Lockfiles/Cartfile.resolved exists
|
||||
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import ProjectDescription
|
||||
|
||||
let dependencies = Dependencies([
|
||||
.carthage(origin: .github(path: "Alamofire/Alamofire"), requirement: .exact("5.0.4"), platforms: [.macOS])
|
||||
])
|
||||
let dependencies = Dependencies(
|
||||
carthage: .carthage(
|
||||
[
|
||||
.github(path: "Alamofire/Alamofire", requirement: .exact("5.0.4"))
|
||||
],
|
||||
platforms: [.iOS, .macOS],
|
||||
useXCFrameworks: true
|
||||
)
|
||||
)
|
||||
|
|
|
@ -32,9 +32,15 @@ The snippet below shows an example `Dependencies.swift` manifest file:
|
|||
```swift
|
||||
import ProjectDescription
|
||||
|
||||
let dependencies = Dependencies([
|
||||
.carthage(origin: .github(path: "Alamofire/Alamofire"), requirement: .exact("5.0.4"), platforms: [.macOS])
|
||||
])
|
||||
let dependencies = Dependencies(
|
||||
carthage: .carthage(
|
||||
[
|
||||
.github(path: "Alamofire/Alamofire", requirement: .exact("5.0.4"))
|
||||
],
|
||||
platforms: [.iOS, .macOS],
|
||||
useXCFrameworks: true
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Step 2: "tuist dependencies" commands
|
||||
|
@ -55,10 +61,7 @@ Tuist
|
|||
|- Podfile.lock # coming soon
|
||||
|- Package.resolved # coming soon
|
||||
|- Carthage # stores content of `Carthage/Build` generated by `carthage`
|
||||
|- iOS
|
||||
|- Alamofire.framework
|
||||
|- tvOS
|
||||
|- Alamofire.framework
|
||||
|- Alamofire.xcframework
|
||||
|- Cocoapods # coming soon
|
||||
|- RxSwift
|
||||
|- SwiftPackageManager # coming soon
|
||||
|
@ -67,10 +70,33 @@ Tuist
|
|||
|
||||
### Step 3: Link dependencies
|
||||
|
||||
You can link third-party dependencies like local ones.
|
||||
Link pulled dependencies in your project manifest file.
|
||||
|
||||
1. Run `tuist edit` to start editing your manifest files.
|
||||
2. Open `Project.swift`.
|
||||
3. Define your project with dependencies.
|
||||
|
||||
The snippet below shows an example `Project.swift` manifest file:
|
||||
|
||||
```swift
|
||||
let target = Target(dependencies: [
|
||||
.framework("Tuist/Dependencies/Carthage/iOS/Alamofire.framework"),
|
||||
])
|
||||
import ProjectDescription
|
||||
|
||||
let project = Project(
|
||||
name: "App",
|
||||
organizationName: "tuist.io",
|
||||
targets: [
|
||||
Target(
|
||||
name: "App",
|
||||
platform: .iOS,
|
||||
product: .app,
|
||||
bundleId: "io.tuist.app",
|
||||
deploymentTarget: .iOS(targetVersion: "13.0", devices: .iphone),
|
||||
infoPlist: .default,
|
||||
sources: ["Targets/App/Sources/**"],
|
||||
dependencies: [
|
||||
.xcFramework("Tuist/Dependencies/Carthage/Alamofire.xcframework"),
|
||||
]
|
||||
),
|
||||
]
|
||||
)
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue