Remove symbols from test input/output file lists (#1118)
When a project has a scheme that runs multiple test targets that rely on the `Embed Precompiled Frameworks` script then the new build system fails because there are multiple commands that produce the same target file. This commit prevents adding symbol files to the input/output file lists for test targets to prevent this error from occuring. Fixes tuist/tuist#919
This commit is contained in:
parent
4bae7665ef
commit
79395e0430
|
@ -4,6 +4,10 @@ Please, check out guidelines: https://keepachangelog.com/en/1.0.0/
|
||||||
|
|
||||||
## Next
|
## Next
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Prevent `Multiple commands produce XXXXX` error produced by multiple test targets using “Embed Precompiled Frameworks” script https://github.com/tuist/tuist/pull/1118 by @paulsamuels
|
||||||
|
|
||||||
## 1.5.2
|
## 1.5.2
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -46,15 +46,6 @@
|
||||||
"version": "0.4.1"
|
"version": "0.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"package": "PathKit",
|
|
||||||
"repositoryURL": "https://github.com/kylef/PathKit.git",
|
|
||||||
"state": {
|
|
||||||
"branch": null,
|
|
||||||
"revision": "73f8e9dca9b7a3078cb79128217dc8f2e585a511",
|
|
||||||
"version": "1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"package": "RxSwift",
|
"package": "RxSwift",
|
||||||
"repositoryURL": "https://github.com/ReactiveX/RxSwift.git",
|
"repositoryURL": "https://github.com/ReactiveX/RxSwift.git",
|
||||||
|
|
|
@ -89,6 +89,7 @@ final class LinkGenerator: LinkGenerating {
|
||||||
linkableModules: linkableModules)
|
linkableModules: linkableModules)
|
||||||
|
|
||||||
try generateEmbedPhase(dependencies: embeddableFrameworks,
|
try generateEmbedPhase(dependencies: embeddableFrameworks,
|
||||||
|
target: target,
|
||||||
pbxTarget: pbxTarget,
|
pbxTarget: pbxTarget,
|
||||||
pbxproj: pbxproj,
|
pbxproj: pbxproj,
|
||||||
fileElements: fileElements,
|
fileElements: fileElements,
|
||||||
|
@ -152,6 +153,7 @@ final class LinkGenerator: LinkGenerating {
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateEmbedPhase(dependencies: [GraphDependencyReference],
|
func generateEmbedPhase(dependencies: [GraphDependencyReference],
|
||||||
|
target: Target,
|
||||||
pbxTarget: PBXTarget,
|
pbxTarget: PBXTarget,
|
||||||
pbxproj: PBXProj,
|
pbxproj: PBXProj,
|
||||||
fileElements: ProjectFileElements,
|
fileElements: ProjectFileElements,
|
||||||
|
@ -201,7 +203,10 @@ final class LinkGenerator: LinkGenerating {
|
||||||
if frameworkReferences.isEmpty {
|
if frameworkReferences.isEmpty {
|
||||||
precompiledEmbedPhase.shellScript = "echo \"Skipping, nothing to be embedded.\""
|
precompiledEmbedPhase.shellScript = "echo \"Skipping, nothing to be embedded.\""
|
||||||
} else {
|
} else {
|
||||||
let script = try embedScriptGenerator.script(sourceRootPath: sourceRootPath, frameworkReferences: frameworkReferences)
|
let script = try embedScriptGenerator.script(sourceRootPath: sourceRootPath,
|
||||||
|
frameworkReferences: frameworkReferences,
|
||||||
|
includeSymbolsInFileLists: !target.product.testsBundle)
|
||||||
|
|
||||||
precompiledEmbedPhase.shellScript = script.script
|
precompiledEmbedPhase.shellScript = script.script
|
||||||
precompiledEmbedPhase.inputPaths = script.inputPaths.map(\.pathString)
|
precompiledEmbedPhase.inputPaths = script.inputPaths.map(\.pathString)
|
||||||
precompiledEmbedPhase.outputPaths = script.outputPaths
|
precompiledEmbedPhase.outputPaths = script.outputPaths
|
||||||
|
|
|
@ -12,7 +12,10 @@ protocol EmbedScriptGenerating {
|
||||||
/// to embed the given frameworks into the compiled product.
|
/// to embed the given frameworks into the compiled product.
|
||||||
/// - Parameter sourceRootPath: Directory where the Xcode project will be created.
|
/// - Parameter sourceRootPath: Directory where the Xcode project will be created.
|
||||||
/// - Parameter frameworkReferences: Framework references.
|
/// - Parameter frameworkReferences: Framework references.
|
||||||
func script(sourceRootPath: AbsolutePath, frameworkReferences: [GraphDependencyReference]) throws -> EmbedScript
|
/// - Parameter includeSymbolsInFileLists: Whether or not to list DSYMs/bcsymbol files in the input/output file list.
|
||||||
|
func script(sourceRootPath: AbsolutePath,
|
||||||
|
frameworkReferences: [GraphDependencyReference],
|
||||||
|
includeSymbolsInFileLists: Bool) throws -> EmbedScript
|
||||||
}
|
}
|
||||||
|
|
||||||
/// It represents a embed frameworks script.
|
/// It represents a embed frameworks script.
|
||||||
|
@ -30,11 +33,13 @@ struct EmbedScript {
|
||||||
final class EmbedScriptGenerator: EmbedScriptGenerating {
|
final class EmbedScriptGenerator: EmbedScriptGenerating {
|
||||||
typealias FrameworkScript = (script: String, inputPaths: [RelativePath], outputPaths: [String])
|
typealias FrameworkScript = (script: String, inputPaths: [RelativePath], outputPaths: [String])
|
||||||
|
|
||||||
func script(sourceRootPath: AbsolutePath, frameworkReferences: [GraphDependencyReference]) throws -> EmbedScript {
|
func script(sourceRootPath: AbsolutePath, frameworkReferences: [GraphDependencyReference], includeSymbolsInFileLists: Bool) throws -> EmbedScript {
|
||||||
var script = baseScript()
|
var script = baseScript()
|
||||||
script.append("\n")
|
script.append("\n")
|
||||||
|
|
||||||
let (frameworksScript, inputPaths, outputPaths) = try self.frameworksScript(sourceRootPath: sourceRootPath, frameworkReferences: frameworkReferences)
|
let (frameworksScript, inputPaths, outputPaths) = try self.frameworksScript(sourceRootPath: sourceRootPath,
|
||||||
|
frameworkReferences: frameworkReferences,
|
||||||
|
includeSymbolsInFileLists: includeSymbolsInFileLists)
|
||||||
script.append(frameworksScript)
|
script.append(frameworksScript)
|
||||||
|
|
||||||
return EmbedScript(script: script, inputPaths: inputPaths, outputPaths: outputPaths)
|
return EmbedScript(script: script, inputPaths: inputPaths, outputPaths: outputPaths)
|
||||||
|
@ -42,11 +47,25 @@ final class EmbedScriptGenerator: EmbedScriptGenerating {
|
||||||
|
|
||||||
// MARK: - Fileprivate
|
// MARK: - Fileprivate
|
||||||
|
|
||||||
fileprivate func frameworksScript(sourceRootPath: AbsolutePath, frameworkReferences: [GraphDependencyReference]) throws -> FrameworkScript {
|
fileprivate func frameworksScript(sourceRootPath: AbsolutePath,
|
||||||
|
frameworkReferences: [GraphDependencyReference],
|
||||||
|
includeSymbolsInFileLists: Bool) throws -> FrameworkScript {
|
||||||
var script = ""
|
var script = ""
|
||||||
var inputPaths: [RelativePath] = []
|
var inputPaths: [RelativePath] = []
|
||||||
var outputPaths: [String] = []
|
var outputPaths: [String] = []
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is required to prevent the new build system from failing when multiple test targets cause the same
|
||||||
|
* output files. The symbols aren't really required to be copied for tests so this patch excludes them.
|
||||||
|
* For more details see the discussion on https://github.com/tuist/tuist/issues/919.
|
||||||
|
*/
|
||||||
|
func addSymbolsIfRequired(inputPath: RelativePath, outputPath: String) {
|
||||||
|
if includeSymbolsInFileLists {
|
||||||
|
inputPaths.append(inputPath)
|
||||||
|
outputPaths.append(outputPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for frameworkReference in frameworkReferences {
|
for frameworkReference in frameworkReferences {
|
||||||
guard case let GraphDependencyReference.framework(path, _, _, dsymPath, bcsymbolmapPaths, _, _, _) = frameworkReference else {
|
guard case let GraphDependencyReference.framework(path, _, _, dsymPath, bcsymbolmapPaths, _, _, _) = frameworkReference else {
|
||||||
preconditionFailure("references need to be of type framework")
|
preconditionFailure("references need to be of type framework")
|
||||||
|
@ -63,16 +82,14 @@ final class EmbedScriptGenerator: EmbedScriptGenerating {
|
||||||
if let dsymPath = dsymPath {
|
if let dsymPath = dsymPath {
|
||||||
let relativeDsymPath = dsymPath.relative(to: sourceRootPath)
|
let relativeDsymPath = dsymPath.relative(to: sourceRootPath)
|
||||||
script.append("install_dsym \"\(relativeDsymPath.pathString)\"\n")
|
script.append("install_dsym \"\(relativeDsymPath.pathString)\"\n")
|
||||||
inputPaths.append(relativeDsymPath)
|
addSymbolsIfRequired(inputPath: relativeDsymPath, outputPath: "${DWARF_DSYM_FOLDER_PATH}/\(dsymPath.basename)")
|
||||||
outputPaths.append("${DWARF_DSYM_FOLDER_PATH}/\(dsymPath.basename)")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// .bcsymbolmap
|
// .bcsymbolmap
|
||||||
for bcsymbolmapPath in bcsymbolmapPaths {
|
for bcsymbolmapPath in bcsymbolmapPaths {
|
||||||
let relativeDsymPath = bcsymbolmapPath.relative(to: sourceRootPath)
|
let relativeDsymPath = bcsymbolmapPath.relative(to: sourceRootPath)
|
||||||
script.append("install_bcsymbolmap \"\(relativeDsymPath.pathString)\"\n")
|
script.append("install_bcsymbolmap \"\(relativeDsymPath.pathString)\"\n")
|
||||||
inputPaths.append(relativeDsymPath)
|
addSymbolsIfRequired(inputPath: relativeDsymPath, outputPath: "${BUILT_PRODUCTS_DIR}/\(relativeDsymPath.basename)")
|
||||||
outputPaths.append("${BUILT_PRODUCTS_DIR}/\(relativeDsymPath.basename)")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (script: script, inputPaths: inputPaths, outputPaths: outputPaths)
|
return (script: script, inputPaths: inputPaths, outputPaths: outputPaths)
|
||||||
|
|
|
@ -40,7 +40,7 @@ final class LinkGeneratorErrorTests: XCTestCase {
|
||||||
dependencies.append(GraphDependencyReference.testFramework())
|
dependencies.append(GraphDependencyReference.testFramework())
|
||||||
dependencies.append(GraphDependencyReference.product(target: "Test", productName: "Test.framework"))
|
dependencies.append(GraphDependencyReference.product(target: "Test", productName: "Test.framework"))
|
||||||
let pbxproj = PBXProj()
|
let pbxproj = PBXProj()
|
||||||
let pbxTarget = PBXNativeTarget(name: "Test")
|
let (pbxTarget, target) = createTargets(product: .framework)
|
||||||
let fileElements = ProjectFileElements()
|
let fileElements = ProjectFileElements()
|
||||||
let wakaFile = PBXFileReference()
|
let wakaFile = PBXFileReference()
|
||||||
pbxproj.add(object: wakaFile)
|
pbxproj.add(object: wakaFile)
|
||||||
|
@ -52,6 +52,7 @@ final class LinkGeneratorErrorTests: XCTestCase {
|
||||||
|
|
||||||
// When
|
// When
|
||||||
try subject.generateEmbedPhase(dependencies: dependencies,
|
try subject.generateEmbedPhase(dependencies: dependencies,
|
||||||
|
target: target,
|
||||||
pbxTarget: pbxTarget,
|
pbxTarget: pbxTarget,
|
||||||
pbxproj: pbxproj,
|
pbxproj: pbxproj,
|
||||||
fileElements: fileElements,
|
fileElements: fileElements,
|
||||||
|
@ -72,15 +73,76 @@ final class LinkGeneratorErrorTests: XCTestCase {
|
||||||
XCTAssertEqual(settings, ["ATTRIBUTES": ["CodeSignOnCopy", "RemoveHeadersOnCopy"]])
|
XCTAssertEqual(settings, ["ATTRIBUTES": ["CodeSignOnCopy", "RemoveHeadersOnCopy"]])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_generateEmbedPhase_includesSymbols_when_nonTestTarget() throws {
|
||||||
|
try Product.allCases.filter { !$0.testsBundle }.forEach { product in
|
||||||
|
// Given
|
||||||
|
|
||||||
|
var dependencies: [GraphDependencyReference] = []
|
||||||
|
dependencies.append(GraphDependencyReference.testFramework())
|
||||||
|
dependencies.append(GraphDependencyReference.product(target: "Test", productName: "Test.framework"))
|
||||||
|
let pbxproj = PBXProj()
|
||||||
|
let (pbxTarget, target) = createTargets(product: product)
|
||||||
|
let fileElements = ProjectFileElements()
|
||||||
|
let wakaFile = PBXFileReference()
|
||||||
|
pbxproj.add(object: wakaFile)
|
||||||
|
fileElements.products["Test"] = wakaFile
|
||||||
|
let sourceRootPath = AbsolutePath("/")
|
||||||
|
embedScriptGenerator.scriptStub = .success(EmbedScript(script: "script",
|
||||||
|
inputPaths: [RelativePath("frameworks/A.framework")],
|
||||||
|
outputPaths: ["output/A.framework"]))
|
||||||
|
|
||||||
|
// When
|
||||||
|
try subject.generateEmbedPhase(dependencies: dependencies,
|
||||||
|
target: target,
|
||||||
|
pbxTarget: pbxTarget,
|
||||||
|
pbxproj: pbxproj,
|
||||||
|
fileElements: fileElements,
|
||||||
|
sourceRootPath: sourceRootPath)
|
||||||
|
|
||||||
|
XCTAssert(embedScriptGenerator.scriptArgs.last?.2 == true, "Expected `includeSymbolsInFileLists == true` for product `\(product)`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_generateEmbedPhase_doesNot_includesSymbols_when_testTarget() throws {
|
||||||
|
try Product.allCases.filter { $0.testsBundle }.forEach { product in
|
||||||
|
// Given
|
||||||
|
|
||||||
|
var dependencies: [GraphDependencyReference] = []
|
||||||
|
dependencies.append(GraphDependencyReference.testFramework())
|
||||||
|
dependencies.append(GraphDependencyReference.product(target: "Test", productName: "Test.framework"))
|
||||||
|
let pbxproj = PBXProj()
|
||||||
|
let (pbxTarget, target) = createTargets(product: product)
|
||||||
|
let fileElements = ProjectFileElements()
|
||||||
|
let wakaFile = PBXFileReference()
|
||||||
|
pbxproj.add(object: wakaFile)
|
||||||
|
fileElements.products["Test"] = wakaFile
|
||||||
|
let sourceRootPath = AbsolutePath("/")
|
||||||
|
embedScriptGenerator.scriptStub = .success(EmbedScript(script: "script",
|
||||||
|
inputPaths: [RelativePath("frameworks/A.framework")],
|
||||||
|
outputPaths: ["output/A.framework"]))
|
||||||
|
|
||||||
|
// When
|
||||||
|
try subject.generateEmbedPhase(dependencies: dependencies,
|
||||||
|
target: target,
|
||||||
|
pbxTarget: pbxTarget,
|
||||||
|
pbxproj: pbxproj,
|
||||||
|
fileElements: fileElements,
|
||||||
|
sourceRootPath: sourceRootPath)
|
||||||
|
|
||||||
|
XCTAssert(embedScriptGenerator.scriptArgs.last?.2 == false, "Expected `includeSymbolsInFileLists == false` for product `\(product)`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func test_generateEmbedPhase_throws_when_aProductIsMissing() throws {
|
func test_generateEmbedPhase_throws_when_aProductIsMissing() throws {
|
||||||
var dependencies: [GraphDependencyReference] = []
|
var dependencies: [GraphDependencyReference] = []
|
||||||
dependencies.append(GraphDependencyReference.product(target: "Test", productName: "Test.framework"))
|
dependencies.append(GraphDependencyReference.product(target: "Test", productName: "Test.framework"))
|
||||||
let pbxproj = PBXProj()
|
let pbxproj = PBXProj()
|
||||||
let pbxTarget = PBXNativeTarget(name: "Test")
|
let (pbxTarget, target) = createTargets(product: .framework)
|
||||||
let fileElements = ProjectFileElements()
|
let fileElements = ProjectFileElements()
|
||||||
let sourceRootPath = AbsolutePath("/")
|
let sourceRootPath = AbsolutePath("/")
|
||||||
|
|
||||||
XCTAssertThrowsError(try subject.generateEmbedPhase(dependencies: dependencies,
|
XCTAssertThrowsError(try subject.generateEmbedPhase(dependencies: dependencies,
|
||||||
|
target: target,
|
||||||
pbxTarget: pbxTarget,
|
pbxTarget: pbxTarget,
|
||||||
pbxproj: pbxproj,
|
pbxproj: pbxproj,
|
||||||
fileElements: fileElements,
|
fileElements: fileElements,
|
||||||
|
@ -94,7 +156,7 @@ final class LinkGeneratorErrorTests: XCTestCase {
|
||||||
var dependencies: [GraphDependencyReference] = []
|
var dependencies: [GraphDependencyReference] = []
|
||||||
dependencies.append(GraphDependencyReference.testXCFramework(path: "/Frameworks/Test.xcframework"))
|
dependencies.append(GraphDependencyReference.testXCFramework(path: "/Frameworks/Test.xcframework"))
|
||||||
let pbxproj = PBXProj()
|
let pbxproj = PBXProj()
|
||||||
let pbxTarget = PBXNativeTarget(name: "Test")
|
let (pbxTarget, target) = createTargets(product: .framework)
|
||||||
let sourceRootPath = AbsolutePath("/")
|
let sourceRootPath = AbsolutePath("/")
|
||||||
|
|
||||||
let group = PBXGroup()
|
let group = PBXGroup()
|
||||||
|
@ -105,6 +167,7 @@ final class LinkGeneratorErrorTests: XCTestCase {
|
||||||
|
|
||||||
// When
|
// When
|
||||||
try subject.generateEmbedPhase(dependencies: dependencies,
|
try subject.generateEmbedPhase(dependencies: dependencies,
|
||||||
|
target: target,
|
||||||
pbxTarget: pbxTarget,
|
pbxTarget: pbxTarget,
|
||||||
pbxproj: pbxproj,
|
pbxproj: pbxproj,
|
||||||
fileElements: fileElements,
|
fileElements: fileElements,
|
||||||
|
@ -539,6 +602,13 @@ final class LinkGeneratorErrorTests: XCTestCase {
|
||||||
return projectFileElements
|
return projectFileElements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func createTargets(product: Product) -> (PBXTarget, Target) {
|
||||||
|
return (
|
||||||
|
PBXNativeTarget(name: "Test"),
|
||||||
|
Target.test(name: "Test", product: product)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private func createFileElements(fileAbsolutePath: AbsolutePath) -> ProjectFileElements {
|
private func createFileElements(fileAbsolutePath: AbsolutePath) -> ProjectFileElements {
|
||||||
let fileElements = ProjectFileElements()
|
let fileElements = ProjectFileElements()
|
||||||
fileElements.elements[fileAbsolutePath] = PBXFileReference(path: fileAbsolutePath.basename)
|
fileElements.elements[fileAbsolutePath] = PBXFileReference(path: fileAbsolutePath.basename)
|
||||||
|
|
|
@ -20,7 +20,7 @@ final class EmbedScriptGeneratorTests: TuistUnitTestCase {
|
||||||
subject = nil
|
subject = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func test_script() throws {
|
func test_script_when_includingSymbolsInFileLists() throws {
|
||||||
// Given
|
// Given
|
||||||
let path = AbsolutePath("/frameworks/tuist.framework")
|
let path = AbsolutePath("/frameworks/tuist.framework")
|
||||||
let dsymPath = AbsolutePath("/frameworks/tuist.dSYM")
|
let dsymPath = AbsolutePath("/frameworks/tuist.dSYM")
|
||||||
|
@ -30,7 +30,7 @@ final class EmbedScriptGeneratorTests: TuistUnitTestCase {
|
||||||
dsymPath: dsymPath,
|
dsymPath: dsymPath,
|
||||||
bcsymbolmapPaths: [bcsymbolPath])
|
bcsymbolmapPaths: [bcsymbolPath])
|
||||||
// When
|
// When
|
||||||
let got = try subject.script(sourceRootPath: framework.precompiledPath!.parentDirectory, frameworkReferences: [framework])
|
let got = try subject.script(sourceRootPath: framework.precompiledPath!.parentDirectory, frameworkReferences: [framework], includeSymbolsInFileLists: true)
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
XCTAssertEqual(got.inputPaths, [
|
XCTAssertEqual(got.inputPaths, [
|
||||||
|
@ -47,4 +47,29 @@ final class EmbedScriptGeneratorTests: TuistUnitTestCase {
|
||||||
XCTAssertTrue(got.script.contains("install_dsym \"\(dsymPath.basename)\""))
|
XCTAssertTrue(got.script.contains("install_dsym \"\(dsymPath.basename)\""))
|
||||||
XCTAssertTrue(got.script.contains("install_bcsymbolmap \"\(bcsymbolPath.basename)\""))
|
XCTAssertTrue(got.script.contains("install_bcsymbolmap \"\(bcsymbolPath.basename)\""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_script_when_not_includingSymbolsInFileLists() throws {
|
||||||
|
// Given
|
||||||
|
let path = AbsolutePath("/frameworks/tuist.framework")
|
||||||
|
let dsymPath = AbsolutePath("/frameworks/tuist.dSYM")
|
||||||
|
let bcsymbolPath = AbsolutePath("/frameworks/tuist.bcsymbolmap")
|
||||||
|
let framework = GraphDependencyReference.testFramework(path: path,
|
||||||
|
binaryPath: path.appending(component: "tuist"),
|
||||||
|
dsymPath: dsymPath,
|
||||||
|
bcsymbolmapPaths: [bcsymbolPath])
|
||||||
|
// When
|
||||||
|
let got = try subject.script(sourceRootPath: framework.precompiledPath!.parentDirectory, frameworkReferences: [framework], includeSymbolsInFileLists: false)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertEqual(got.inputPaths, [
|
||||||
|
RelativePath(path.basename),
|
||||||
|
])
|
||||||
|
XCTAssertEqual(got.outputPaths, [
|
||||||
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/\(path.basename)",
|
||||||
|
])
|
||||||
|
|
||||||
|
XCTAssertTrue(got.script.contains("install_framework \"\(path.basename)\""))
|
||||||
|
XCTAssertTrue(got.script.contains("install_dsym \"\(dsymPath.basename)\""))
|
||||||
|
XCTAssertTrue(got.script.contains("install_bcsymbolmap \"\(bcsymbolPath.basename)\""))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,13 @@ import TuistCore
|
||||||
@testable import TuistSupportTesting
|
@testable import TuistSupportTesting
|
||||||
|
|
||||||
final class MockEmbedScriptGenerator: EmbedScriptGenerating {
|
final class MockEmbedScriptGenerator: EmbedScriptGenerating {
|
||||||
var scriptArgs: [(AbsolutePath, [GraphDependencyReference])] = []
|
var scriptArgs: [(AbsolutePath, [GraphDependencyReference], Bool)] = []
|
||||||
var scriptStub: Result<EmbedScript, Error>?
|
var scriptStub: Result<EmbedScript, Error>?
|
||||||
|
|
||||||
func script(sourceRootPath: AbsolutePath,
|
func script(sourceRootPath: AbsolutePath,
|
||||||
frameworkReferences: [GraphDependencyReference]) throws -> EmbedScript {
|
frameworkReferences: [GraphDependencyReference],
|
||||||
scriptArgs.append((sourceRootPath, frameworkReferences))
|
includeSymbolsInFileLists: Bool) throws -> EmbedScript {
|
||||||
|
scriptArgs.append((sourceRootPath, frameworkReferences, includeSymbolsInFileLists))
|
||||||
if let scriptStub = scriptStub {
|
if let scriptStub = scriptStub {
|
||||||
switch scriptStub {
|
switch scriptStub {
|
||||||
case let .failure(error): throw error
|
case let .failure(error): throw error
|
||||||
|
|
|
@ -30,7 +30,7 @@ Scenario: The project is an iOS application with Carthage frameworks (ios_app_wi
|
||||||
And I have a working directory
|
And I have a working directory
|
||||||
Then I copy the fixture ios_app_with_carthage_frameworks into the working directory
|
Then I copy the fixture ios_app_with_carthage_frameworks into the working directory
|
||||||
Then tuist generates the project
|
Then tuist generates the project
|
||||||
Then I should be able to build for iOS the scheme App
|
Then I should be able to build for iOS the scheme AllTargets
|
||||||
Then the product 'App.app' with destination 'Debug-iphoneos' contains the framework 'RxSwift' without architecture 'armv7'
|
Then the product 'App.app' with destination 'Debug-iphoneos' contains the framework 'RxSwift' without architecture 'armv7'
|
||||||
Then the product 'App.app' with destination 'Debug-iphoneos' contains the framework 'RxSwift' with architecture 'arm64'
|
Then the product 'App.app' with destination 'Debug-iphoneos' contains the framework 'RxSwift' with architecture 'arm64'
|
||||||
Then the product 'App.app' with destination 'Debug-iphoneos' does not contain headers
|
Then the product 'App.app' with destination 'Debug-iphoneos' does not contain headers
|
||||||
|
@ -44,4 +44,4 @@ Scenario: The project is an iOS application with extensions (ios_app_with_extens
|
||||||
Then the product 'App.app' with destination 'Debug-iphoneos' contains extension 'StickersPackExtension'
|
Then the product 'App.app' with destination 'Debug-iphoneos' contains extension 'StickersPackExtension'
|
||||||
Then the product 'App.app' with destination 'Debug-iphoneos' contains extension 'NotificationServiceExtension'
|
Then the product 'App.app' with destination 'Debug-iphoneos' contains extension 'NotificationServiceExtension'
|
||||||
Then the product 'App.app' with destination 'Debug-iphoneos' contains extension 'NotificationServiceExtension'
|
Then the product 'App.app' with destination 'Debug-iphoneos' contains extension 'NotificationServiceExtension'
|
||||||
Then the product 'App.app' with destination 'Debug-iphoneos' does not contain headers
|
Then the product 'App.app' with destination 'Debug-iphoneos' does not contain headers
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class CoreFile {
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
public func hello() -> String {
|
||||||
|
return "CoreFile.hello()"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
import Foundation
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable import Core
|
||||||
|
|
||||||
|
final class CoreTests: XCTestCase {
|
||||||
|
|
||||||
|
func testHello() {
|
||||||
|
let sut = CoreFile()
|
||||||
|
|
||||||
|
XCTAssertEqual("CoreTests.hello()", sut.hello())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,14 +2,51 @@ import ProjectDescription
|
||||||
|
|
||||||
let project = Project(name: "App",
|
let project = Project(name: "App",
|
||||||
targets: [
|
targets: [
|
||||||
Target(name: "App",
|
Target(name: "App",
|
||||||
platform: .iOS,
|
platform: .iOS,
|
||||||
product: .app,
|
product: .app,
|
||||||
bundleId: "io.tuist.App",
|
bundleId: "io.tuist.App",
|
||||||
infoPlist: .extendingDefault(with: [:]),
|
infoPlist: .default,
|
||||||
sources: "Sources/**",
|
sources: "Sources/**",
|
||||||
resources: "Sources/Main.storyboard",
|
resources: "Sources/Main.storyboard",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.framework(path: "Carthage/Build/iOS/RxSwift.framework")
|
.target(name: "Core"),
|
||||||
])
|
.framework(path: "Carthage/Build/iOS/RxSwift.framework")
|
||||||
|
]),
|
||||||
|
Target(name: "AppTests",
|
||||||
|
platform: .iOS,
|
||||||
|
product: .unitTests,
|
||||||
|
bundleId: "io.tuist.AppTests",
|
||||||
|
infoPlist: .default,
|
||||||
|
sources: "Tests/**",
|
||||||
|
dependencies: [
|
||||||
|
.target(name: "App"),
|
||||||
|
]),
|
||||||
|
Target(name: "Core",
|
||||||
|
platform: .iOS,
|
||||||
|
product: .framework,
|
||||||
|
bundleId: "io.tuist.Core",
|
||||||
|
infoPlist: .default,
|
||||||
|
sources: "Core/**",
|
||||||
|
dependencies: [
|
||||||
|
.framework(path: "Carthage/Build/iOS/RxSwift.framework"),
|
||||||
|
]),
|
||||||
|
Target(name: "CoreTests",
|
||||||
|
platform: .iOS,
|
||||||
|
product: .unitTests,
|
||||||
|
bundleId: "io.tuist.CoreTests",
|
||||||
|
infoPlist: .default,
|
||||||
|
sources: "CoreTests/**",
|
||||||
|
dependencies: [
|
||||||
|
.target(name: "Core")
|
||||||
|
])
|
||||||
|
], schemes: [
|
||||||
|
Scheme(name: "AllTargets",
|
||||||
|
shared: true,
|
||||||
|
buildAction: BuildAction(targets: [
|
||||||
|
"App",
|
||||||
|
"AppTests",
|
||||||
|
"Core",
|
||||||
|
"CoreTests"
|
||||||
|
]))
|
||||||
])
|
])
|
||||||
|
|
|
@ -8,4 +8,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
func applicationDidFinishLaunching(_: UIApplication) {
|
func applicationDidFinishLaunching(_: UIApplication) {
|
||||||
let observable = Observable<String>.just("hello world")
|
let observable = Observable<String>.just("hello world")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func hello() -> String {
|
||||||
|
return "AppDelegate.hello()"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import Foundation
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable import App
|
||||||
|
|
||||||
|
final class AppTests: XCTestCase {
|
||||||
|
|
||||||
|
func testHello() {
|
||||||
|
let sut = AppDelegate()
|
||||||
|
|
||||||
|
XCTAssertEqual("AppDelegate.hello()", sut.hello())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue