Make Scheme Generation Methods More Generic (#730)
Addresses https://github.com/tuist/tuist/issues/667 ### Short description 📝 In order to support custom workspace schemes, we need to make the current scheme generation functions more generic and decouple it from the `Project` type. We now make graph look ups in the project scheme generation functions so that in a follow up pull request it will be easy to add custom workspace scheme support. *Note that this pull request should make no user facing changes.* I've pasted the steps listed in #667 below and marked the items completed by this pull request: - [X] Changing the functions in the SchemeGenerator to use the graph for look ups by default (as this is the main difference between the project and workspace schemes) - [X] Update the scheme model (in TuistGenerator) to start referencing targets using the .project(...) - [ ] Expose workspace scheme type in the project manifest (ProjectDescription) ### Solution 📦 I've added a new `TargetReference` type in place of simple target names of type `String`. `TargetReference` has the name of a target and the relative path to its project. This `TargetReference` type works well for both project scheme generation and workspace scheme generation (in the follow up pull request). This new type enables functions in the scheme generator to do graph lookups to any target in the graph. ### Implementation 👩💻👨💻 - [X] Add `TargetReference` type to model - [X] Change instances of simple target `String` types to `TargetReference` within the `Scheme` type in the model - [X] Update `GeneratorModelLoader` to convert simple target name `String`s into `TargetReference` types by propagating the project path - [X] Update instances where a simple target `String` type is expected to work with the name property in `TargetReference` - [X] Update tests in `SchemesGeneratorTests`, `ProjectGeneratorTests`, `GeneratorModelLoaderTests`
This commit is contained in:
parent
b0290e7711
commit
37e44f5a09
|
@ -20,6 +20,8 @@ Please, check out guidelines: https://keepachangelog.com/en/1.0.0/
|
||||||
- Support for paths relative to root https://github.com/tuist/tuist/pull/727 by @pepibumur.
|
- Support for paths relative to root https://github.com/tuist/tuist/pull/727 by @pepibumur.
|
||||||
- Replace `Sheme.testAction.targets` type from `String` to `TestableTarget` is a description of target that adds to the `TestAction`, you can specify execution tests parallelizable, random execution order or skip tests https://github.com/tuist/tuist/pull/728 by @rowwingman.
|
- Replace `Sheme.testAction.targets` type from `String` to `TestableTarget` is a description of target that adds to the `TestAction`, you can specify execution tests parallelizable, random execution order or skip tests https://github.com/tuist/tuist/pull/728 by @rowwingman.
|
||||||
- Galaxy manifest model https://github.com/tuist/tuist/pull/729 by @pepibumur.
|
- Galaxy manifest model https://github.com/tuist/tuist/pull/729 by @pepibumur.
|
||||||
|
- Make scheme generation methods more generic by @adamkhazi @kwridan.
|
||||||
|
|
||||||
|
|
||||||
## 0.19.0
|
## 0.19.0
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,7 @@ public protocol Graphing: AnyObject, Encodable {
|
||||||
func librariesSearchPaths(path: AbsolutePath, name: String) -> [AbsolutePath]
|
func librariesSearchPaths(path: AbsolutePath, name: String) -> [AbsolutePath]
|
||||||
func librariesSwiftIncludePaths(path: AbsolutePath, name: String) -> [AbsolutePath]
|
func librariesSwiftIncludePaths(path: AbsolutePath, name: String) -> [AbsolutePath]
|
||||||
func embeddableFrameworks(path: AbsolutePath, name: String) throws -> [DependencyReference]
|
func embeddableFrameworks(path: AbsolutePath, name: String) throws -> [DependencyReference]
|
||||||
|
func target(path: AbsolutePath, name: String) throws -> TargetNode?
|
||||||
func targetDependencies(path: AbsolutePath, name: String) -> [TargetNode]
|
func targetDependencies(path: AbsolutePath, name: String) -> [TargetNode]
|
||||||
func staticDependencies(path: AbsolutePath, name: String) -> [DependencyReference]
|
func staticDependencies(path: AbsolutePath, name: String) -> [DependencyReference]
|
||||||
func resourceBundleDependencies(path: AbsolutePath, name: String) -> [TargetNode]
|
func resourceBundleDependencies(path: AbsolutePath, name: String) -> [TargetNode]
|
||||||
|
@ -185,6 +186,10 @@ public class Graph: Graphing {
|
||||||
public var targets: [TargetNode] {
|
public var targets: [TargetNode] {
|
||||||
return cache.targetNodes.flatMap { $0.value.values }
|
return cache.targetNodes.flatMap { $0.value.values }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func target(path: AbsolutePath, name: String) -> TargetNode? {
|
||||||
|
return findTargetNode(path: path, name: name)
|
||||||
|
}
|
||||||
|
|
||||||
public func targetDependencies(path: AbsolutePath, name: String) -> [TargetNode] {
|
public func targetDependencies(path: AbsolutePath, name: String) -> [TargetNode] {
|
||||||
guard let targetNode = findTargetNode(path: path, name: name) else {
|
guard let targetNode = findTargetNode(path: path, name: name) else {
|
||||||
|
|
|
@ -66,13 +66,13 @@ public class ExecutionAction: Equatable {
|
||||||
|
|
||||||
public let title: String
|
public let title: String
|
||||||
public let scriptText: String
|
public let scriptText: String
|
||||||
public let target: String?
|
public let target: TargetReference?
|
||||||
|
|
||||||
// MARK: - Init
|
// MARK: - Init
|
||||||
|
|
||||||
public init(title: String,
|
public init(title: String,
|
||||||
scriptText: String,
|
scriptText: String,
|
||||||
target: String?) {
|
target: TargetReference?) {
|
||||||
self.title = title
|
self.title = title
|
||||||
self.scriptText = scriptText
|
self.scriptText = scriptText
|
||||||
self.target = target
|
self.target = target
|
||||||
|
@ -85,16 +85,30 @@ public class ExecutionAction: Equatable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct TargetReference: Equatable {
|
||||||
|
public var projectPath: AbsolutePath
|
||||||
|
public var name: String
|
||||||
|
|
||||||
|
public static func project(path: AbsolutePath, target: String) -> TargetReference {
|
||||||
|
return .init(projectPath: path, name: target)
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(projectPath: AbsolutePath, name: String) {
|
||||||
|
self.projectPath = projectPath
|
||||||
|
self.name = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class BuildAction: Equatable {
|
public class BuildAction: Equatable {
|
||||||
// MARK: - Attributes
|
// MARK: - Attributes
|
||||||
|
|
||||||
public let targets: [String]
|
public let targets: [TargetReference]
|
||||||
public let preActions: [ExecutionAction]
|
public let preActions: [ExecutionAction]
|
||||||
public let postActions: [ExecutionAction]
|
public let postActions: [ExecutionAction]
|
||||||
|
|
||||||
// MARK: - Init
|
// MARK: - Init
|
||||||
|
|
||||||
public init(targets: [String] = [],
|
public init(targets: [TargetReference] = [],
|
||||||
preActions: [ExecutionAction] = [],
|
preActions: [ExecutionAction] = [],
|
||||||
postActions: [ExecutionAction] = []) {
|
postActions: [ExecutionAction] = []) {
|
||||||
self.targets = targets
|
self.targets = targets
|
||||||
|
@ -118,7 +132,7 @@ public class TestAction: Equatable {
|
||||||
public let arguments: Arguments?
|
public let arguments: Arguments?
|
||||||
public let configurationName: String
|
public let configurationName: String
|
||||||
public let coverage: Bool
|
public let coverage: Bool
|
||||||
public let codeCoverageTargets: [String]
|
public let codeCoverageTargets: [TargetReference]
|
||||||
public let preActions: [ExecutionAction]
|
public let preActions: [ExecutionAction]
|
||||||
public let postActions: [ExecutionAction]
|
public let postActions: [ExecutionAction]
|
||||||
|
|
||||||
|
@ -128,7 +142,7 @@ public class TestAction: Equatable {
|
||||||
arguments: Arguments? = nil,
|
arguments: Arguments? = nil,
|
||||||
configurationName: String,
|
configurationName: String,
|
||||||
coverage: Bool = false,
|
coverage: Bool = false,
|
||||||
codeCoverageTargets: [String] = [],
|
codeCoverageTargets: [TargetReference] = [],
|
||||||
preActions: [ExecutionAction] = [],
|
preActions: [ExecutionAction] = [],
|
||||||
postActions: [ExecutionAction] = []) {
|
postActions: [ExecutionAction] = []) {
|
||||||
self.targets = targets
|
self.targets = targets
|
||||||
|
@ -153,13 +167,13 @@ public class TestAction: Equatable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct TestableTarget: Equatable, Hashable {
|
public struct TestableTarget: Equatable {
|
||||||
public let target: String
|
public let target: TargetReference
|
||||||
public let isSkipped: Bool
|
public let isSkipped: Bool
|
||||||
public let isParallelizable: Bool
|
public let isParallelizable: Bool
|
||||||
public let isRandomExecutionOrdering: Bool
|
public let isRandomExecutionOrdering: Bool
|
||||||
|
|
||||||
public init(target: String, skipped: Bool = false, parallelizable: Bool = false, randomExecutionOrdering: Bool = false) {
|
public init(target: TargetReference, skipped: Bool = false, parallelizable: Bool = false, randomExecutionOrdering: Bool = false) {
|
||||||
self.target = target
|
self.target = target
|
||||||
self.isSkipped = skipped
|
self.isSkipped = skipped
|
||||||
self.isParallelizable = parallelizable
|
self.isParallelizable = parallelizable
|
||||||
|
@ -171,13 +185,13 @@ public class RunAction: Equatable {
|
||||||
// MARK: - Attributes
|
// MARK: - Attributes
|
||||||
|
|
||||||
public let configurationName: String
|
public let configurationName: String
|
||||||
public let executable: String?
|
public let executable: TargetReference?
|
||||||
public let arguments: Arguments?
|
public let arguments: Arguments?
|
||||||
|
|
||||||
// MARK: - Init
|
// MARK: - Init
|
||||||
|
|
||||||
public init(configurationName: String,
|
public init(configurationName: String,
|
||||||
executable: String? = nil,
|
executable: TargetReference? = nil,
|
||||||
arguments: Arguments? = nil) {
|
arguments: Arguments? = nil) {
|
||||||
self.configurationName = configurationName
|
self.configurationName = configurationName
|
||||||
self.executable = executable
|
self.executable = executable
|
||||||
|
|
|
@ -12,7 +12,7 @@ public extension Arguments {
|
||||||
|
|
||||||
public extension RunAction {
|
public extension RunAction {
|
||||||
static func test(configurationName: String = BuildConfiguration.debug.name,
|
static func test(configurationName: String = BuildConfiguration.debug.name,
|
||||||
executable: String? = "App",
|
executable: TargetReference? = TargetReference(projectPath: "/Project", name: "App"),
|
||||||
arguments: Arguments? = Arguments.test()) -> RunAction {
|
arguments: Arguments? = Arguments.test()) -> RunAction {
|
||||||
return RunAction(configurationName: configurationName,
|
return RunAction(configurationName: configurationName,
|
||||||
executable: executable,
|
executable: executable,
|
||||||
|
@ -21,11 +21,11 @@ public extension RunAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension TestAction {
|
public extension TestAction {
|
||||||
static func test(targets: [TestableTarget] = [TestableTarget(target: "AppTests")],
|
static func test(targets: [TestableTarget] = [TestableTarget(target: TargetReference(projectPath: "/Project", name: "AppTests"))],
|
||||||
arguments: Arguments? = Arguments.test(),
|
arguments: Arguments? = Arguments.test(),
|
||||||
configurationName: String = BuildConfiguration.debug.name,
|
configurationName: String = BuildConfiguration.debug.name,
|
||||||
coverage: Bool = false,
|
coverage: Bool = false,
|
||||||
codeCoverageTargets: [String] = [],
|
codeCoverageTargets: [TargetReference] = [],
|
||||||
preActions: [ExecutionAction] = [],
|
preActions: [ExecutionAction] = [],
|
||||||
postActions: [ExecutionAction] = []) -> TestAction {
|
postActions: [ExecutionAction] = []) -> TestAction {
|
||||||
return TestAction(targets: targets,
|
return TestAction(targets: targets,
|
||||||
|
@ -39,7 +39,7 @@ public extension TestAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension BuildAction {
|
public extension BuildAction {
|
||||||
static func test(targets: [String] = ["App"],
|
static func test(targets: [TargetReference] = [TargetReference(projectPath: "/Project", name: "App")],
|
||||||
preActions: [ExecutionAction] = [],
|
preActions: [ExecutionAction] = [],
|
||||||
postActions: [ExecutionAction] = []) -> BuildAction {
|
postActions: [ExecutionAction] = []) -> BuildAction {
|
||||||
return BuildAction(targets: targets, preActions: preActions, postActions: postActions)
|
return BuildAction(targets: targets, preActions: preActions, postActions: postActions)
|
||||||
|
|
|
@ -38,7 +38,7 @@ final class ProjectGenerator: ProjectGenerating {
|
||||||
let configGenerator: ConfigGenerating
|
let configGenerator: ConfigGenerating
|
||||||
|
|
||||||
/// Generator for the project schemes.
|
/// Generator for the project schemes.
|
||||||
let schemesGenerator: SchemesGenerating
|
let schemesGenerator: SchemesGenerator
|
||||||
|
|
||||||
/// Generator for the project derived files.
|
/// Generator for the project derived files.
|
||||||
let derivedFileGenerator: DerivedFileGenerating
|
let derivedFileGenerator: DerivedFileGenerating
|
||||||
|
@ -54,7 +54,7 @@ final class ProjectGenerator: ProjectGenerating {
|
||||||
/// - derivedFileGenerator: Generator for the project derived files.
|
/// - derivedFileGenerator: Generator for the project derived files.
|
||||||
init(targetGenerator: TargetGenerating = TargetGenerator(),
|
init(targetGenerator: TargetGenerating = TargetGenerator(),
|
||||||
configGenerator: ConfigGenerating = ConfigGenerator(),
|
configGenerator: ConfigGenerating = ConfigGenerator(),
|
||||||
schemesGenerator: SchemesGenerating = SchemesGenerator(),
|
schemesGenerator: SchemesGenerator = SchemesGenerator(),
|
||||||
derivedFileGenerator: DerivedFileGenerating = DerivedFileGenerator()) {
|
derivedFileGenerator: DerivedFileGenerating = DerivedFileGenerator()) {
|
||||||
self.targetGenerator = targetGenerator
|
self.targetGenerator = targetGenerator
|
||||||
self.configGenerator = configGenerator
|
self.configGenerator = configGenerator
|
||||||
|
@ -103,9 +103,7 @@ final class ProjectGenerator: ProjectGenerating {
|
||||||
groups: groups,
|
groups: groups,
|
||||||
pbxproj: pbxproj,
|
pbxproj: pbxproj,
|
||||||
sourceRootPath: sourceRootPath)
|
sourceRootPath: sourceRootPath)
|
||||||
let configurationList = try configGenerator.generateProjectConfig(project: project,
|
let configurationList = try configGenerator.generateProjectConfig(project: project, pbxproj: pbxproj, fileElements: fileElements)
|
||||||
pbxproj: pbxproj,
|
|
||||||
fileElements: fileElements)
|
|
||||||
let pbxProject = try generatePbxproject(project: project,
|
let pbxProject = try generatePbxproject(project: project,
|
||||||
configurationList: configurationList,
|
configurationList: configurationList,
|
||||||
groups: groups,
|
groups: groups,
|
||||||
|
@ -252,7 +250,7 @@ final class ProjectGenerator: ProjectGenerating {
|
||||||
workspace: XCWorkspace,
|
workspace: XCWorkspace,
|
||||||
pbxproj: PBXProj,
|
pbxproj: PBXProj,
|
||||||
project: Project,
|
project: Project,
|
||||||
graph _: Graphing) throws -> GeneratedProject {
|
graph: Graphing) throws -> GeneratedProject {
|
||||||
var generatedProject: GeneratedProject!
|
var generatedProject: GeneratedProject!
|
||||||
|
|
||||||
try FileHandler.shared.inTemporaryDirectory { temporaryPath in
|
try FileHandler.shared.inTemporaryDirectory { temporaryPath in
|
||||||
|
@ -263,9 +261,11 @@ final class ProjectGenerator: ProjectGenerating {
|
||||||
generatedProject = GeneratedProject(pbxproj: pbxproj,
|
generatedProject = GeneratedProject(pbxproj: pbxproj,
|
||||||
path: temporaryPath,
|
path: temporaryPath,
|
||||||
targets: nativeTargets,
|
targets: nativeTargets,
|
||||||
name: xcodeprojPath.components.last!)
|
name: xcodeprojPath.basename)
|
||||||
try writeSchemes(project: project,
|
try writeSchemes(project: project,
|
||||||
generatedProject: generatedProject)
|
generatedProject: generatedProject,
|
||||||
|
xcprojectPath: temporaryPath,
|
||||||
|
graph: graph)
|
||||||
try FileHandler.shared.replace(xcodeprojPath, with: temporaryPath)
|
try FileHandler.shared.replace(xcodeprojPath, with: temporaryPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,9 +280,13 @@ final class ProjectGenerator: ProjectGenerating {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func writeSchemes(project: Project,
|
private func writeSchemes(project: Project,
|
||||||
generatedProject: GeneratedProject) throws {
|
generatedProject: GeneratedProject,
|
||||||
try schemesGenerator.generateTargetSchemes(project: project,
|
xcprojectPath: AbsolutePath,
|
||||||
generatedProject: generatedProject)
|
graph: Graphing) throws {
|
||||||
|
try schemesGenerator.generateProjectSchemes(project: project,
|
||||||
|
xcprojectPath: xcprojectPath,
|
||||||
|
generatedProject: generatedProject,
|
||||||
|
graph: graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func determineProjectConstants(graph: Graphing) throws -> ProjectConstants {
|
private func determineProjectConstants(graph: Graphing) throws -> ProjectConstants {
|
||||||
|
|
|
@ -10,10 +10,14 @@ protocol SchemesGenerating {
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - project: Project manifest.
|
/// - project: Project manifest.
|
||||||
|
/// - xcprojectPath: Path to the Xcode project.
|
||||||
/// - generatedProject: Generated Xcode project.
|
/// - generatedProject: Generated Xcode project.
|
||||||
|
/// - graph: Tuist graph.
|
||||||
/// - Throws: A FatalError if the generation of the schemes fails.
|
/// - Throws: A FatalError if the generation of the schemes fails.
|
||||||
func generateTargetSchemes(project: Project,
|
func generateProjectSchemes(project: Project,
|
||||||
generatedProject: GeneratedProject) throws
|
xcprojectPath: AbsolutePath,
|
||||||
|
generatedProject: GeneratedProject,
|
||||||
|
graph: Graphing) throws
|
||||||
}
|
}
|
||||||
|
|
||||||
// swiftlint:disable:next type_body_length
|
// swiftlint:disable:next type_body_length
|
||||||
|
@ -23,57 +27,93 @@ final class SchemesGenerator: SchemesGenerating {
|
||||||
|
|
||||||
/// Default version for generated schemes.
|
/// Default version for generated schemes.
|
||||||
private static let defaultVersion = "1.3"
|
private static let defaultVersion = "1.3"
|
||||||
|
|
||||||
/// Generates the schemes for the project manifest.
|
/// Generate schemes for a project.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - project: Project manifest.
|
/// - project: Project manifest.
|
||||||
/// - generatedProject: Generated Xcode project.
|
/// - xcprojectPath: Path to project's .xcodeproj.
|
||||||
/// - Throws: A FatalError if the generation of the schemes fails.
|
/// - generatedProject: Generated Project
|
||||||
func generateTargetSchemes(project: Project, generatedProject: GeneratedProject) throws {
|
/// - graph: Tuist graph.
|
||||||
/// Generate scheme from manifest
|
func generateProjectSchemes(project: Project,
|
||||||
|
xcprojectPath: AbsolutePath,
|
||||||
|
generatedProject: GeneratedProject,
|
||||||
|
graph: Graphing) throws {
|
||||||
|
|
||||||
|
/// Generate custom schemes from manifest
|
||||||
try project.schemes.forEach { scheme in
|
try project.schemes.forEach { scheme in
|
||||||
try generateScheme(scheme: scheme, project: project, generatedProject: generatedProject)
|
try generateScheme(scheme: scheme,
|
||||||
|
xcPath: xcprojectPath,
|
||||||
|
path: project.path,
|
||||||
|
graph: graph,
|
||||||
|
generatedProjects: [project.path: generatedProject])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate scheme for every targets in Project that is not defined in Manifest
|
/// Generate default schemes for targets in Project that are not defined in Manifest
|
||||||
let buildConfiguration = defaultDebugBuildConfigurationName(in: project)
|
let buildConfiguration = defaultDebugBuildConfigurationName(in: project)
|
||||||
try project.targets.forEach { target in
|
let userDefinedSchemes = Set(project.schemes.map(\.name))
|
||||||
|
let defaultSchemeTargets = project.targets.filter { !userDefinedSchemes.contains($0.name) }
|
||||||
|
try defaultSchemeTargets.forEach { target in
|
||||||
|
let scheme = createDefaultScheme(target: target, project: project, buildConfiguration: buildConfiguration)
|
||||||
|
try generateScheme(scheme: scheme,
|
||||||
|
xcPath: xcprojectPath,
|
||||||
|
path: project.path,
|
||||||
|
graph: graph,
|
||||||
|
generatedProjects: [project.path: generatedProject])
|
||||||
|
|
||||||
if !project.schemes.contains(where: { $0.name == target.name }) {
|
|
||||||
let scheme = Scheme(name: target.name,
|
|
||||||
shared: true,
|
|
||||||
buildAction: BuildAction(targets: [target.name]),
|
|
||||||
testAction: TestAction(targets: [TestableTarget(target: target.name)], configurationName: buildConfiguration),
|
|
||||||
runAction: RunAction(configurationName: buildConfiguration,
|
|
||||||
executable: target.productName,
|
|
||||||
arguments: Arguments(environment: target.environment)))
|
|
||||||
|
|
||||||
try generateScheme(scheme: scheme,
|
|
||||||
project: project,
|
|
||||||
generatedProject: generatedProject)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates the scheme.
|
private func createDefaultScheme(target: Target, project: Project, buildConfiguration: String) -> Scheme {
|
||||||
|
let targetReference = TargetReference.project(path: project.path, target: target.name)
|
||||||
|
let testTargets = target.product.testsBundle ? [TestableTarget(target: targetReference)] : []
|
||||||
|
return Scheme(name: target.name,
|
||||||
|
shared: true,
|
||||||
|
buildAction: BuildAction(targets: [targetReference]),
|
||||||
|
testAction: TestAction(targets: testTargets, configurationName: buildConfiguration),
|
||||||
|
runAction: RunAction(configurationName: buildConfiguration, executable: targetReference, arguments: Arguments(environment: target.environment)))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate schemes for a project or workspace.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - scheme: Scheme manifest.
|
/// - scheme: Project scheme.
|
||||||
/// - project: Project manifest.
|
/// - xcPath: Path to workspace's .xcworkspace or project's .xcodeproj.
|
||||||
/// - generatedProject: Generated Xcode project.
|
/// - path: Path to workspace or project folder.
|
||||||
/// - Throws: An error if the generation fails.
|
/// - graph: Tuist graph.
|
||||||
func generateScheme(scheme: Scheme,
|
/// - generatedProjects: Project paths mapped to generated projects.
|
||||||
project: Project,
|
private func generateScheme(scheme: Scheme,
|
||||||
generatedProject: GeneratedProject) throws {
|
xcPath: AbsolutePath,
|
||||||
let schemesDirectory = try createSchemesDirectory(projectPath: generatedProject.path, shared: scheme.shared)
|
path: AbsolutePath,
|
||||||
let schemePath = schemesDirectory.appending(component: "\(scheme.name).xcscheme")
|
graph: Graphing,
|
||||||
|
generatedProjects: [AbsolutePath: GeneratedProject]) throws {
|
||||||
let generatedBuildAction = schemeBuildAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
let schemeDirectory = try createSchemesDirectory(path: xcPath, shared: scheme.shared)
|
||||||
let generatedTestAction = schemeTestAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
let schemePath = schemeDirectory.appending(component: "\(scheme.name).xcscheme")
|
||||||
let generatedLaunchAction = schemeLaunchAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
|
||||||
let generatedProfileAction = schemeProfileAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
let generatedBuildAction = try schemeBuildAction(scheme: scheme,
|
||||||
let generatedArchiveAction = schemeArchiveAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
graph: graph,
|
||||||
|
rootPath: path,
|
||||||
|
generatedProjects: generatedProjects)
|
||||||
|
let generatedTestAction = try schemeTestAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: path,
|
||||||
|
generatedProjects: generatedProjects)
|
||||||
|
let generatedLaunchAction = try schemeLaunchAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: path,
|
||||||
|
generatedProjects: generatedProjects)
|
||||||
|
let generatedProfileAction = try schemeProfileAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: path,
|
||||||
|
generatedProjects: generatedProjects)
|
||||||
|
let generatedAnalyzeAction = try schemeAnalyzeAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: path,
|
||||||
|
generatedProjects: generatedProjects)
|
||||||
|
let generatedArchiveAction = try schemeArchiveAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: path,
|
||||||
|
generatedProjects: generatedProjects)
|
||||||
|
|
||||||
let scheme = XCScheme(name: scheme.name,
|
let scheme = XCScheme(name: scheme.name,
|
||||||
lastUpgradeVersion: SchemesGenerator.defaultLastUpgradeVersion,
|
lastUpgradeVersion: SchemesGenerator.defaultLastUpgradeVersion,
|
||||||
|
@ -82,158 +122,96 @@ final class SchemesGenerator: SchemesGenerating {
|
||||||
testAction: generatedTestAction,
|
testAction: generatedTestAction,
|
||||||
launchAction: generatedLaunchAction,
|
launchAction: generatedLaunchAction,
|
||||||
profileAction: generatedProfileAction,
|
profileAction: generatedProfileAction,
|
||||||
analyzeAction: schemeAnalyzeAction(for: project),
|
analyzeAction: generatedAnalyzeAction,
|
||||||
archiveAction: generatedArchiveAction)
|
archiveAction: generatedArchiveAction)
|
||||||
|
|
||||||
try scheme.write(path: schemePath.path, override: true)
|
try scheme.write(path: schemePath.path, override: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the build action for the project scheme.
|
/// Generates the scheme build action.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - project: Project manifest.
|
/// - scheme: Scheme manifest.
|
||||||
/// - generatedProject: Generated Xcode project.
|
/// - graph: Tuist graph.
|
||||||
/// - graph: Dependencies graph.
|
/// - rootPath: Path to the project or workspace.
|
||||||
|
/// - generatedProjects: Project paths mapped to generated projects.
|
||||||
/// - Returns: Scheme build action.
|
/// - Returns: Scheme build action.
|
||||||
func projectBuildAction(project: Project,
|
func schemeBuildAction(scheme: Scheme,
|
||||||
generatedProject: GeneratedProject,
|
graph: Graphing,
|
||||||
graph: Graphing) -> XCScheme.BuildAction {
|
rootPath: AbsolutePath,
|
||||||
let targets = project.sortedTargetsForProjectScheme(graph: graph)
|
generatedProjects: [AbsolutePath: GeneratedProject]) throws -> XCScheme.BuildAction? {
|
||||||
let entries: [XCScheme.BuildAction.Entry] = targets.map { (target) -> XCScheme.BuildAction.Entry in
|
guard let buildAction = scheme.buildAction else { return nil }
|
||||||
|
|
||||||
let pbxTarget = generatedProject.targets[target.name]!
|
let buildFor: [XCScheme.BuildAction.Entry.BuildFor] = [
|
||||||
let buildableReference = targetBuildableReference(target: target,
|
.analyzing, .archiving, .profiling, .running, .testing,
|
||||||
pbxTarget: pbxTarget,
|
]
|
||||||
projectName: generatedProject.name)
|
|
||||||
var buildFor: [XCScheme.BuildAction.Entry.BuildFor] = []
|
|
||||||
if target.product.testsBundle {
|
|
||||||
buildFor.append(.testing)
|
|
||||||
} else {
|
|
||||||
buildFor.append(contentsOf: [.analyzing, .archiving, .profiling, .running, .testing])
|
|
||||||
}
|
|
||||||
|
|
||||||
return XCScheme.BuildAction.Entry(buildableReference: buildableReference,
|
var entries: [XCScheme.BuildAction.Entry] = []
|
||||||
buildFor: buildFor)
|
var preActions: [XCScheme.ExecutionAction] = []
|
||||||
|
var postActions: [XCScheme.ExecutionAction] = []
|
||||||
|
|
||||||
|
try buildAction.targets.forEach { buildActionTarget in
|
||||||
|
guard let buildableReference = try createBuildableReference(targetReference: buildActionTarget,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: rootPath,
|
||||||
|
generatedProjects: generatedProjects) else { return }
|
||||||
|
entries.append(XCScheme.BuildAction.Entry(buildableReference: buildableReference, buildFor: buildFor))
|
||||||
|
}
|
||||||
|
|
||||||
|
preActions = try buildAction.preActions.map {
|
||||||
|
try schemeExecutionAction(action: $0, graph: graph, generatedProjects: generatedProjects, rootPath: rootPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
postActions = try buildAction.postActions.map {
|
||||||
|
try schemeExecutionAction(action: $0, graph: graph, generatedProjects: generatedProjects, rootPath: rootPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return XCScheme.BuildAction(buildActionEntries: entries,
|
return XCScheme.BuildAction(buildActionEntries: entries,
|
||||||
|
preActions: preActions,
|
||||||
|
postActions: postActions,
|
||||||
parallelizeBuild: true,
|
parallelizeBuild: true,
|
||||||
buildImplicitDependencies: true)
|
buildImplicitDependencies: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates the test action for the project scheme.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - project: Project manifest.
|
|
||||||
/// - generatedProject: Generated Xcode project.
|
|
||||||
/// - Returns: Scheme test action.
|
|
||||||
func projectTestAction(project: Project,
|
|
||||||
generatedProject: GeneratedProject) -> XCScheme.TestAction {
|
|
||||||
var testables: [XCScheme.TestableReference] = []
|
|
||||||
let testTargets = project.targets.filter { $0.product.testsBundle }
|
|
||||||
|
|
||||||
testTargets.forEach { target in
|
|
||||||
let pbxTarget = generatedProject.targets[target.name]!
|
|
||||||
|
|
||||||
let reference = targetBuildableReference(target: target,
|
|
||||||
pbxTarget: pbxTarget,
|
|
||||||
projectName: generatedProject.name)
|
|
||||||
let testable = XCScheme.TestableReference(skipped: false,
|
|
||||||
buildableReference: reference)
|
|
||||||
testables.append(testable)
|
|
||||||
}
|
|
||||||
|
|
||||||
let buildConfiguration = defaultDebugBuildConfigurationName(in: project)
|
|
||||||
return XCScheme.TestAction(buildConfiguration: buildConfiguration,
|
|
||||||
macroExpansion: nil,
|
|
||||||
testables: testables)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generates the scheme archive action.
|
|
||||||
/// - Parameter scheme: Scheme manifest.
|
|
||||||
/// - Parameter project: Project manifest.
|
|
||||||
/// - Parameter generatedProject: Generated Xcode project.
|
|
||||||
/// - Returns: Scheme archive action.
|
|
||||||
func schemeArchiveAction(scheme: Scheme,
|
|
||||||
project: Project,
|
|
||||||
generatedProject: GeneratedProject) -> XCScheme.ArchiveAction {
|
|
||||||
guard let archiveAction = scheme.archiveAction else {
|
|
||||||
return defaultSchemeArchiveAction(for: project)
|
|
||||||
}
|
|
||||||
|
|
||||||
return XCScheme.ArchiveAction(buildConfiguration: archiveAction.configurationName,
|
|
||||||
revealArchiveInOrganizer: archiveAction.revealArchiveInOrganizer,
|
|
||||||
customArchiveName: archiveAction.customArchiveName,
|
|
||||||
preActions: schemeExecutionActions(actions: archiveAction.preActions,
|
|
||||||
project: project,
|
|
||||||
generatedProject: generatedProject),
|
|
||||||
postActions: schemeExecutionActions(actions: archiveAction.postActions,
|
|
||||||
project: project,
|
|
||||||
generatedProject: generatedProject))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generates the array of BuildableReference for targets that the
|
|
||||||
/// coverage report should be generated for them.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - testAction: test actions.
|
|
||||||
/// - project: Project manifest.
|
|
||||||
/// - generatedProject: Generated Xcode project.
|
|
||||||
/// - Returns: Array of buildable references.
|
|
||||||
private func testCoverageTargetReferences(testAction: TestAction, project: Project, generatedProject: GeneratedProject) -> [XCScheme.BuildableReference] {
|
|
||||||
var codeCoverageTargets: [XCScheme.BuildableReference] = []
|
|
||||||
testAction.codeCoverageTargets.forEach { name in
|
|
||||||
|
|
||||||
guard let target = project.targets.first(where: { $0.name == name }) else { return }
|
|
||||||
guard let pbxTarget = generatedProject.targets[name] else { return }
|
|
||||||
|
|
||||||
let reference = self.targetBuildableReference(target: target,
|
|
||||||
pbxTarget: pbxTarget,
|
|
||||||
projectName: generatedProject.name)
|
|
||||||
codeCoverageTargets.append(reference)
|
|
||||||
}
|
|
||||||
|
|
||||||
return codeCoverageTargets
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generates the scheme test action.
|
/// Generates the scheme test action.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - scheme: Scheme manifest.
|
/// - scheme: Scheme manifest.
|
||||||
/// - project: Project manifest.
|
/// - graph: Tuist graph.
|
||||||
/// - generatedProject: Generated Xcode project.
|
/// - rootPath: Root path to either project or workspace.
|
||||||
|
/// - generatedProjects: Project paths mapped to generated projects.
|
||||||
/// - Returns: Scheme test action.
|
/// - Returns: Scheme test action.
|
||||||
func schemeTestAction(scheme: Scheme,
|
func schemeTestAction(scheme: Scheme,
|
||||||
project: Project,
|
graph: Graphing,
|
||||||
generatedProject: GeneratedProject) -> XCScheme.TestAction? {
|
rootPath: AbsolutePath,
|
||||||
|
generatedProjects: [AbsolutePath: GeneratedProject]) throws -> XCScheme.TestAction? {
|
||||||
guard let testAction = scheme.testAction else { return nil }
|
guard let testAction = scheme.testAction else { return nil }
|
||||||
|
|
||||||
var testables: [XCScheme.TestableReference] = []
|
var testables: [XCScheme.TestableReference] = []
|
||||||
var preActions: [XCScheme.ExecutionAction] = []
|
var preActions: [XCScheme.ExecutionAction] = []
|
||||||
var postActions: [XCScheme.ExecutionAction] = []
|
var postActions: [XCScheme.ExecutionAction] = []
|
||||||
|
|
||||||
testAction.targets.forEach { test in
|
try testAction.targets.forEach { testableTarget in
|
||||||
let targetName = test.target
|
guard let reference = try createBuildableReference(targetReference: testableTarget.target,
|
||||||
guard let target = project.targets.first(where: { $0.name == targetName }), target.product.testsBundle else { return }
|
graph: graph,
|
||||||
guard let pbxTarget = generatedProject.targets[targetName] else { return }
|
rootPath: rootPath,
|
||||||
|
generatedProjects: generatedProjects) else { return }
|
||||||
let reference = self.targetBuildableReference(target: target,
|
|
||||||
pbxTarget: pbxTarget,
|
let testable = XCScheme.TestableReference(skipped: testableTarget.isSkipped,
|
||||||
projectName: generatedProject.name)
|
parallelizable: testableTarget.isParallelizable,
|
||||||
|
randomExecutionOrdering: testableTarget.isRandomExecutionOrdering,
|
||||||
let testable = XCScheme.TestableReference(skipped: test.isSkipped,
|
|
||||||
parallelizable: test.isParallelizable,
|
|
||||||
randomExecutionOrdering: test.isRandomExecutionOrdering,
|
|
||||||
buildableReference: reference)
|
buildableReference: reference)
|
||||||
testables.append(testable)
|
testables.append(testable)
|
||||||
}
|
}
|
||||||
|
|
||||||
preActions = schemeExecutionActions(actions: testAction.preActions,
|
preActions = try testAction.preActions.map { try schemeExecutionAction(action: $0,
|
||||||
project: project,
|
graph: graph,
|
||||||
generatedProject: generatedProject)
|
generatedProjects: generatedProjects,
|
||||||
|
rootPath: rootPath) }
|
||||||
postActions = schemeExecutionActions(actions: testAction.postActions,
|
postActions = try testAction.postActions.map { try schemeExecutionAction(action: $0,
|
||||||
project: project,
|
graph: graph,
|
||||||
generatedProject: generatedProject)
|
generatedProjects: generatedProjects,
|
||||||
|
rootPath: rootPath) }
|
||||||
|
|
||||||
var args: XCScheme.CommandLineArguments?
|
var args: XCScheme.CommandLineArguments?
|
||||||
var environments: [XCScheme.EnvironmentVariable]?
|
var environments: [XCScheme.EnvironmentVariable]?
|
||||||
|
@ -242,8 +220,13 @@ final class SchemesGenerator: SchemesGenerating {
|
||||||
args = XCScheme.CommandLineArguments(arguments: commandlineArgruments(arguments.launch))
|
args = XCScheme.CommandLineArguments(arguments: commandlineArgruments(arguments.launch))
|
||||||
environments = environmentVariables(arguments.environment)
|
environments = environmentVariables(arguments.environment)
|
||||||
}
|
}
|
||||||
|
|
||||||
let codeCoverageTargets = testCoverageTargetReferences(testAction: testAction, project: project, generatedProject: generatedProject)
|
let codeCoverageTargets = try testAction.codeCoverageTargets.compactMap {
|
||||||
|
try testCoverageTargetReferences(target: $0,
|
||||||
|
graph: graph,
|
||||||
|
generatedProjects: generatedProjects,
|
||||||
|
rootPath: rootPath)
|
||||||
|
}
|
||||||
|
|
||||||
let onlyGenerateCoverageForSpecifiedTargets = codeCoverageTargets.count > 0 ? true : nil
|
let onlyGenerateCoverageForSpecifiedTargets = codeCoverageTargets.count > 0 ? true : nil
|
||||||
|
|
||||||
|
@ -261,75 +244,35 @@ final class SchemesGenerator: SchemesGenerating {
|
||||||
commandlineArguments: args,
|
commandlineArguments: args,
|
||||||
environmentVariables: environments)
|
environmentVariables: environments)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates the scheme build action.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - scheme: Scheme manifest.
|
|
||||||
/// - project: Project manifest.
|
|
||||||
/// - generatedProject: Generated Xcode project.
|
|
||||||
/// - Returns: Scheme build action.
|
|
||||||
func schemeBuildAction(scheme: Scheme,
|
|
||||||
project: Project,
|
|
||||||
generatedProject: GeneratedProject) -> XCScheme.BuildAction? {
|
|
||||||
guard let buildAction = scheme.buildAction else { return nil }
|
|
||||||
|
|
||||||
let buildFor: [XCScheme.BuildAction.Entry.BuildFor] = [
|
|
||||||
.analyzing, .archiving, .profiling, .running, .testing,
|
|
||||||
]
|
|
||||||
|
|
||||||
var entries: [XCScheme.BuildAction.Entry] = []
|
|
||||||
var preActions: [XCScheme.ExecutionAction] = []
|
|
||||||
var postActions: [XCScheme.ExecutionAction] = []
|
|
||||||
|
|
||||||
buildAction.targets.forEach { name in
|
|
||||||
guard let target = project.targets.first(where: { $0.name == name }) else { return }
|
|
||||||
guard let pbxTarget = generatedProject.targets[name] else { return }
|
|
||||||
let buildableReference = self.targetBuildableReference(target: target,
|
|
||||||
pbxTarget: pbxTarget,
|
|
||||||
projectName: generatedProject.name)
|
|
||||||
|
|
||||||
entries.append(XCScheme.BuildAction.Entry(buildableReference: buildableReference, buildFor: buildFor))
|
|
||||||
}
|
|
||||||
|
|
||||||
preActions = schemeExecutionActions(actions: buildAction.preActions,
|
|
||||||
project: project,
|
|
||||||
generatedProject: generatedProject)
|
|
||||||
|
|
||||||
postActions = schemeExecutionActions(actions: buildAction.postActions,
|
|
||||||
project: project,
|
|
||||||
generatedProject: generatedProject)
|
|
||||||
|
|
||||||
return XCScheme.BuildAction(buildActionEntries: entries,
|
|
||||||
preActions: preActions,
|
|
||||||
postActions: postActions,
|
|
||||||
parallelizeBuild: true,
|
|
||||||
buildImplicitDependencies: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generates the scheme launch action.
|
/// Generates the scheme launch action.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - scheme: Scheme manifest.
|
/// - scheme: Scheme manifest.
|
||||||
/// - project: Project manifest.
|
/// - graph: Tuist graph.
|
||||||
/// - generatedProject: Generated Xcode project.
|
/// - rootPath: Root path to either project or workspace.
|
||||||
|
/// - generatedProjects: Project paths mapped to generated projects.
|
||||||
/// - Returns: Scheme launch action.
|
/// - Returns: Scheme launch action.
|
||||||
func schemeLaunchAction(scheme: Scheme,
|
func schemeLaunchAction(scheme: Scheme,
|
||||||
project: Project,
|
graph: Graphing,
|
||||||
generatedProject: GeneratedProject) -> XCScheme.LaunchAction? {
|
rootPath: AbsolutePath,
|
||||||
guard var target = project.targets.first(where: { $0.name == scheme.buildAction?.targets.first }) else { return nil }
|
generatedProjects: [AbsolutePath: GeneratedProject]) throws -> XCScheme.LaunchAction? {
|
||||||
|
guard var target = try defaultTargetReference(scheme: scheme) else { return nil }
|
||||||
|
|
||||||
if let executable = scheme.runAction?.executable {
|
if let executable = scheme.runAction?.executable {
|
||||||
guard let runableTarget = project.targets.first(where: { $0.name == executable }) else { return nil }
|
target = executable
|
||||||
target = runableTarget
|
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let pbxTarget = generatedProject.targets[target.name] else { return nil }
|
guard let targetNode = try graph.target(path: target.projectPath, name: target.name) else { return nil }
|
||||||
|
guard let buildableReference = try createBuildableReference(targetReference: target,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: rootPath,
|
||||||
|
generatedProjects: generatedProjects) else { return nil }
|
||||||
|
|
||||||
var buildableProductRunnable: XCScheme.BuildableProductRunnable?
|
var buildableProductRunnable: XCScheme.BuildableProductRunnable?
|
||||||
var macroExpansion: XCScheme.BuildableReference?
|
var macroExpansion: XCScheme.BuildableReference?
|
||||||
let buildableReference = targetBuildableReference(target: target, pbxTarget: pbxTarget, projectName: generatedProject.name)
|
|
||||||
if target.product.runnable {
|
if targetNode.target.product.runnable {
|
||||||
buildableProductRunnable = XCScheme.BuildableProductRunnable(buildableReference: buildableReference, runnableDebuggingMode: "0")
|
buildableProductRunnable = XCScheme.BuildableProductRunnable(buildableReference: buildableReference, runnableDebuggingMode: "0")
|
||||||
} else {
|
} else {
|
||||||
macroExpansion = buildableReference
|
macroExpansion = buildableReference
|
||||||
|
@ -343,127 +286,276 @@ final class SchemesGenerator: SchemesGenerating {
|
||||||
environments = environmentVariables(arguments.environment)
|
environments = environmentVariables(arguments.environment)
|
||||||
}
|
}
|
||||||
|
|
||||||
let buildConfiguration = scheme.runAction?.configurationName ?? defaultDebugBuildConfigurationName(in: project)
|
let buildConfiguration = scheme.runAction?.configurationName ?? defaultDebugBuildConfigurationName(in: targetNode.project)
|
||||||
return XCScheme.LaunchAction(runnable: buildableProductRunnable,
|
return XCScheme.LaunchAction(runnable: buildableProductRunnable,
|
||||||
buildConfiguration: buildConfiguration,
|
buildConfiguration: buildConfiguration,
|
||||||
macroExpansion: macroExpansion,
|
macroExpansion: macroExpansion,
|
||||||
commandlineArguments: commandlineArguments,
|
commandlineArguments: commandlineArguments,
|
||||||
environmentVariables: environments)
|
environmentVariables: environments)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates the scheme profile action for a given target.
|
/// Generates the scheme profile action for a given target.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - target: Target manifest.
|
/// - scheme: Target manifest.
|
||||||
/// - pbxTarget: Xcode native target.
|
/// - graph: Tuist graph.
|
||||||
/// - projectName: Project name with .xcodeproj extension.
|
/// - rootPath: Root path to either project or workspace.
|
||||||
|
/// - generatedProjects: Project paths mapped to generated projects.
|
||||||
/// - Returns: Scheme profile action.
|
/// - Returns: Scheme profile action.
|
||||||
func schemeProfileAction(scheme: Scheme,
|
func schemeProfileAction(scheme: Scheme,
|
||||||
project: Project,
|
graph: Graphing,
|
||||||
generatedProject: GeneratedProject) -> XCScheme.ProfileAction? {
|
rootPath: AbsolutePath,
|
||||||
guard var target = project.targets.first(where: { $0.name == scheme.buildAction?.targets.first }) else { return nil }
|
generatedProjects: [AbsolutePath: GeneratedProject]) throws -> XCScheme.ProfileAction? {
|
||||||
|
|
||||||
|
guard var target = try defaultTargetReference(scheme: scheme) else { return nil }
|
||||||
if let executable = scheme.runAction?.executable {
|
if let executable = scheme.runAction?.executable {
|
||||||
guard let runableTarget = project.targets.first(where: { $0.name == executable }) else { return nil }
|
target = executable
|
||||||
target = runableTarget
|
|
||||||
}
|
}
|
||||||
|
guard let targetNode = try graph.target(path: target.projectPath, name: target.name) else { return nil }
|
||||||
guard let pbxTarget = generatedProject.targets[target.name] else { return nil }
|
guard let buildableReference = try createBuildableReference(targetReference: target,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: rootPath,
|
||||||
|
generatedProjects: generatedProjects) else { return nil }
|
||||||
|
|
||||||
var buildableProductRunnable: XCScheme.BuildableProductRunnable?
|
var buildableProductRunnable: XCScheme.BuildableProductRunnable?
|
||||||
var macroExpansion: XCScheme.BuildableReference?
|
var macroExpansion: XCScheme.BuildableReference?
|
||||||
let buildableReference = targetBuildableReference(target: target, pbxTarget: pbxTarget, projectName: generatedProject.name)
|
|
||||||
|
if targetNode.target.product.runnable {
|
||||||
if target.product.runnable {
|
|
||||||
buildableProductRunnable = XCScheme.BuildableProductRunnable(buildableReference: buildableReference, runnableDebuggingMode: "0")
|
buildableProductRunnable = XCScheme.BuildableProductRunnable(buildableReference: buildableReference, runnableDebuggingMode: "0")
|
||||||
} else {
|
} else {
|
||||||
macroExpansion = buildableReference
|
macroExpansion = buildableReference
|
||||||
}
|
}
|
||||||
|
|
||||||
let buildConfiguration = defaultReleaseBuildConfigurationName(in: project)
|
let buildConfiguration = defaultReleaseBuildConfigurationName(in: targetNode.project)
|
||||||
return XCScheme.ProfileAction(buildableProductRunnable: buildableProductRunnable,
|
return XCScheme.ProfileAction(buildableProductRunnable: buildableProductRunnable,
|
||||||
buildConfiguration: buildConfiguration,
|
buildConfiguration: buildConfiguration,
|
||||||
macroExpansion: macroExpansion)
|
macroExpansion: macroExpansion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the scheme analyze action.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - scheme: Scheme manifest.
|
||||||
|
/// - graph: Tuist graph.
|
||||||
|
/// - rootPath: Root path to either project or workspace.
|
||||||
|
/// - generatedProjects: Project paths mapped to generated projects.
|
||||||
|
/// - Returns: Scheme analyze action.
|
||||||
|
func schemeAnalyzeAction(scheme: Scheme,
|
||||||
|
graph: Graphing,
|
||||||
|
rootPath: AbsolutePath,
|
||||||
|
generatedProjects: [AbsolutePath: GeneratedProject]) throws -> XCScheme.AnalyzeAction? {
|
||||||
|
guard let target = try defaultTargetReference(scheme: scheme),
|
||||||
|
let targetNode = try graph.target(path: target.projectPath, name: target.name) else { return nil }
|
||||||
|
|
||||||
|
let buildConfiguration = defaultDebugBuildConfigurationName(in: targetNode.project)
|
||||||
|
return XCScheme.AnalyzeAction(buildConfiguration: buildConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates the scheme archive action.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - scheme: Scheme manifest.
|
||||||
|
/// - graph: Tuist graph.
|
||||||
|
/// - rootPath: Root path to either project or workspace.
|
||||||
|
/// - generatedProjects: Project paths mapped to generated projects.
|
||||||
|
/// - Returns: Scheme archive action.
|
||||||
|
func schemeArchiveAction(scheme: Scheme,
|
||||||
|
graph: Graphing,
|
||||||
|
rootPath: AbsolutePath,
|
||||||
|
generatedProjects: [AbsolutePath: GeneratedProject]) throws -> XCScheme.ArchiveAction? {
|
||||||
|
|
||||||
|
guard let target = try defaultTargetReference(scheme: scheme),
|
||||||
|
let targetNode = try graph.target(path: target.projectPath, name: target.name) else { return nil }
|
||||||
|
|
||||||
|
guard let archiveAction = scheme.archiveAction else {
|
||||||
|
return defaultSchemeArchiveAction(for: targetNode.project)
|
||||||
|
}
|
||||||
|
|
||||||
|
let preActions = try archiveAction.preActions.map {
|
||||||
|
try schemeExecutionAction(action: $0, graph: graph, generatedProjects: generatedProjects, rootPath: rootPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
let postActions = try archiveAction.postActions.map {
|
||||||
|
try schemeExecutionAction(action: $0, graph: graph, generatedProjects: generatedProjects, rootPath: rootPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return XCScheme.ArchiveAction(buildConfiguration: archiveAction.configurationName,
|
||||||
|
revealArchiveInOrganizer: archiveAction.revealArchiveInOrganizer,
|
||||||
|
customArchiveName: archiveAction.customArchiveName,
|
||||||
|
preActions: preActions,
|
||||||
|
postActions: postActions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func schemeExecutionAction(action: ExecutionAction,
|
||||||
|
graph: Graphing,
|
||||||
|
generatedProjects: [AbsolutePath: GeneratedProject],
|
||||||
|
rootPath: AbsolutePath) throws -> XCScheme.ExecutionAction {
|
||||||
|
|
||||||
|
guard let targetReference = action.target,
|
||||||
|
let targetNode = try graph.target(path: targetReference.projectPath, name: targetReference.name),
|
||||||
|
let generatedProject = generatedProjects[targetReference.projectPath] else {
|
||||||
|
return schemeExecutionAction(action: action)
|
||||||
|
}
|
||||||
|
return schemeExecutionAction(action: action,
|
||||||
|
target: targetNode.target,
|
||||||
|
generatedProject: generatedProject)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func schemeExecutionAction(action: ExecutionAction) -> XCScheme.ExecutionAction {
|
||||||
|
return XCScheme.ExecutionAction(scriptText: action.scriptText,
|
||||||
|
title: action.title,
|
||||||
|
environmentBuildable: nil)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the scheme pre/post actions.
|
/// Returns the scheme pre/post actions.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - actions: pre/post action manifest.
|
/// - action: pre/post action manifest.
|
||||||
/// - project: Project manifest.
|
/// - target: Project manifest.
|
||||||
/// - generatedProject: Generated Xcode project.
|
/// - generatedProject: Generated Xcode project.
|
||||||
/// - Returns: Scheme actions.
|
/// - Returns: Scheme actions.
|
||||||
func schemeExecutionActions(actions: [ExecutionAction],
|
private func schemeExecutionAction(action: ExecutionAction,
|
||||||
project: Project,
|
target: Target,
|
||||||
generatedProject: GeneratedProject) -> [XCScheme.ExecutionAction] {
|
generatedProject: GeneratedProject) -> XCScheme.ExecutionAction {
|
||||||
/// Return Buildable Reference for Scheme Action
|
/// Return Buildable Reference for Scheme Action
|
||||||
func schemeBuildableReference(targetName: String?, project: Project, generatedProject: GeneratedProject) -> XCScheme.BuildableReference? {
|
func schemeBuildableReference(target: Target, generatedProject: GeneratedProject) -> XCScheme.BuildableReference? {
|
||||||
guard let targetName = targetName else { return nil }
|
guard let pbxTarget = generatedProject.targets[target.name] else { return nil }
|
||||||
guard let target = project.targets.first(where: { $0.name == targetName }) else { return nil }
|
|
||||||
guard let pbxTarget = generatedProject.targets[targetName] else { return nil }
|
return targetBuildableReference(target: target,
|
||||||
|
pbxTarget: pbxTarget,
|
||||||
return targetBuildableReference(target: target, pbxTarget: pbxTarget, projectName: generatedProject.name)
|
projectPath: generatedProject.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
var schemeActions: [XCScheme.ExecutionAction] = []
|
let schemeAction = XCScheme.ExecutionAction(scriptText: action.scriptText,
|
||||||
actions.forEach { action in
|
title: action.title,
|
||||||
let schemeAction = XCScheme.ExecutionAction(scriptText: action.scriptText,
|
environmentBuildable: nil)
|
||||||
title: action.title,
|
|
||||||
environmentBuildable: nil)
|
|
||||||
|
|
||||||
schemeAction.environmentBuildable = schemeBuildableReference(targetName: action.target,
|
schemeAction.environmentBuildable = schemeBuildableReference(target: target,
|
||||||
project: project,
|
generatedProject: generatedProject)
|
||||||
generatedProject: generatedProject)
|
return schemeAction
|
||||||
schemeActions.append(schemeAction)
|
|
||||||
}
|
|
||||||
return schemeActions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Helpers
|
||||||
|
|
||||||
|
private func resolveRelativeProjectPath(targetNode: TargetNode,
|
||||||
|
generatedProject: GeneratedProject,
|
||||||
|
rootPath: AbsolutePath) -> RelativePath {
|
||||||
|
let xcodeProjectPath = targetNode.path.appending(component: generatedProject.name)
|
||||||
|
return xcodeProjectPath.relative(to: rootPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a target buildable refernece for a target
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - targetReference: The target reference.
|
||||||
|
/// - graph: Tuist graph.
|
||||||
|
/// - rootPath: Path to the project or workspace.
|
||||||
|
/// - generatedProjects: Project paths mapped to generated projects.
|
||||||
|
private func createBuildableReference(targetReference: TargetReference,
|
||||||
|
graph: Graphing,
|
||||||
|
rootPath: AbsolutePath,
|
||||||
|
generatedProjects: [AbsolutePath: GeneratedProject]) throws -> XCScheme.BuildableReference? {
|
||||||
|
|
||||||
|
let projectPath = targetReference.projectPath
|
||||||
|
guard let target = try graph.target(path: projectPath, name: targetReference.name) else { return nil }
|
||||||
|
guard let generatedProject = generatedProjects[projectPath] else { return nil }
|
||||||
|
guard let pbxTarget = generatedProject.targets[targetReference.name] else { return nil }
|
||||||
|
let relativeXcodeProjectPath = resolveRelativeProjectPath(targetNode: target,
|
||||||
|
generatedProject: generatedProject,
|
||||||
|
rootPath: rootPath)
|
||||||
|
|
||||||
|
return targetBuildableReference(target: target.target,
|
||||||
|
pbxTarget: pbxTarget,
|
||||||
|
projectPath: relativeXcodeProjectPath.pathString)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates the array of BuildableReference for targets that the
|
||||||
|
/// coverage report should be generated for them.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - target: test actions.
|
||||||
|
/// - graph: tuist graph.
|
||||||
|
/// - generatedProjects: Generated Xcode projects.
|
||||||
|
/// - rootPath: Root path to workspace or project.
|
||||||
|
/// - Returns: Array of buildable references.
|
||||||
|
private func testCoverageTargetReferences(target: TargetReference,
|
||||||
|
graph: Graphing,
|
||||||
|
generatedProjects: [AbsolutePath: GeneratedProject],
|
||||||
|
rootPath: AbsolutePath) throws -> XCScheme.BuildableReference? {
|
||||||
|
return try createBuildableReference(targetReference: target,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: rootPath,
|
||||||
|
generatedProjects: generatedProjects)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates the directory where the schemes are stored inside the project.
|
||||||
|
/// If the directory exists it does not re-create it.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - path: Path to the Xcode workspace or project.
|
||||||
|
/// - shared: Scheme should be shared or not
|
||||||
|
/// - Returns: Path to the schemes directory.
|
||||||
|
/// - Throws: A FatalError if the creation of the directory fails.
|
||||||
|
private func createSchemesDirectory(path: AbsolutePath, shared: Bool = true) throws -> AbsolutePath {
|
||||||
|
let schemePath: AbsolutePath
|
||||||
|
if shared {
|
||||||
|
schemePath = path.appending(RelativePath("xcshareddata/xcschemes"))
|
||||||
|
} else {
|
||||||
|
let username = NSUserName()
|
||||||
|
schemePath = path.appending(RelativePath("xcuserdata/\(username).xcuserdatad/xcschemes"))
|
||||||
|
}
|
||||||
|
if !FileHandler.shared.exists(schemePath) {
|
||||||
|
try FileHandler.shared.createFolder(schemePath)
|
||||||
|
}
|
||||||
|
return schemePath
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the scheme commandline argument passed on launch
|
/// Returns the scheme commandline argument passed on launch
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - environments: commandline argument keys.
|
/// - environments: commandline argument keys.
|
||||||
/// - Returns: XCScheme.CommandLineArguments.CommandLineArgument.
|
/// - Returns: XCScheme.CommandLineArguments.CommandLineArgument.
|
||||||
func commandlineArgruments(_ arguments: [String: Bool]) -> [XCScheme.CommandLineArguments.CommandLineArgument] {
|
private func commandlineArgruments(_ arguments: [String: Bool]) -> [XCScheme.CommandLineArguments.CommandLineArgument] {
|
||||||
return arguments.map { key, enabled in
|
return arguments.map { key, enabled in
|
||||||
XCScheme.CommandLineArguments.CommandLineArgument(name: key, enabled: enabled)
|
XCScheme.CommandLineArguments.CommandLineArgument(name: key, enabled: enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the scheme environment variables
|
/// Returns the scheme environment variables
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - environments: environment variables
|
/// - environments: environment variables
|
||||||
/// - Returns: XCScheme.EnvironmentVariable.
|
/// - Returns: XCScheme.EnvironmentVariable.
|
||||||
func environmentVariables(_ environments: [String: String]) -> [XCScheme.EnvironmentVariable] {
|
private func environmentVariables(_ environments: [String: String]) -> [XCScheme.EnvironmentVariable] {
|
||||||
return environments.map { key, value in
|
return environments.map { key, value in
|
||||||
XCScheme.EnvironmentVariable(variable: key, value: value, enabled: true)
|
XCScheme.EnvironmentVariable(variable: key, value: value, enabled: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func defaultDebugBuildConfigurationName(in project: Project) -> String {
|
||||||
|
let debugConfiguration = project.settings.defaultDebugBuildConfiguration()
|
||||||
|
let buildConfiguration = debugConfiguration ?? project.settings.configurations.keys.first
|
||||||
|
|
||||||
|
return buildConfiguration?.name ?? BuildConfiguration.debug.name
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the scheme buildable reference for a given target.
|
/// Returns the scheme buildable reference for a given target.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - target: Target manifest.
|
/// - target: Target manifest.
|
||||||
/// - pbxTarget: Xcode native target.
|
/// - pbxTarget: Xcode native target.
|
||||||
/// - projectName: Project name with the .xcodeproj extension.
|
/// - projectPath: Project name with the .xcodeproj extension.
|
||||||
/// - Returns: Buildable reference.
|
/// - Returns: Buildable reference.
|
||||||
func targetBuildableReference(target: Target, pbxTarget: PBXNativeTarget, projectName: String) -> XCScheme.BuildableReference {
|
private func targetBuildableReference(target: Target,
|
||||||
return XCScheme.BuildableReference(referencedContainer: "container:\(projectName)",
|
pbxTarget: PBXNativeTarget,
|
||||||
|
projectPath: String) -> XCScheme.BuildableReference {
|
||||||
|
return XCScheme.BuildableReference(referencedContainer: "container:\(projectPath)",
|
||||||
blueprint: pbxTarget,
|
blueprint: pbxTarget,
|
||||||
buildableName: target.productNameWithExtension,
|
buildableName: target.productNameWithExtension,
|
||||||
blueprintName: target.name,
|
blueprintName: target.name,
|
||||||
buildableIdentifier: "primary")
|
buildableIdentifier: "primary")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the scheme analyze action
|
|
||||||
///
|
|
||||||
/// - Returns: Scheme analyze action.
|
|
||||||
func schemeAnalyzeAction(for project: Project) -> XCScheme.AnalyzeAction {
|
|
||||||
let buildConfiguration = defaultDebugBuildConfigurationName(in: project)
|
|
||||||
return XCScheme.AnalyzeAction(buildConfiguration: buildConfiguration)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the scheme archive action
|
/// Returns the scheme archive action
|
||||||
///
|
///
|
||||||
/// - Returns: Scheme archive action.
|
/// - Returns: Scheme archive action.
|
||||||
|
@ -472,40 +564,15 @@ final class SchemesGenerator: SchemesGenerating {
|
||||||
return XCScheme.ArchiveAction(buildConfiguration: buildConfiguration,
|
return XCScheme.ArchiveAction(buildConfiguration: buildConfiguration,
|
||||||
revealArchiveInOrganizer: true)
|
revealArchiveInOrganizer: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates the directory where the schemes are stored inside the project.
|
|
||||||
/// If the directory exists it does not re-create it.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - projectPath: Path to the Xcode project.
|
|
||||||
/// - shared: Scheme should be shared or not
|
|
||||||
/// - Returns: Path to the schemes directory.
|
|
||||||
/// - Throws: A FatalError if the creation of the directory fails.
|
|
||||||
private func createSchemesDirectory(projectPath: AbsolutePath, shared: Bool = true) throws -> AbsolutePath {
|
|
||||||
var path: AbsolutePath!
|
|
||||||
if shared {
|
|
||||||
path = projectPath.appending(RelativePath("xcshareddata/xcschemes"))
|
|
||||||
} else {
|
|
||||||
let username = NSUserName()
|
|
||||||
path = projectPath.appending(RelativePath("xcuserdata/\(username).xcuserdatad/xcschemes"))
|
|
||||||
}
|
|
||||||
if !FileHandler.shared.exists(path) {
|
|
||||||
try FileHandler.shared.createFolder(path)
|
|
||||||
}
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
|
|
||||||
private func defaultDebugBuildConfigurationName(in project: Project) -> String {
|
|
||||||
let debugConfiguration = project.settings.defaultDebugBuildConfiguration()
|
|
||||||
let buildConfiguration = debugConfiguration ?? project.settings.configurations.keys.first
|
|
||||||
|
|
||||||
return buildConfiguration?.name ?? BuildConfiguration.debug.name
|
|
||||||
}
|
|
||||||
|
|
||||||
private func defaultReleaseBuildConfigurationName(in project: Project) -> String {
|
private func defaultReleaseBuildConfigurationName(in project: Project) -> String {
|
||||||
let releaseConfiguration = project.settings.defaultReleaseBuildConfiguration()
|
let releaseConfiguration = project.settings.defaultReleaseBuildConfiguration()
|
||||||
let buildConfiguration = releaseConfiguration ?? project.settings.configurations.keys.first
|
let buildConfiguration = releaseConfiguration ?? project.settings.configurations.keys.first
|
||||||
|
|
||||||
return buildConfiguration?.name ?? BuildConfiguration.release.name
|
return buildConfiguration?.name ?? BuildConfiguration.release.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func defaultTargetReference(scheme: Scheme) throws -> TargetReference? {
|
||||||
|
return scheme.buildAction?.targets.first
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,8 +66,8 @@ private extension SchemeLinter {
|
||||||
|
|
||||||
for scheme in schemes {
|
for scheme in schemes {
|
||||||
for target in scheme.testAction?.codeCoverageTargets ?? [] {
|
for target in scheme.testAction?.codeCoverageTargets ?? [] {
|
||||||
if !targetNames.contains(target) {
|
if !targetNames.contains(target.name) {
|
||||||
issues.append(missingCodeCoverageTargetIssue(missingTargetName: target, schemaName: scheme.name))
|
issues.append(missingCodeCoverageTargetIssue(missingTargetName: target.name, schemaName: scheme.name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,7 +225,7 @@ extension TuistCore.Project {
|
||||||
generatorPaths: generatorPaths)
|
generatorPaths: generatorPaths)
|
||||||
}
|
}
|
||||||
|
|
||||||
let schemes = manifest.schemes.map { TuistCore.Scheme.from(manifest: $0) }
|
let schemes = manifest.schemes.map { TuistCore.Scheme.from(manifest: $0, projectPath: path) }
|
||||||
|
|
||||||
let additionalFiles = try manifest.additionalFiles.flatMap {
|
let additionalFiles = try manifest.additionalFiles.flatMap {
|
||||||
try TuistCore.FileElement.from(manifest: $0,
|
try TuistCore.FileElement.from(manifest: $0,
|
||||||
|
@ -273,6 +273,7 @@ extension TuistCore.Project {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TuistCore.Target {
|
extension TuistCore.Target {
|
||||||
|
// swiftlint:disable:next function_body_length
|
||||||
static func from(manifest: ProjectDescription.Target,
|
static func from(manifest: ProjectDescription.Target,
|
||||||
path: AbsolutePath,
|
path: AbsolutePath,
|
||||||
generatorPaths: GeneratorPaths) throws -> TuistCore.Target {
|
generatorPaths: GeneratorPaths) throws -> TuistCore.Target {
|
||||||
|
@ -569,13 +570,13 @@ extension TuistCore.Dependency {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TuistCore.Scheme {
|
extension TuistCore.Scheme {
|
||||||
static func from(manifest: ProjectDescription.Scheme) -> TuistCore.Scheme {
|
static func from(manifest: ProjectDescription.Scheme, projectPath: AbsolutePath) -> TuistCore.Scheme {
|
||||||
let name = manifest.name
|
let name = manifest.name
|
||||||
let shared = manifest.shared
|
let shared = manifest.shared
|
||||||
let buildAction = manifest.buildAction.map { TuistCore.BuildAction.from(manifest: $0) }
|
let buildAction = manifest.buildAction.map { TuistCore.BuildAction.from(manifest: $0, projectPath: projectPath) }
|
||||||
let testAction = manifest.testAction.map { TuistCore.TestAction.from(manifest: $0) }
|
let testAction = manifest.testAction.map { TuistCore.TestAction.from(manifest: $0, projectPath: projectPath) }
|
||||||
let runAction = manifest.runAction.map { TuistCore.RunAction.from(manifest: $0) }
|
let runAction = manifest.runAction.map { TuistCore.RunAction.from(manifest: $0, projectPath: projectPath) }
|
||||||
let archiveAction = manifest.archiveAction.map { TuistCore.ArchiveAction.from(manifest: $0) }
|
let archiveAction = manifest.archiveAction.map { TuistCore.ArchiveAction.from(manifest: $0, projectPath: projectPath) }
|
||||||
|
|
||||||
return Scheme(name: name,
|
return Scheme(name: name,
|
||||||
shared: shared,
|
shared: shared,
|
||||||
|
@ -587,24 +588,26 @@ extension TuistCore.Scheme {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TuistCore.BuildAction {
|
extension TuistCore.BuildAction {
|
||||||
static func from(manifest: ProjectDescription.BuildAction) -> TuistCore.BuildAction {
|
static func from(manifest: ProjectDescription.BuildAction, projectPath: AbsolutePath) -> TuistCore.BuildAction {
|
||||||
let preActions = manifest.preActions.map { TuistCore.ExecutionAction.from(manifest: $0) }
|
let preActions = manifest.preActions.map { TuistCore.ExecutionAction.from(manifest: $0, projectPath: projectPath) }
|
||||||
let postActions = manifest.postActions.map { TuistCore.ExecutionAction.from(manifest: $0) }
|
let postActions = manifest.postActions.map { TuistCore.ExecutionAction.from(manifest: $0, projectPath: projectPath) }
|
||||||
|
let targets: [TuistCore.TargetReference] = manifest.targets.map {
|
||||||
return BuildAction(targets: manifest.targets, preActions: preActions, postActions: postActions)
|
.project(path: projectPath, target: $0)
|
||||||
|
}
|
||||||
|
return TuistCore.BuildAction(targets: targets, preActions: preActions, postActions: postActions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TuistCore.TestAction {
|
extension TuistCore.TestAction {
|
||||||
static func from(manifest: ProjectDescription.TestAction) -> TuistCore.TestAction {
|
static func from(manifest: ProjectDescription.TestAction, projectPath: AbsolutePath) -> TuistCore.TestAction {
|
||||||
let targets = manifest.targets.map { TuistCore.TestableTarget.from(manifest: $0) }
|
let targets = manifest.targets.map { TuistCore.TestableTarget.from(manifest: $0, projectPath: projectPath) }
|
||||||
let arguments = manifest.arguments.map { TuistCore.Arguments.from(manifest: $0) }
|
let arguments = manifest.arguments.map { TuistCore.Arguments.from(manifest: $0) }
|
||||||
let configurationName = manifest.configurationName
|
let configurationName = manifest.configurationName
|
||||||
let coverage = manifest.coverage
|
let coverage = manifest.coverage
|
||||||
let codeCoverageTargets = manifest.codeCoverageTargets
|
let codeCoverageTargets = manifest.codeCoverageTargets.map { TuistCore.TargetReference(projectPath: projectPath, name: $0) }
|
||||||
let preActions = manifest.preActions.map { TuistCore.ExecutionAction.from(manifest: $0) }
|
let preActions = manifest.preActions.map { TuistCore.ExecutionAction.from(manifest: $0, projectPath: projectPath) }
|
||||||
let postActions = manifest.postActions.map { TuistCore.ExecutionAction.from(manifest: $0) }
|
let postActions = manifest.postActions.map { TuistCore.ExecutionAction.from(manifest: $0, projectPath: projectPath) }
|
||||||
|
|
||||||
return TestAction(targets: targets,
|
return TestAction(targets: targets,
|
||||||
arguments: arguments,
|
arguments: arguments,
|
||||||
configurationName: configurationName,
|
configurationName: configurationName,
|
||||||
|
@ -616,8 +619,8 @@ extension TuistCore.TestAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TuistCore.TestableTarget {
|
extension TuistCore.TestableTarget {
|
||||||
static func from(manifest: ProjectDescription.TestableTarget) -> TuistCore.TestableTarget {
|
static func from(manifest: ProjectDescription.TestableTarget, projectPath: AbsolutePath) -> TuistCore.TestableTarget {
|
||||||
return TestableTarget(target: manifest.target,
|
return TestableTarget(target: TuistCore.TargetReference(projectPath: projectPath, name: manifest.target),
|
||||||
skipped: manifest.isSkipped,
|
skipped: manifest.isSkipped,
|
||||||
parallelizable: manifest.isParallelizable,
|
parallelizable: manifest.isParallelizable,
|
||||||
randomExecutionOrdering: manifest.isRandomExecutionOrdering)
|
randomExecutionOrdering: manifest.isRandomExecutionOrdering)
|
||||||
|
@ -625,24 +628,28 @@ extension TuistCore.TestableTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TuistCore.RunAction {
|
extension TuistCore.RunAction {
|
||||||
static func from(manifest: ProjectDescription.RunAction) -> TuistCore.RunAction {
|
static func from(manifest: ProjectDescription.RunAction, projectPath: AbsolutePath) -> TuistCore.RunAction {
|
||||||
let configurationName = manifest.configurationName
|
let configurationName = manifest.configurationName
|
||||||
let executable = manifest.executable
|
|
||||||
let arguments = manifest.arguments.map { TuistCore.Arguments.from(manifest: $0) }
|
let arguments = manifest.arguments.map { TuistCore.Arguments.from(manifest: $0) }
|
||||||
|
|
||||||
|
var executableResolved: TuistCore.TargetReference?
|
||||||
|
if let executable = manifest.executable {
|
||||||
|
executableResolved = TargetReference(projectPath: projectPath, name: executable)
|
||||||
|
}
|
||||||
|
|
||||||
return RunAction(configurationName: configurationName,
|
return RunAction(configurationName: configurationName,
|
||||||
executable: executable,
|
executable: executableResolved,
|
||||||
arguments: arguments)
|
arguments: arguments)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TuistCore.ArchiveAction {
|
extension TuistCore.ArchiveAction {
|
||||||
static func from(manifest: ProjectDescription.ArchiveAction) -> TuistCore.ArchiveAction {
|
static func from(manifest: ProjectDescription.ArchiveAction, projectPath: AbsolutePath) -> TuistCore.ArchiveAction {
|
||||||
let configurationName = manifest.configurationName
|
let configurationName = manifest.configurationName
|
||||||
let revealArchiveInOrganizer = manifest.revealArchiveInOrganizer
|
let revealArchiveInOrganizer = manifest.revealArchiveInOrganizer
|
||||||
let customArchiveName = manifest.customArchiveName
|
let customArchiveName = manifest.customArchiveName
|
||||||
let preActions = manifest.preActions.map { TuistCore.ExecutionAction.from(manifest: $0) }
|
let preActions = manifest.preActions.map { TuistCore.ExecutionAction.from(manifest: $0, projectPath: projectPath) }
|
||||||
let postActions = manifest.postActions.map { TuistCore.ExecutionAction.from(manifest: $0) }
|
let postActions = manifest.postActions.map { TuistCore.ExecutionAction.from(manifest: $0, projectPath: projectPath) }
|
||||||
|
|
||||||
return TuistCore.ArchiveAction(configurationName: configurationName,
|
return TuistCore.ArchiveAction(configurationName: configurationName,
|
||||||
revealArchiveInOrganizer: revealArchiveInOrganizer,
|
revealArchiveInOrganizer: revealArchiveInOrganizer,
|
||||||
|
@ -653,8 +660,10 @@ extension TuistCore.ArchiveAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TuistCore.ExecutionAction {
|
extension TuistCore.ExecutionAction {
|
||||||
static func from(manifest: ProjectDescription.ExecutionAction) -> TuistCore.ExecutionAction {
|
static func from(manifest: ProjectDescription.ExecutionAction,
|
||||||
return ExecutionAction(title: manifest.title, scriptText: manifest.scriptText, target: manifest.target)
|
projectPath: AbsolutePath) -> TuistCore.ExecutionAction {
|
||||||
|
let targetReference: TuistCore.TargetReference? = manifest.target.map { .project(path: projectPath, target: $0) }
|
||||||
|
return ExecutionAction(title: manifest.title, scriptText: manifest.scriptText, target: targetReference)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import Basic
|
||||||
import TuistCore
|
import TuistCore
|
||||||
import TuistCoreTesting
|
import TuistCoreTesting
|
||||||
@testable import TuistGenerator
|
@testable import TuistGenerator
|
||||||
|
|
||||||
final class MockSchemesGenerator: SchemesGenerating {
|
final class MockSchemesGenerator: SchemesGenerating {
|
||||||
var generateTargetSchemesArgs: [(project: Project, generatedProject: GeneratedProject)] = []
|
var generateProjectSchemeArgs: [(project: Project, xcprojectPath: AbsolutePath, generatedProject: GeneratedProject, graph: Graphing)] = []
|
||||||
var generateProjectSchemeArgs: [(project: Project, generatedProject: GeneratedProject, graph: Graphing)] = []
|
|
||||||
|
func generateProjectSchemes(project: Project, xcprojectPath: AbsolutePath, generatedProject: GeneratedProject, graph: Graphing) throws {
|
||||||
func generateTargetSchemes(project: Project, generatedProject: GeneratedProject) throws {
|
generateProjectSchemeArgs.append((project: project, xcprojectPath: xcprojectPath, generatedProject: generatedProject, graph: graph))
|
||||||
generateTargetSchemesArgs.append((project: project, generatedProject: generatedProject))
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateProjectScheme(project: Project, generatedProject: GeneratedProject, graph: Graphing) throws {
|
|
||||||
generateProjectSchemeArgs.append((project: project, generatedProject: generatedProject, graph: graph))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ final class ProjectGeneratorTests: TuistUnitTestCase {
|
||||||
// Given
|
// Given
|
||||||
let temporaryPath = try self.temporaryPath()
|
let temporaryPath = try self.temporaryPath()
|
||||||
let target = Target.test(name: "Target", platform: .iOS, product: .framework)
|
let target = Target.test(name: "Target", platform: .iOS, product: .framework)
|
||||||
let sharedScheme = Scheme.test(name: "Target-Scheme", shared: true, buildAction: BuildAction(targets: ["Target"]))
|
let sharedScheme = Scheme.test(name: "Target-Scheme", shared: true, buildAction: BuildAction(targets: [TargetReference(projectPath: temporaryPath, name: "Target")]))
|
||||||
|
|
||||||
let targets = [target]
|
let targets = [target]
|
||||||
let project = Project.test(path: temporaryPath, name: "Project", targets: targets, schemes: [sharedScheme])
|
let project = Project.test(path: temporaryPath, name: "Project", targets: targets, schemes: [sharedScheme])
|
||||||
|
@ -79,7 +79,7 @@ final class ProjectGeneratorTests: TuistUnitTestCase {
|
||||||
// Given
|
// Given
|
||||||
let temporaryPath = try self.temporaryPath()
|
let temporaryPath = try self.temporaryPath()
|
||||||
let target = Target.test(name: "Target", platform: .iOS, product: .framework)
|
let target = Target.test(name: "Target", platform: .iOS, product: .framework)
|
||||||
let localScheme = Scheme.test(name: "Target-Local", shared: false, buildAction: BuildAction(targets: ["Target"]))
|
let localScheme = Scheme.test(name: "Target-Local", shared: false, buildAction: BuildAction(targets: [TargetReference(projectPath: temporaryPath, name: "Target")]))
|
||||||
|
|
||||||
let targets = [target]
|
let targets = [target]
|
||||||
let project = Project.test(path: temporaryPath, name: "Project", targets: targets, schemes: [localScheme])
|
let project = Project.test(path: temporaryPath, name: "Project", targets: targets, schemes: [localScheme])
|
||||||
|
|
|
@ -9,374 +9,518 @@ import XCTest
|
||||||
@testable import TuistGenerator
|
@testable import TuistGenerator
|
||||||
@testable import TuistSupportTesting
|
@testable import TuistSupportTesting
|
||||||
|
|
||||||
final class SchemeGeneratorTests: XCTestCase {
|
final class SchemesGeneratorTests: XCTestCase {
|
||||||
var subject: SchemesGenerator!
|
var subject: SchemesGenerator!
|
||||||
|
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
subject = SchemesGenerator()
|
subject = SchemesGenerator()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Build Action Tests
|
||||||
|
|
||||||
func test_projectBuildAction() {
|
func test_schemeBuildAction_whenSingleProject() throws {
|
||||||
|
// Given
|
||||||
|
let projectPath = AbsolutePath("/somepath/Workspace/Projects/Project")
|
||||||
|
let scheme = Scheme.test(buildAction: BuildAction(targets: [TargetReference(projectPath: projectPath, name: "App")]))
|
||||||
|
|
||||||
let app = Target.test(name: "App", product: .app)
|
let app = Target.test(name: "App", product: .app)
|
||||||
let appTests = Target.test(name: "AppTests", product: .unitTests)
|
let targets = [app]
|
||||||
let appUITests = Target.test(name: "AppUITests", product: .uiTests)
|
|
||||||
let targets = [app, appTests, appUITests]
|
let project = Project.test(path: projectPath)
|
||||||
|
let graph = Graph.create(dependencies: [(project: project, target: app, dependencies: [])])
|
||||||
|
|
||||||
|
// Then
|
||||||
|
let got = try subject.schemeBuildAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: AbsolutePath("/somepath/Workspace"),
|
||||||
|
generatedProjects: [projectPath:
|
||||||
|
generatedProject(targets: targets, projectPath: "\(projectPath)/project.xcodeproj")])
|
||||||
|
|
||||||
let project = Project.test(targets: targets)
|
// When
|
||||||
let graphCache = GraphLoaderCache()
|
let result = try XCTUnwrap(got)
|
||||||
let graph = Graph.test(cache: graphCache)
|
XCTAssertEqual(result.buildActionEntries.count, 1)
|
||||||
|
let entry = try XCTUnwrap(result.buildActionEntries.first)
|
||||||
|
let buildableReference = entry.buildableReference
|
||||||
|
XCTAssertEqual(entry.buildFor, [.analyzing, .archiving, .profiling, .running, .testing])
|
||||||
|
|
||||||
let got = subject.projectBuildAction(project: project,
|
XCTAssertEqual(buildableReference.referencedContainer, "container:Projects/Project/project.xcodeproj")
|
||||||
generatedProject: generatedProject(targets: targets),
|
XCTAssertEqual(buildableReference.buildableName, "App.app")
|
||||||
graph: graph)
|
XCTAssertEqual(buildableReference.blueprintName, "App")
|
||||||
|
XCTAssertEqual(buildableReference.buildableIdentifier, "primary")
|
||||||
|
|
||||||
XCTAssertTrue(got.parallelizeBuild)
|
XCTAssertEqual(result.parallelizeBuild, true)
|
||||||
XCTAssertTrue(got.buildImplicitDependencies)
|
XCTAssertEqual(result.buildImplicitDependencies, true)
|
||||||
XCTAssertEqual(got.buildActionEntries.count, 3)
|
|
||||||
|
|
||||||
let appEntry = got.buildActionEntries[0]
|
|
||||||
let testsEntry = got.buildActionEntries[1]
|
|
||||||
let uiTestsEntry = got.buildActionEntries[2]
|
|
||||||
|
|
||||||
XCTAssertEqual(appEntry.buildFor, [.analyzing, .archiving, .profiling, .running, .testing])
|
|
||||||
XCTAssertEqual(appEntry.buildableReference.referencedContainer, "container:project.xcodeproj")
|
|
||||||
XCTAssertEqual(appEntry.buildableReference.buildableName, app.productNameWithExtension)
|
|
||||||
XCTAssertEqual(appEntry.buildableReference.blueprintName, app.name)
|
|
||||||
XCTAssertEqual(appEntry.buildableReference.buildableIdentifier, "primary")
|
|
||||||
|
|
||||||
XCTAssertEqual(testsEntry.buildFor, [.testing])
|
|
||||||
XCTAssertEqual(testsEntry.buildableReference.referencedContainer, "container:project.xcodeproj")
|
|
||||||
XCTAssertEqual(testsEntry.buildableReference.buildableName, appTests.productNameWithExtension)
|
|
||||||
XCTAssertEqual(testsEntry.buildableReference.blueprintName, appTests.name)
|
|
||||||
XCTAssertEqual(testsEntry.buildableReference.buildableIdentifier, "primary")
|
|
||||||
|
|
||||||
XCTAssertEqual(uiTestsEntry.buildFor, [.testing])
|
|
||||||
XCTAssertEqual(uiTestsEntry.buildableReference.referencedContainer, "container:project.xcodeproj")
|
|
||||||
XCTAssertEqual(uiTestsEntry.buildableReference.buildableName, appUITests.productNameWithExtension)
|
|
||||||
XCTAssertEqual(uiTestsEntry.buildableReference.blueprintName, appUITests.name)
|
|
||||||
XCTAssertEqual(uiTestsEntry.buildableReference.buildableIdentifier, "primary")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_schemeBuildAction_whenMultipleProject() throws {
|
||||||
|
// Given
|
||||||
|
let projectAPath = AbsolutePath("/somepath/Workspace/Projects/ProjectA")
|
||||||
|
let projectBPath = AbsolutePath("/somepath/Workspace/Projects/ProjectB")
|
||||||
|
|
||||||
|
let buildAction = BuildAction(targets: [
|
||||||
|
TargetReference(projectPath: projectAPath, name: "FrameworkA"),
|
||||||
|
TargetReference(projectPath: projectBPath, name: "FrameworkB")
|
||||||
|
])
|
||||||
|
let scheme = Scheme.test(buildAction: buildAction)
|
||||||
|
|
||||||
|
let frameworkA = Target.test(name: "FrameworkA", product: .staticFramework)
|
||||||
|
let frameworkB = Target.test(name: "FrameworkB", product: .staticFramework)
|
||||||
|
let targets = [frameworkA, frameworkB]
|
||||||
|
|
||||||
|
let projectA = Project.test(path: projectAPath)
|
||||||
|
let projectB = Project.test(path: projectBPath)
|
||||||
|
let graph = Graph.create(dependencies: [
|
||||||
|
(project: projectA, target: frameworkA, dependencies: []),
|
||||||
|
(project: projectB, target: frameworkB, dependencies: [])
|
||||||
|
])
|
||||||
|
|
||||||
|
// Then
|
||||||
|
let got = try subject.schemeBuildAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: AbsolutePath("/somepath/Workspace"),
|
||||||
|
generatedProjects: [
|
||||||
|
projectAPath: generatedProject(targets: targets, projectPath: "\(projectAPath)/project.xcodeproj"),
|
||||||
|
projectBPath: generatedProject(targets: targets, projectPath: "\(projectBPath)/project.xcodeproj")
|
||||||
|
])
|
||||||
|
|
||||||
func test_projectTestAction() {
|
// When
|
||||||
let app = Target.test(name: "App", product: .app)
|
let result = try XCTUnwrap(got)
|
||||||
let appTests = Target.test(name: "AppTests", product: .unitTests)
|
XCTAssertEqual(result.buildActionEntries.count, 2)
|
||||||
let targets = [app, appTests]
|
|
||||||
let project = Project.test(targets: targets)
|
let firstEntry = try XCTUnwrap(result.buildActionEntries[0])
|
||||||
|
let firstBuildableReference = firstEntry.buildableReference
|
||||||
|
XCTAssertEqual(firstEntry.buildFor, [.analyzing, .archiving, .profiling, .running, .testing])
|
||||||
|
|
||||||
|
let secondEntry = try XCTUnwrap(result.buildActionEntries[1])
|
||||||
|
let secondBuildableReference = secondEntry.buildableReference
|
||||||
|
XCTAssertEqual(secondEntry.buildFor, [.analyzing, .archiving, .profiling, .running, .testing])
|
||||||
|
|
||||||
let got = subject.projectTestAction(project: project,
|
XCTAssertEqual(firstBuildableReference.referencedContainer, "container:Projects/ProjectA/project.xcodeproj")
|
||||||
generatedProject: generatedProject(targets: targets))
|
XCTAssertEqual(firstBuildableReference.buildableName, "FrameworkA.framework")
|
||||||
|
XCTAssertEqual(firstBuildableReference.blueprintName, "FrameworkA")
|
||||||
|
XCTAssertEqual(firstBuildableReference.buildableIdentifier, "primary")
|
||||||
|
|
||||||
|
XCTAssertEqual(secondBuildableReference.referencedContainer, "container:Projects/ProjectB/project.xcodeproj")
|
||||||
|
XCTAssertEqual(secondBuildableReference.buildableName, "FrameworkB.framework")
|
||||||
|
XCTAssertEqual(secondBuildableReference.blueprintName, "FrameworkB")
|
||||||
|
XCTAssertEqual(secondBuildableReference.buildableIdentifier, "primary")
|
||||||
|
|
||||||
XCTAssertEqual(got.buildConfiguration, "Debug")
|
XCTAssertEqual(result.parallelizeBuild, true)
|
||||||
XCTAssertNil(got.macroExpansion)
|
XCTAssertEqual(result.buildImplicitDependencies, true)
|
||||||
XCTAssertEqual(got.testables.count, 1)
|
|
||||||
|
|
||||||
let testable = got.testables.first
|
|
||||||
XCTAssertEqual(testable?.skipped, false)
|
|
||||||
|
|
||||||
XCTAssertEqual(testable?.buildableReference.referencedContainer, "container:project.xcodeproj")
|
|
||||||
XCTAssertEqual(testable?.buildableReference.buildableName, appTests.productNameWithExtension)
|
|
||||||
XCTAssertEqual(testable?.buildableReference.blueprintName, appTests.name)
|
|
||||||
XCTAssertEqual(testable?.buildableReference.buildableIdentifier, "primary")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_schemeTestAction_when_notTestsTarget() {
|
func test_schemeBuildAction_with_executionAction() throws {
|
||||||
let scheme = Scheme.test()
|
// Given
|
||||||
let project = Project.test()
|
let projectPath = AbsolutePath("/somepath/Project")
|
||||||
let generatedProject = GeneratedProject.test()
|
|
||||||
|
|
||||||
let got = subject.schemeTestAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
|
||||||
|
|
||||||
XCTAssertEqual(got?.buildConfiguration, "Debug")
|
|
||||||
XCTAssertEqual(got?.shouldUseLaunchSchemeArgsEnv, false)
|
|
||||||
XCTAssertNil(got?.macroExpansion)
|
|
||||||
XCTAssertEqual(got?.testables.count, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func test_schemeTestAction_when_testsTarget() {
|
|
||||||
let target = Target.test(name: "App", product: .app)
|
let target = Target.test(name: "App", product: .app)
|
||||||
let testTarget = Target.test(name: "AppTests", product: .unitTests)
|
|
||||||
|
let preAction = ExecutionAction(title: "Pre Action", scriptText: "echo Pre Actions", target: TargetReference(projectPath: projectPath, name: "App"))
|
||||||
|
let postAction = ExecutionAction(title: "Post Action", scriptText: "echo Post Actions", target: TargetReference(projectPath: projectPath, name: "App"))
|
||||||
|
let buildAction = BuildAction.test(targets: [TargetReference(projectPath: projectPath, name: "Library")], preActions: [preAction], postActions: [postAction])
|
||||||
|
|
||||||
let testAction = TestAction.test(arguments: nil)
|
let scheme = Scheme.test(name: "App", shared: true, buildAction: buildAction)
|
||||||
let scheme = Scheme.test(name: "AppTests", testAction: testAction)
|
let project = Project.test(path: projectPath, targets: [target])
|
||||||
let project = Project.test(targets: [target, testTarget])
|
let graph = Graph.create(dependencies: [
|
||||||
|
(project: project, target: target, dependencies: [])
|
||||||
|
])
|
||||||
|
|
||||||
let pbxTarget = PBXNativeTarget(name: "App")
|
// When
|
||||||
let pbxTestTarget = PBXNativeTarget(name: "AppTests", productType: .unitTestBundle)
|
let got = try subject.schemeBuildAction(scheme: scheme,
|
||||||
let generatedProject = GeneratedProject.test(targets: ["App": pbxTarget, "AppTests": pbxTestTarget])
|
graph: graph,
|
||||||
|
rootPath: projectPath,
|
||||||
let got = subject.schemeTestAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
generatedProjects: createGeneratedProjects(projects: [project]))
|
||||||
|
|
||||||
XCTAssertEqual(got?.buildConfiguration, "Debug")
|
|
||||||
XCTAssertEqual(got?.shouldUseLaunchSchemeArgsEnv, true)
|
|
||||||
XCTAssertNil(got?.macroExpansion)
|
|
||||||
let testable = got?.testables.first
|
|
||||||
let buildableReference = testable?.buildableReference
|
|
||||||
|
|
||||||
XCTAssertEqual(testable?.skipped, false)
|
|
||||||
XCTAssertEqual(buildableReference?.referencedContainer, "container:project.xcodeproj")
|
|
||||||
XCTAssertEqual(buildableReference?.buildableName, "AppTests.xctest")
|
|
||||||
XCTAssertEqual(buildableReference?.blueprintName, "AppTests")
|
|
||||||
XCTAssertEqual(buildableReference?.buildableIdentifier, "primary")
|
|
||||||
}
|
|
||||||
|
|
||||||
func test_schemeTestAction_with_executionAction() {
|
|
||||||
let testTarget = Target.test(name: "AppTests", product: .unitTests)
|
|
||||||
|
|
||||||
let preAction = ExecutionAction(title: "Pre Action", scriptText: "echo Pre Actions", target: "AppTests")
|
|
||||||
let postAction = ExecutionAction(title: "Post Action", scriptText: "echo Post Actions", target: "AppTests")
|
|
||||||
let testAction = TestAction.test(targets: [TestableTarget(target: "AppTests")], preActions: [preAction], postActions: [postAction])
|
|
||||||
|
|
||||||
let scheme = Scheme.test(name: "AppTests", shared: true, testAction: testAction)
|
|
||||||
let project = Project.test(targets: [testTarget])
|
|
||||||
|
|
||||||
let pbxTestTarget = PBXNativeTarget(name: "AppTests", productType: .unitTestBundle)
|
|
||||||
let generatedProject = GeneratedProject.test(targets: ["AppTests": pbxTestTarget])
|
|
||||||
|
|
||||||
let got = subject.schemeTestAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
|
||||||
|
|
||||||
|
// Then
|
||||||
// Pre Action
|
// Pre Action
|
||||||
XCTAssertEqual(got?.preActions.first?.title, "Pre Action")
|
XCTAssertEqual(got?.preActions.first?.title, "Pre Action")
|
||||||
XCTAssertEqual(got?.preActions.first?.scriptText, "echo Pre Actions")
|
XCTAssertEqual(got?.preActions.first?.scriptText, "echo Pre Actions")
|
||||||
|
|
||||||
let preBuildableReference = got?.preActions.first?.environmentBuildable
|
let preBuildableReference = got?.preActions.first?.environmentBuildable
|
||||||
|
|
||||||
XCTAssertEqual(preBuildableReference?.referencedContainer, "container:project.xcodeproj")
|
XCTAssertEqual(preBuildableReference?.referencedContainer, "container:Project.xcodeproj")
|
||||||
XCTAssertEqual(preBuildableReference?.buildableName, "AppTests.xctest")
|
XCTAssertEqual(preBuildableReference?.buildableName, "App.app")
|
||||||
XCTAssertEqual(preBuildableReference?.blueprintName, "AppTests")
|
XCTAssertEqual(preBuildableReference?.blueprintName, "App")
|
||||||
XCTAssertEqual(preBuildableReference?.buildableIdentifier, "primary")
|
XCTAssertEqual(preBuildableReference?.buildableIdentifier, "primary")
|
||||||
|
|
||||||
// Post Action
|
// Post Action
|
||||||
XCTAssertEqual(got?.postActions.first?.title, "Post Action")
|
XCTAssertEqual(got?.postActions.first?.title, "Post Action")
|
||||||
XCTAssertEqual(got?.postActions.first?.scriptText, "echo Post Actions")
|
XCTAssertEqual(got?.postActions.first?.scriptText, "echo Post Actions")
|
||||||
|
|
||||||
let postBuildableReference = got?.postActions.first?.environmentBuildable
|
let postBuildableReference = got?.postActions.first?.environmentBuildable
|
||||||
|
|
||||||
XCTAssertEqual(postBuildableReference?.referencedContainer, "container:project.xcodeproj")
|
XCTAssertEqual(postBuildableReference?.referencedContainer, "container:Project.xcodeproj")
|
||||||
XCTAssertEqual(postBuildableReference?.buildableName, "AppTests.xctest")
|
XCTAssertEqual(postBuildableReference?.buildableName, "App.app")
|
||||||
XCTAssertEqual(postBuildableReference?.blueprintName, "AppTests")
|
XCTAssertEqual(postBuildableReference?.blueprintName, "App")
|
||||||
XCTAssertEqual(postBuildableReference?.buildableIdentifier, "primary")
|
XCTAssertEqual(postBuildableReference?.buildableIdentifier, "primary")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Test Action Tests
|
||||||
|
func test_schemeTestAction_when_testsTarget() throws {
|
||||||
|
// Given
|
||||||
|
let target = Target.test(name: "App", product: .app)
|
||||||
|
let testTarget = Target.test(name: "AppTests", product: .unitTests)
|
||||||
|
let project = Project.test(targets: [target, testTarget])
|
||||||
|
|
||||||
|
let testAction = TestAction.test(targets: [TestableTarget(target: TargetReference(projectPath: project.path, name: "AppTests"))],
|
||||||
|
arguments: nil)
|
||||||
|
|
||||||
|
|
||||||
|
let scheme = Scheme.test(name: "AppTests", testAction: testAction)
|
||||||
|
let generatedProjects = createGeneratedProjects(projects: [project])
|
||||||
|
|
||||||
|
let graph = Graph.create(dependencies: [(project: project, target: target, dependencies: []),
|
||||||
|
(project: project, target: testTarget, dependencies: [target])])
|
||||||
|
|
||||||
|
// When
|
||||||
|
let got = try subject.schemeTestAction(scheme: scheme, graph: graph, rootPath: project.path, generatedProjects: generatedProjects)
|
||||||
|
|
||||||
|
|
||||||
|
// Then
|
||||||
|
let result = try XCTUnwrap(got)
|
||||||
|
XCTAssertEqual(result.buildConfiguration, "Debug")
|
||||||
|
XCTAssertEqual(result.shouldUseLaunchSchemeArgsEnv, true)
|
||||||
|
XCTAssertNil(result.macroExpansion)
|
||||||
|
let testable = try XCTUnwrap(result.testables.first)
|
||||||
|
let buildableReference = testable.buildableReference
|
||||||
|
|
||||||
|
XCTAssertEqual(testable.skipped, false)
|
||||||
|
XCTAssertEqual(buildableReference.referencedContainer, "container:Project.xcodeproj")
|
||||||
|
XCTAssertEqual(buildableReference.buildableName, "AppTests.xctest")
|
||||||
|
XCTAssertEqual(buildableReference.blueprintName, "AppTests")
|
||||||
|
XCTAssertEqual(buildableReference.buildableIdentifier, "primary")
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_schemeTestAction_with_codeCoverageTargets() {
|
func test_schemeTestAction_with_codeCoverageTargets() throws {
|
||||||
|
// Given
|
||||||
|
let projectPath = AbsolutePath("/somepath/Project")
|
||||||
|
|
||||||
let target = Target.test(name: "App", product: .app)
|
let target = Target.test(name: "App", product: .app)
|
||||||
let testTarget = Target.test(name: "AppTests", product: .unitTests)
|
let testTarget = Target.test(name: "AppTests", product: .unitTests)
|
||||||
|
|
||||||
let testAction = TestAction.test(targets: [TestableTarget(target: "AppTests")], coverage: true, codeCoverageTargets: ["App"])
|
let testAction = TestAction.test(targets: [TestableTarget(target: TargetReference(projectPath: projectPath, name: "AppTests"))],
|
||||||
let buildAction = BuildAction.test(targets: ["App"])
|
coverage: true,
|
||||||
|
codeCoverageTargets: [TargetReference(projectPath: projectPath, name: "App")])
|
||||||
|
let buildAction = BuildAction.test(targets: [TargetReference(projectPath: projectPath, name: "App")])
|
||||||
|
|
||||||
let scheme = Scheme.test(name: "AppTests", shared: true, buildAction: buildAction, testAction: testAction)
|
let scheme = Scheme.test(name: "AppTests", shared: true, buildAction: buildAction, testAction: testAction)
|
||||||
let project = Project.test(targets: [target, testTarget])
|
|
||||||
|
let project = Project.test(path: projectPath, targets: [target, testTarget])
|
||||||
|
let graph = Graph.create(dependencies: [(project: project, target: target, dependencies: []),
|
||||||
|
(project: project, target: testTarget, dependencies: [target])])
|
||||||
|
|
||||||
|
// When
|
||||||
|
let got = try subject.schemeTestAction(scheme: scheme, graph: graph, rootPath: AbsolutePath("/somepath/Workspace"), generatedProjects: createGeneratedProjects(projects: [project]))
|
||||||
|
|
||||||
|
// Then
|
||||||
|
let result = try XCTUnwrap(got)
|
||||||
|
let codeCoverageTargetsBuildableReference = try XCTUnwrap(result.codeCoverageTargets)
|
||||||
|
|
||||||
let pbxTarget = PBXNativeTarget(name: "App", productType: .application)
|
XCTAssertEqual(result.onlyGenerateCoverageForSpecifiedTargets, true)
|
||||||
let pbxTestTarget = PBXNativeTarget(name: "AppTests", productType: .unitTestBundle)
|
XCTAssertEqual(codeCoverageTargetsBuildableReference.count, 1)
|
||||||
let generatedProject = GeneratedProject.test(targets: ["AppTests": pbxTestTarget, "App": pbxTarget])
|
XCTAssertEqual(codeCoverageTargetsBuildableReference.first?.buildableName, "App.app")
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_schemeTestAction_when_notTestsTarget() throws {
|
||||||
|
// Given
|
||||||
|
let scheme = Scheme.test()
|
||||||
|
let project = Project.test()
|
||||||
|
let generatedProject = GeneratedProject.test()
|
||||||
|
let graph = Graph.create(dependencies: [])
|
||||||
|
|
||||||
let got = subject.schemeTestAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
// Then
|
||||||
|
let got = try subject.schemeTestAction(scheme: scheme, graph: graph, rootPath: project.path, generatedProjects: [project.path: generatedProject])
|
||||||
|
|
||||||
let codeCoverageTargetsBuildableReference = got?.codeCoverageTargets
|
// When
|
||||||
|
let result = try XCTUnwrap(got)
|
||||||
XCTAssertEqual(got?.onlyGenerateCoverageForSpecifiedTargets, true)
|
XCTAssertEqual(result.buildConfiguration, "Debug")
|
||||||
XCTAssertEqual(codeCoverageTargetsBuildableReference?.count, 1)
|
XCTAssertEqual(result.shouldUseLaunchSchemeArgsEnv, false)
|
||||||
XCTAssertEqual(codeCoverageTargetsBuildableReference?.first?.buildableName, "App.app")
|
XCTAssertNil(result.macroExpansion)
|
||||||
|
XCTAssertEqual(result.testables.count, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_schemeTestAction_with_testable_info() {
|
|
||||||
|
func test_schemeTestAction_with_testable_info() throws {
|
||||||
|
// Given
|
||||||
let target = Target.test(name: "App", product: .app)
|
let target = Target.test(name: "App", product: .app)
|
||||||
let testTarget = Target.test(name: "AppTests", product: .unitTests)
|
let testTarget = Target.test(name: "AppTests", product: .unitTests)
|
||||||
|
let project = Project.test(targets: [target, testTarget])
|
||||||
|
|
||||||
let testableTarget = TestableTarget(target: "AppTests", skipped: false, parallelizable: true, randomExecutionOrdering: true)
|
let testableTarget = TestableTarget(target: TargetReference(projectPath: project.path, name: "AppTests"),
|
||||||
|
skipped: false,
|
||||||
|
parallelizable: true,
|
||||||
|
randomExecutionOrdering: true)
|
||||||
let testAction = TestAction.test(targets: [testableTarget])
|
let testAction = TestAction.test(targets: [testableTarget])
|
||||||
let buildAction = BuildAction.test(targets: ["App"])
|
let buildAction = BuildAction.test(targets: [TargetReference(projectPath: project.path, name: "App")])
|
||||||
|
|
||||||
let scheme = Scheme.test(name: "AppTests", shared: true, buildAction: buildAction, testAction: testAction)
|
let scheme = Scheme.test(name: "AppTests", shared: true, buildAction: buildAction, testAction: testAction)
|
||||||
let project = Project.test(targets: [target, testTarget])
|
let graph = Graph.create(dependencies: [(project: project, target: target, dependencies: []),
|
||||||
|
(project: project, target: testTarget, dependencies: [testTarget])])
|
||||||
|
|
||||||
let pbxTarget = PBXNativeTarget(name: "App", productType: .application)
|
// When
|
||||||
let pbxTestTarget = PBXNativeTarget(name: "AppTests", productType: .unitTestBundle)
|
let got = try subject.schemeTestAction(scheme: scheme, graph: graph, rootPath: project.path, generatedProjects: createGeneratedProjects(projects: [project]))
|
||||||
let generatedProject = GeneratedProject.test(targets: ["AppTests": pbxTestTarget, "App": pbxTarget])
|
|
||||||
|
|
||||||
let got = subject.schemeTestAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
// Then
|
||||||
let testableTargetReference = got!.testables[0]
|
let testableTargetReference = got!.testables[0]
|
||||||
XCTAssertEqual(testableTargetReference.skipped, false)
|
XCTAssertEqual(testableTargetReference.skipped, false)
|
||||||
XCTAssertEqual(testableTargetReference.parallelizable, true)
|
XCTAssertEqual(testableTargetReference.parallelizable, true)
|
||||||
XCTAssertEqual(testableTargetReference.randomExecutionOrdering, true)
|
XCTAssertEqual(testableTargetReference.randomExecutionOrdering, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_schemeBuildAction() {
|
func test_schemeBuildAction() throws {
|
||||||
let target = Target.test(name: "App", product: .app)
|
let target = Target.test(name: "App", product: .app)
|
||||||
let pbxTarget = PBXNativeTarget(name: "App")
|
let testTarget = Target.test(name: "AppTests", product: .unitTests)
|
||||||
|
let project = Project.test(targets: [target, testTarget])
|
||||||
|
|
||||||
|
let testAction = TestAction.test(targets: [TestableTarget(target: TargetReference(projectPath: project.path, name: "AppTests"))],
|
||||||
|
arguments: nil)
|
||||||
|
|
||||||
|
|
||||||
|
let scheme = Scheme.test(name: "AppTests", testAction: testAction)
|
||||||
|
let generatedProjects = createGeneratedProjects(projects: [project])
|
||||||
|
|
||||||
|
let graph = Graph.create(dependencies: [(project: project, target: target, dependencies: []),
|
||||||
|
(project: project, target: testTarget, dependencies: [target])])
|
||||||
|
|
||||||
|
// When
|
||||||
|
let got = try subject.schemeTestAction(scheme: scheme, graph: graph, rootPath: project.path, generatedProjects: generatedProjects)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
let result = try XCTUnwrap(got)
|
||||||
|
XCTAssertEqual(result.buildConfiguration, "Debug")
|
||||||
|
XCTAssertEqual(result.shouldUseLaunchSchemeArgsEnv, true)
|
||||||
|
XCTAssertNil(result.macroExpansion)
|
||||||
|
let testable = try XCTUnwrap(result.testables.first)
|
||||||
|
let buildableReference = testable.buildableReference
|
||||||
|
|
||||||
let scheme = Scheme.test(name: "App")
|
XCTAssertEqual(testable.skipped, false)
|
||||||
let project = Project.test(targets: [target])
|
XCTAssertEqual(buildableReference.referencedContainer, "container:Project.xcodeproj")
|
||||||
let generatedProject = GeneratedProject.test(targets: ["App": pbxTarget])
|
XCTAssertEqual(buildableReference.buildableName, "AppTests.xctest")
|
||||||
|
XCTAssertEqual(buildableReference.blueprintName, "AppTests")
|
||||||
let got = subject.schemeBuildAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
XCTAssertEqual(buildableReference.buildableIdentifier, "primary")
|
||||||
|
|
||||||
XCTAssertEqual(got?.buildActionEntries.count, 1)
|
|
||||||
let entry = got?.buildActionEntries.first
|
|
||||||
let buildableReference = entry?.buildableReference
|
|
||||||
XCTAssertEqual(entry?.buildFor, [.analyzing, .archiving, .profiling, .running, .testing])
|
|
||||||
|
|
||||||
XCTAssertEqual(buildableReference?.referencedContainer, "container:project.xcodeproj")
|
|
||||||
XCTAssertEqual(buildableReference?.buildableName, "App.app")
|
|
||||||
XCTAssertEqual(buildableReference?.blueprintName, "App")
|
|
||||||
XCTAssertEqual(buildableReference?.buildableIdentifier, "primary")
|
|
||||||
|
|
||||||
XCTAssertEqual(got?.parallelizeBuild, true)
|
|
||||||
XCTAssertEqual(got?.buildImplicitDependencies, true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_schemeTestAction_with_executionAction() throws {
|
||||||
|
// Given
|
||||||
|
let projectPath = AbsolutePath("/somepath/Project")
|
||||||
|
let testTarget = Target.test(name: "AppTests", product: .unitTests)
|
||||||
|
|
||||||
func test_schemeBuildAction_with_executionAction() {
|
let preAction = ExecutionAction(title: "Pre Action", scriptText: "echo Pre Actions", target: TargetReference(projectPath: projectPath, name: "AppTests"))
|
||||||
let target = Target.test(name: "App", product: .app)
|
let postAction = ExecutionAction(title: "Post Action", scriptText: "echo Post Actions", target: TargetReference(projectPath: projectPath, name: "AppTests"))
|
||||||
let pbxTarget = PBXNativeTarget(name: "App")
|
let testAction = TestAction.test(targets: [TestableTarget(target: TargetReference(projectPath: projectPath, name: "AppTests"))], preActions: [preAction], postActions: [postAction])
|
||||||
|
|
||||||
let preAction = ExecutionAction(title: "Pre Action", scriptText: "echo Pre Actions", target: "App")
|
let scheme = Scheme.test(name: "AppTests", shared: true, testAction: testAction)
|
||||||
let postAction = ExecutionAction(title: "Post Action", scriptText: "echo Post Actions", target: "App")
|
let project = Project.test(path: projectPath, targets: [testTarget])
|
||||||
let buildAction = BuildAction.test(targets: ["Library"], preActions: [preAction], postActions: [postAction])
|
|
||||||
|
|
||||||
let scheme = Scheme.test(name: "App", shared: true, buildAction: buildAction)
|
let generatedProjects = createGeneratedProjects(projects: [project])
|
||||||
let project = Project.test(targets: [target])
|
let graph = Graph.create(dependencies: [(project: project, target: testTarget, dependencies: [])])
|
||||||
let generatedProject = GeneratedProject.test(targets: ["App": pbxTarget])
|
|
||||||
|
|
||||||
let got = subject.schemeBuildAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
// When
|
||||||
|
let got = try subject.schemeTestAction(scheme: scheme, graph: graph, rootPath: project.path, generatedProjects: generatedProjects)
|
||||||
|
|
||||||
|
// Then
|
||||||
// Pre Action
|
// Pre Action
|
||||||
XCTAssertEqual(got?.preActions.first?.title, "Pre Action")
|
let result = try XCTUnwrap(got)
|
||||||
XCTAssertEqual(got?.preActions.first?.scriptText, "echo Pre Actions")
|
XCTAssertEqual(result.preActions.first?.title, "Pre Action")
|
||||||
|
XCTAssertEqual(result.preActions.first?.scriptText, "echo Pre Actions")
|
||||||
|
|
||||||
let preBuildableReference = got?.preActions.first?.environmentBuildable
|
let preBuildableReference = try XCTUnwrap(result.preActions.first?.environmentBuildable)
|
||||||
|
|
||||||
XCTAssertEqual(preBuildableReference?.referencedContainer, "container:project.xcodeproj")
|
XCTAssertEqual(preBuildableReference.referencedContainer, "container:Project.xcodeproj")
|
||||||
XCTAssertEqual(preBuildableReference?.buildableName, "App.app")
|
XCTAssertEqual(preBuildableReference.buildableName, "AppTests.xctest")
|
||||||
XCTAssertEqual(preBuildableReference?.blueprintName, "App")
|
XCTAssertEqual(preBuildableReference.blueprintName, "AppTests")
|
||||||
XCTAssertEqual(preBuildableReference?.buildableIdentifier, "primary")
|
XCTAssertEqual(preBuildableReference.buildableIdentifier, "primary")
|
||||||
|
|
||||||
// Post Action
|
// Post Action
|
||||||
XCTAssertEqual(got?.postActions.first?.title, "Post Action")
|
XCTAssertEqual(result.postActions.first?.title, "Post Action")
|
||||||
XCTAssertEqual(got?.postActions.first?.scriptText, "echo Post Actions")
|
XCTAssertEqual(result.postActions.first?.scriptText, "echo Post Actions")
|
||||||
|
|
||||||
let postBuildableReference = got?.postActions.first?.environmentBuildable
|
let postBuildableReference = try XCTUnwrap(result.postActions.first?.environmentBuildable)
|
||||||
|
|
||||||
XCTAssertEqual(postBuildableReference?.referencedContainer, "container:project.xcodeproj")
|
XCTAssertEqual(postBuildableReference.referencedContainer, "container:Project.xcodeproj")
|
||||||
XCTAssertEqual(postBuildableReference?.buildableName, "App.app")
|
XCTAssertEqual(postBuildableReference.buildableName, "AppTests.xctest")
|
||||||
XCTAssertEqual(postBuildableReference?.blueprintName, "App")
|
XCTAssertEqual(postBuildableReference.blueprintName, "AppTests")
|
||||||
XCTAssertEqual(postBuildableReference?.buildableIdentifier, "primary")
|
XCTAssertEqual(postBuildableReference.buildableIdentifier, "primary")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Launch Action Tests
|
||||||
|
|
||||||
func test_schemeLaunchAction_when_runnableTarget() {
|
func test_schemeLaunchAction() throws {
|
||||||
let target = Target.test(name: "App", product: .app, environment: ["a": "b"])
|
// Given
|
||||||
let pbxTarget = PBXNativeTarget(name: "App")
|
let projectPath = AbsolutePath("/somepath/Workspace/Projects/Project")
|
||||||
let scheme = Scheme.test(runAction: RunAction.test(arguments: Arguments.test(environment: ["a": "b"])))
|
|
||||||
let project = Project.test(path: AbsolutePath("/project.xcodeproj"), targets: [target])
|
|
||||||
let generatedProject = GeneratedProject.test(targets: ["App": pbxTarget])
|
|
||||||
|
|
||||||
let got = subject.schemeLaunchAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
let buildAction = BuildAction.test(targets: [TargetReference(projectPath: projectPath, name: "App")])
|
||||||
|
let runAction = RunAction.test(configurationName: "Release",
|
||||||
|
executable: TargetReference(projectPath: projectPath, name: "App"),
|
||||||
|
arguments: Arguments(environment:["a": "b"], launch: ["some": true]))
|
||||||
|
let scheme = Scheme.test(buildAction: buildAction, runAction: runAction)
|
||||||
|
|
||||||
|
let app = Target.test(name: "App", product: .app, environment: ["a": "b"])
|
||||||
|
|
||||||
|
let project = Project.test(path: projectPath, targets: [app])
|
||||||
|
let graph = Graph.create(dependencies: [(project: project, target: app, dependencies: [])])
|
||||||
|
|
||||||
|
// When
|
||||||
|
let got = try subject.schemeLaunchAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: AbsolutePath("/somepath/Workspace"),
|
||||||
|
generatedProjects: createGeneratedProjects(projects: [project]))
|
||||||
|
|
||||||
|
// Then
|
||||||
|
let result = try XCTUnwrap(got)
|
||||||
|
|
||||||
|
XCTAssertNil(result.macroExpansion)
|
||||||
|
|
||||||
XCTAssertNil(got?.macroExpansion)
|
let buildableReference = try XCTUnwrap(result.runnable?.buildableReference)
|
||||||
|
|
||||||
let buildableReference = got?.runnable?.buildableReference
|
XCTAssertEqual(result.buildConfiguration, "Release")
|
||||||
|
XCTAssertEqual(result.environmentVariables, [XCScheme.EnvironmentVariable(variable: "a", value: "b", enabled: true)])
|
||||||
XCTAssertEqual(got?.buildConfiguration, "Debug")
|
XCTAssertEqual(buildableReference.referencedContainer, "container:Projects/Project/Project.xcodeproj")
|
||||||
XCTAssertEqual(got?.environmentVariables, [XCScheme.EnvironmentVariable(variable: "a", value: "b", enabled: true)])
|
XCTAssertEqual(buildableReference.buildableName, "App.app")
|
||||||
XCTAssertEqual(buildableReference?.referencedContainer, "container:project.xcodeproj")
|
XCTAssertEqual(buildableReference.blueprintName, "App")
|
||||||
XCTAssertEqual(buildableReference?.buildableName, "App.app")
|
XCTAssertEqual(buildableReference.buildableIdentifier, "primary")
|
||||||
XCTAssertEqual(buildableReference?.blueprintName, "App")
|
|
||||||
XCTAssertEqual(buildableReference?.buildableIdentifier, "primary")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_schemeLaunchAction_when_notRunnableTarget() {
|
func test_schemeLaunchAction_when_notRunnableTarget() throws {
|
||||||
|
// Given
|
||||||
|
let projectPath = AbsolutePath("/somepath/Project")
|
||||||
|
|
||||||
let target = Target.test(name: "Library", platform: .iOS, product: .dynamicLibrary)
|
let target = Target.test(name: "Library", platform: .iOS, product: .dynamicLibrary)
|
||||||
let pbxTarget = PBXNativeTarget(name: "App")
|
|
||||||
|
|
||||||
let buildAction = BuildAction.test(targets: ["Library"])
|
let buildAction = BuildAction.test(targets: [TargetReference(projectPath: projectPath, name: "Library")])
|
||||||
let testAction = TestAction.test(targets: [TestableTarget(target: "Library")])
|
let testAction = TestAction.test(targets: [TestableTarget(target: TargetReference(projectPath: projectPath, name: "Library"))])
|
||||||
|
|
||||||
let scheme = Scheme.test(name: "Library", buildAction: buildAction, testAction: testAction, runAction: nil)
|
let scheme = Scheme.test(name: "Library", buildAction: buildAction, testAction: testAction, runAction: nil)
|
||||||
|
let project = Project.test(path: projectPath, targets: [target])
|
||||||
|
let graph = Graph.create(dependencies: [(project: project, target: target, dependencies: [])])
|
||||||
|
|
||||||
let project = Project.test(path: AbsolutePath("/project.xcodeproj"), targets: [target])
|
// When
|
||||||
let generatedProject = GeneratedProject.test(targets: ["Library": pbxTarget])
|
let got = try subject.schemeLaunchAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: projectPath,
|
||||||
|
generatedProjects: createGeneratedProjects(projects: [project]))
|
||||||
|
|
||||||
let got = subject.schemeLaunchAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
// Then
|
||||||
|
let result = try XCTUnwrap(got)
|
||||||
|
XCTAssertNil(result.runnable?.buildableReference)
|
||||||
|
|
||||||
XCTAssertNil(got?.runnable?.buildableReference)
|
XCTAssertEqual(result.buildConfiguration, "Debug")
|
||||||
|
XCTAssertEqual(result.macroExpansion?.referencedContainer, "container:Project.xcodeproj")
|
||||||
XCTAssertEqual(got?.buildConfiguration, "Debug")
|
XCTAssertEqual(result.macroExpansion?.buildableName, "libLibrary.dylib")
|
||||||
XCTAssertEqual(got?.macroExpansion?.referencedContainer, "container:project.xcodeproj")
|
XCTAssertEqual(result.macroExpansion?.blueprintName, "Library")
|
||||||
XCTAssertEqual(got?.macroExpansion?.buildableName, "libLibrary.dylib")
|
XCTAssertEqual(result.macroExpansion?.buildableIdentifier, "primary")
|
||||||
XCTAssertEqual(got?.macroExpansion?.blueprintName, "Library")
|
|
||||||
XCTAssertEqual(got?.macroExpansion?.buildableIdentifier, "primary")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Profile Action Tests
|
||||||
|
|
||||||
func test_schemeProfileAction_when_runnableTarget() {
|
func test_schemeProfileAction_when_runnableTarget() throws {
|
||||||
|
// Given
|
||||||
|
let projectPath = AbsolutePath("/somepath/Project")
|
||||||
let target = Target.test(name: "App", platform: .iOS, product: .app)
|
let target = Target.test(name: "App", platform: .iOS, product: .app)
|
||||||
let scheme = Scheme.test()
|
|
||||||
let pbxTarget = PBXNativeTarget(name: "App")
|
let appTargetReference = TargetReference(projectPath: projectPath, name: "App")
|
||||||
let project = Project.test(path: AbsolutePath("/project.xcodeproj"), targets: [target])
|
let buildAction = BuildAction.test(targets: [appTargetReference])
|
||||||
let generatedProject = GeneratedProject.test(targets: ["App": pbxTarget])
|
let testAction = TestAction.test(targets: [TestableTarget(target: appTargetReference)])
|
||||||
|
let runAction = RunAction.test(configurationName: "Release", executable: appTargetReference, arguments: nil)
|
||||||
|
|
||||||
|
let scheme = Scheme.test(name: "App", buildAction: buildAction, testAction: testAction, runAction: runAction)
|
||||||
|
let project = Project.test(path: projectPath, targets: [target])
|
||||||
|
let graph = Graph.create(dependencies: [(project: project, target: target, dependencies: [])])
|
||||||
|
|
||||||
|
// When
|
||||||
|
let got = try subject.schemeProfileAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: projectPath,
|
||||||
|
generatedProjects: createGeneratedProjects(projects: [project]))
|
||||||
|
|
||||||
let got = subject.schemeProfileAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
// Then
|
||||||
|
let result = try XCTUnwrap(got)
|
||||||
|
let buildable = try XCTUnwrap(result.buildableProductRunnable?.buildableReference)
|
||||||
|
|
||||||
let buildable = got?.buildableProductRunnable?.buildableReference
|
XCTAssertNil(result.macroExpansion)
|
||||||
|
XCTAssertEqual(result.buildableProductRunnable?.runnableDebuggingMode, "0")
|
||||||
|
XCTAssertEqual(buildable.referencedContainer, "container:Project.xcodeproj")
|
||||||
|
XCTAssertEqual(buildable.buildableName, target.productNameWithExtension)
|
||||||
|
XCTAssertEqual(buildable.blueprintName, target.name)
|
||||||
|
XCTAssertEqual(buildable.buildableIdentifier, "primary")
|
||||||
|
|
||||||
XCTAssertNil(got?.macroExpansion)
|
XCTAssertEqual(result.buildConfiguration, "Release")
|
||||||
XCTAssertEqual(got?.buildableProductRunnable?.runnableDebuggingMode, "0")
|
XCTAssertEqual(result.preActions, [])
|
||||||
XCTAssertEqual(buildable?.referencedContainer, "container:project.xcodeproj")
|
XCTAssertEqual(result.postActions, [])
|
||||||
XCTAssertEqual(buildable?.buildableName, target.productNameWithExtension)
|
XCTAssertEqual(result.shouldUseLaunchSchemeArgsEnv, true)
|
||||||
XCTAssertEqual(buildable?.blueprintName, target.name)
|
XCTAssertEqual(result.savedToolIdentifier, "")
|
||||||
XCTAssertEqual(buildable?.buildableIdentifier, "primary")
|
XCTAssertEqual(result.ignoresPersistentStateOnLaunch, false)
|
||||||
|
XCTAssertEqual(result.useCustomWorkingDirectory, false)
|
||||||
XCTAssertEqual(got?.buildConfiguration, "Release")
|
XCTAssertEqual(result.debugDocumentVersioning, true)
|
||||||
XCTAssertEqual(got?.preActions, [])
|
XCTAssertNil(result.commandlineArguments)
|
||||||
XCTAssertEqual(got?.postActions, [])
|
XCTAssertNil(result.environmentVariables)
|
||||||
XCTAssertEqual(got?.shouldUseLaunchSchemeArgsEnv, true)
|
XCTAssertEqual(result.enableTestabilityWhenProfilingTests, true)
|
||||||
XCTAssertEqual(got?.savedToolIdentifier, "")
|
|
||||||
XCTAssertEqual(got?.ignoresPersistentStateOnLaunch, false)
|
|
||||||
XCTAssertEqual(got?.useCustomWorkingDirectory, false)
|
|
||||||
XCTAssertEqual(got?.debugDocumentVersioning, true)
|
|
||||||
XCTAssertNil(got?.commandlineArguments)
|
|
||||||
XCTAssertNil(got?.environmentVariables)
|
|
||||||
XCTAssertEqual(got?.enableTestabilityWhenProfilingTests, true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_schemeProfileAction_when_notRunnableTarget() {
|
func test_schemeProfileAction_when_notRunnableTarget() throws {
|
||||||
|
// Given
|
||||||
|
let projectPath = AbsolutePath("/somepath/Project")
|
||||||
|
|
||||||
let target = Target.test(name: "Library", platform: .iOS, product: .dynamicLibrary)
|
let target = Target.test(name: "Library", platform: .iOS, product: .dynamicLibrary)
|
||||||
|
|
||||||
let buildAction = BuildAction.test(targets: ["Library"])
|
let buildAction = BuildAction.test(targets: [TargetReference(projectPath: projectPath, name: "Library")])
|
||||||
let testAction = TestAction.test(targets: [TestableTarget(target: "Library")])
|
let testAction = TestAction.test(targets: [TestableTarget(target: TargetReference(projectPath: projectPath, name: "Library"))])
|
||||||
let scheme = Scheme.test(name: "Library", buildAction: buildAction, testAction: testAction, runAction: nil)
|
let scheme = Scheme.test(name: "Library", buildAction: buildAction, testAction: testAction, runAction: nil)
|
||||||
|
|
||||||
let project = Project.test(path: AbsolutePath("/project.xcodeproj"), targets: [target])
|
let project = Project.test(path: projectPath, targets: [target])
|
||||||
let pbxTarget = PBXNativeTarget(name: "Library")
|
let graph = Graph.create(dependencies: [(project: project, target: target, dependencies: [])])
|
||||||
let generatedProject = GeneratedProject.test(targets: ["Library": pbxTarget])
|
|
||||||
|
|
||||||
let got = subject.schemeProfileAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
|
||||||
|
|
||||||
let buildable = got?.buildableProductRunnable?.buildableReference
|
// When
|
||||||
|
let got = try subject.schemeProfileAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: projectPath,
|
||||||
|
generatedProjects: createGeneratedProjects(projects: [project]))
|
||||||
|
|
||||||
|
// Then
|
||||||
|
let result = try XCTUnwrap(got)
|
||||||
|
let buildable = result.buildableProductRunnable?.buildableReference
|
||||||
|
|
||||||
XCTAssertNil(buildable)
|
XCTAssertNil(buildable)
|
||||||
XCTAssertEqual(got?.buildConfiguration, "Release")
|
XCTAssertEqual(result.buildConfiguration, "Release")
|
||||||
XCTAssertEqual(got?.preActions, [])
|
XCTAssertEqual(result.preActions, [])
|
||||||
XCTAssertEqual(got?.postActions, [])
|
XCTAssertEqual(result.postActions, [])
|
||||||
XCTAssertEqual(got?.shouldUseLaunchSchemeArgsEnv, true)
|
XCTAssertEqual(result.shouldUseLaunchSchemeArgsEnv, true)
|
||||||
XCTAssertEqual(got?.savedToolIdentifier, "")
|
XCTAssertEqual(result.savedToolIdentifier, "")
|
||||||
XCTAssertEqual(got?.ignoresPersistentStateOnLaunch, false)
|
XCTAssertEqual(result.ignoresPersistentStateOnLaunch, false)
|
||||||
XCTAssertEqual(got?.useCustomWorkingDirectory, false)
|
XCTAssertEqual(result.useCustomWorkingDirectory, false)
|
||||||
XCTAssertEqual(got?.debugDocumentVersioning, true)
|
XCTAssertEqual(result.debugDocumentVersioning, true)
|
||||||
XCTAssertNil(got?.commandlineArguments)
|
XCTAssertNil(result.commandlineArguments)
|
||||||
XCTAssertNil(got?.environmentVariables)
|
XCTAssertNil(result.environmentVariables)
|
||||||
XCTAssertEqual(got?.enableTestabilityWhenProfilingTests, true)
|
XCTAssertEqual(result.enableTestabilityWhenProfilingTests, true)
|
||||||
|
|
||||||
XCTAssertEqual(got?.buildConfiguration, "Release")
|
XCTAssertEqual(result.buildConfiguration, "Release")
|
||||||
XCTAssertEqual(got?.macroExpansion?.referencedContainer, "container:project.xcodeproj")
|
XCTAssertEqual(result.macroExpansion?.referencedContainer, "container:Project.xcodeproj")
|
||||||
XCTAssertEqual(got?.macroExpansion?.buildableName, "libLibrary.dylib")
|
XCTAssertEqual(result.macroExpansion?.buildableName, "libLibrary.dylib")
|
||||||
XCTAssertEqual(got?.macroExpansion?.blueprintName, "Library")
|
XCTAssertEqual(result.macroExpansion?.blueprintName, "Library")
|
||||||
XCTAssertEqual(got?.macroExpansion?.buildableIdentifier, "primary")
|
XCTAssertEqual(result.macroExpansion?.buildableIdentifier, "primary")
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_schemeAnalyzeAction() {
|
func test_schemeAnalyzeAction() throws {
|
||||||
let got = subject.schemeAnalyzeAction(for: .test())
|
// Given
|
||||||
XCTAssertEqual(got.buildConfiguration, "Debug")
|
let projectPath = AbsolutePath("/Project")
|
||||||
|
let target = Target.test(name: "App", platform: .iOS, product: .app)
|
||||||
|
let buildAction = BuildAction.test(targets: [TargetReference(projectPath: projectPath, name: "App")])
|
||||||
|
let scheme = Scheme.test(buildAction: buildAction)
|
||||||
|
|
||||||
|
let project = Project.test(path: projectPath, targets: [target])
|
||||||
|
let graph = Graph.create(dependencies: [(project: project, target: target, dependencies: [])])
|
||||||
|
|
||||||
|
// When
|
||||||
|
let got = try subject.schemeAnalyzeAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: project.path,
|
||||||
|
generatedProjects: createGeneratedProjects(projects: [project]))
|
||||||
|
|
||||||
|
// Then
|
||||||
|
let result = try XCTUnwrap(got)
|
||||||
|
XCTAssertEqual(result.buildConfiguration, "Debug")
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_defaultSchemeArchiveAction() {
|
func test_defaultSchemeArchiveAction() {
|
||||||
|
@ -385,27 +529,43 @@ final class SchemeGeneratorTests: XCTestCase {
|
||||||
XCTAssertEqual(got.revealArchiveInOrganizer, true)
|
XCTAssertEqual(got.revealArchiveInOrganizer, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_schemeArchiveAction() {
|
func test_schemeArchiveAction() throws {
|
||||||
|
// Given
|
||||||
|
let projectPath = AbsolutePath("/Project")
|
||||||
let target = Target.test(name: "App", platform: .iOS, product: .app)
|
let target = Target.test(name: "App", platform: .iOS, product: .app)
|
||||||
let scheme = Scheme.test(archiveAction: ArchiveAction.test(configurationName: "Beta Release",
|
let buildAction = BuildAction.test(targets: [TargetReference(projectPath: projectPath, name: "App")])
|
||||||
revealArchiveInOrganizer: true,
|
let archiveAction = ArchiveAction.test(configurationName: "Beta Release",
|
||||||
customArchiveName: "App [Beta]"))
|
revealArchiveInOrganizer: true,
|
||||||
let pbxTarget = PBXNativeTarget(name: "App")
|
customArchiveName: "App [Beta]")
|
||||||
let project = Project.test(path: AbsolutePath("/project.xcodeproj"), targets: [target])
|
let scheme = Scheme.test(buildAction: buildAction, archiveAction: archiveAction)
|
||||||
let generatedProject = GeneratedProject.test(targets: ["App": pbxTarget])
|
|
||||||
|
let project = Project.test(path: projectPath, targets: [target])
|
||||||
|
let graph = Graph.create(dependencies: [(project: project, target: target, dependencies: [])])
|
||||||
|
|
||||||
let got = subject.schemeArchiveAction(scheme: scheme, project: project, generatedProject: generatedProject)
|
// When
|
||||||
|
let got = try subject.schemeArchiveAction(scheme: scheme,
|
||||||
|
graph: graph,
|
||||||
|
rootPath: project.path,
|
||||||
|
generatedProjects: createGeneratedProjects(projects: [project]))
|
||||||
|
|
||||||
XCTAssertEqual(got.buildConfiguration, "Beta Release")
|
// Then
|
||||||
XCTAssertEqual(got.customArchiveName, "App [Beta]")
|
let result = try XCTUnwrap(got)
|
||||||
XCTAssertEqual(got.revealArchiveInOrganizer, true)
|
XCTAssertEqual(result.buildConfiguration, "Beta Release")
|
||||||
|
XCTAssertEqual(result.customArchiveName, "App [Beta]")
|
||||||
|
XCTAssertEqual(result.revealArchiveInOrganizer, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
private func createGeneratedProjects(projects: [Project]) -> [AbsolutePath: GeneratedProject] {
|
||||||
|
return Dictionary(uniqueKeysWithValues: projects.map {
|
||||||
private func generatedProject(targets: [Target]) -> GeneratedProject {
|
($0.path, generatedProject(targets: $0.targets,
|
||||||
|
projectPath: $0.path.appending(component: "\($0.name).xcodeproj").pathString))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private func generatedProject(targets: [Target], projectPath: String = "/Project.xcodeproj") -> GeneratedProject {
|
||||||
var pbxTargets: [String: PBXNativeTarget] = [:]
|
var pbxTargets: [String: PBXNativeTarget] = [:]
|
||||||
targets.forEach { pbxTargets[$0.name] = PBXNativeTarget(name: $0.name) }
|
targets.forEach { pbxTargets[$0.name] = PBXNativeTarget(name: $0.name) }
|
||||||
return GeneratedProject(pbxproj: .init(), path: AbsolutePath("/project.xcodeproj"), targets: pbxTargets, name: "project.xcodeproj")
|
let path = AbsolutePath(projectPath)
|
||||||
|
return GeneratedProject(pbxproj: .init(), path: path, targets: pbxTargets, name: path.basename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -539,11 +539,13 @@ class GeneratorModelLoaderTest: TuistUnitTestCase {
|
||||||
// Given
|
// Given
|
||||||
let manifest = SchemeManifest.test(name: "Scheme",
|
let manifest = SchemeManifest.test(name: "Scheme",
|
||||||
shared: false)
|
shared: false)
|
||||||
|
let projectPath = AbsolutePath("/somepath/Project")
|
||||||
|
|
||||||
// When
|
// When
|
||||||
let model = TuistCore.Scheme.from(manifest: manifest)
|
let model = TuistCore.Scheme.from(manifest: manifest, projectPath: projectPath)
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
assert(scheme: model, matches: manifest)
|
assert(scheme: model, matches: manifest, path: projectPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_scheme_withActions() throws {
|
func test_scheme_withActions() throws {
|
||||||
|
@ -564,11 +566,14 @@ class GeneratorModelLoaderTest: TuistUnitTestCase {
|
||||||
buildAction: buildAction,
|
buildAction: buildAction,
|
||||||
testAction: testAction,
|
testAction: testAction,
|
||||||
runAction: runActions)
|
runAction: runActions)
|
||||||
|
|
||||||
|
let projectPath = AbsolutePath("/somepath/Project")
|
||||||
|
|
||||||
// When
|
// When
|
||||||
let model = TuistCore.Scheme.from(manifest: manifest)
|
let model = TuistCore.Scheme.from(manifest: manifest, projectPath: projectPath)
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
assert(scheme: model, matches: manifest)
|
assert(scheme: model, matches: manifest, path: projectPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_generatorModelLoaderError_type() {
|
func test_generatorModelLoaderError_type() {
|
||||||
|
@ -791,16 +796,17 @@ class GeneratorModelLoaderTest: TuistUnitTestCase {
|
||||||
|
|
||||||
func assert(scheme: TuistCore.Scheme,
|
func assert(scheme: TuistCore.Scheme,
|
||||||
matches manifest: ProjectDescription.Scheme,
|
matches manifest: ProjectDescription.Scheme,
|
||||||
|
path: AbsolutePath,
|
||||||
file: StaticString = #file,
|
file: StaticString = #file,
|
||||||
line: UInt = #line) {
|
line: UInt = #line) {
|
||||||
XCTAssertEqual(scheme.name, manifest.name, file: file, line: line)
|
XCTAssertEqual(scheme.name, manifest.name, file: file, line: line)
|
||||||
XCTAssertEqual(scheme.shared, manifest.shared, file: file, line: line)
|
XCTAssertEqual(scheme.shared, manifest.shared, file: file, line: line)
|
||||||
optionalAssert(scheme.buildAction, manifest.buildAction) {
|
optionalAssert(scheme.buildAction, manifest.buildAction) {
|
||||||
assert(buildAction: $0, matches: $1, file: file, line: line)
|
assert(buildAction: $0, matches: $1, path: path, file: file, line: line)
|
||||||
}
|
}
|
||||||
|
|
||||||
optionalAssert(scheme.testAction, manifest.testAction) {
|
optionalAssert(scheme.testAction, manifest.testAction) {
|
||||||
assert(testAction: $0, matches: $1, file: file, line: line)
|
assert(testAction: $0, matches: $1, path: path, file: file, line: line)
|
||||||
}
|
}
|
||||||
|
|
||||||
optionalAssert(scheme.runAction, manifest.runAction) {
|
optionalAssert(scheme.runAction, manifest.runAction) {
|
||||||
|
@ -810,16 +816,19 @@ class GeneratorModelLoaderTest: TuistUnitTestCase {
|
||||||
|
|
||||||
func assert(buildAction: TuistCore.BuildAction,
|
func assert(buildAction: TuistCore.BuildAction,
|
||||||
matches manifest: ProjectDescription.BuildAction,
|
matches manifest: ProjectDescription.BuildAction,
|
||||||
|
path: AbsolutePath,
|
||||||
file: StaticString = #file,
|
file: StaticString = #file,
|
||||||
line: UInt = #line) {
|
line: UInt = #line) {
|
||||||
XCTAssertEqual(buildAction.targets, manifest.targets, file: file, line: line)
|
XCTAssertEqual(buildAction.targets, manifest.targets.map { TargetReference(projectPath: path, name: $0) }, file: file, line: line)
|
||||||
}
|
}
|
||||||
|
|
||||||
func assert(testAction: TuistCore.TestAction,
|
func assert(testAction: TuistCore.TestAction,
|
||||||
matches manifest: ProjectDescription.TestAction,
|
matches manifest: ProjectDescription.TestAction,
|
||||||
|
path: AbsolutePath,
|
||||||
file: StaticString = #file,
|
file: StaticString = #file,
|
||||||
line: UInt = #line) {
|
line: UInt = #line) {
|
||||||
let targets = manifest.targets.map { TestableTarget.from(manifest: $0) }
|
|
||||||
|
let targets = manifest.targets.map { TestableTarget.from(manifest: $0, projectPath: path) }
|
||||||
XCTAssertEqual(testAction.targets, targets, file: file, line: line)
|
XCTAssertEqual(testAction.targets, targets, file: file, line: line)
|
||||||
XCTAssertTrue(testAction.configurationName == manifest.configurationName, file: file, line: line)
|
XCTAssertTrue(testAction.configurationName == manifest.configurationName, file: file, line: line)
|
||||||
XCTAssertEqual(testAction.coverage, manifest.coverage, file: file, line: line)
|
XCTAssertEqual(testAction.coverage, manifest.coverage, file: file, line: line)
|
||||||
|
@ -832,10 +841,13 @@ class GeneratorModelLoaderTest: TuistUnitTestCase {
|
||||||
matches manifest: ProjectDescription.RunAction,
|
matches manifest: ProjectDescription.RunAction,
|
||||||
file: StaticString = #file,
|
file: StaticString = #file,
|
||||||
line: UInt = #line) {
|
line: UInt = #line) {
|
||||||
XCTAssertEqual(runAction.executable, manifest.executable, file: file, line: line)
|
var runActionExecutable: String?
|
||||||
|
if let executable = runAction.executable { runActionExecutable = executable.name }
|
||||||
|
|
||||||
|
XCTAssertEqual(runActionExecutable, manifest.executable, file: file, line: line)
|
||||||
XCTAssertTrue(runAction.configurationName == manifest.configurationName, file: file, line: line)
|
XCTAssertTrue(runAction.configurationName == manifest.configurationName, file: file, line: line)
|
||||||
optionalAssert(runAction.arguments, manifest.arguments) {
|
optionalAssert(runAction.arguments, manifest.arguments) {
|
||||||
assert(arguments: $0, matches: $1, file: file, line: line)
|
self.assert(arguments: $0, matches: $1, file: file, line: line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue