From 2c600a7c643445188f16452bc5cda35dc0301e07 Mon Sep 17 00:00:00 2001 From: Bartosz Polaczyk Date: Mon, 15 Feb 2021 02:43:41 +0100 Subject: [PATCH] Add Discovered Dependency File (#1012) * Upgrade XCodeProj to 7.14.0 * Bump to XcodeProj to fork * Add script discoveredDependencyFile * Align cfbundle test * Add changelog mock * Update Documentation * Update SPM manifest * Change property name * Verify defult dependency file to nil * Add JSON encodable test * Add PR number Co-authored-by: Fernanda Geraissate --- CHANGELOG.md | 1 + Docs/ProjectSpec.md | 2 ++ Sources/ProjectSpec/BuildScript.swift | 10 +++++++++- Sources/XcodeGenKit/PBXProjGenerator.swift | 3 ++- .../TestProject/Project.xcodeproj/project.pbxproj | 3 ++- Tests/Fixtures/TestProject/project.yml | 2 ++ Tests/ProjectSpecTests/ProjectSpecTests.swift | 13 ++++++++++++- .../XcodeGenKitTests/ProjectGeneratorTests.swift | 15 ++++++++++++--- 8 files changed, 42 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a5b3eed..d8cdfcc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - More detailed error message with method arguments. [#990](https://github.com/yonaskolb/XcodeGen/pull/990) @bannzai - Added `basedOnDependencyAnalysis` to Project Spec Build Script to be able to choose not to skip the script. [#992](https://github.com/yonaskolb/XcodeGen/pull/992) @myihsan - Add `BuildRule.runOncePerArchitecture` to allow running build rules once per architecture. [#950](https://github.com/yonaskolb/XcodeGen/pull/950) @sascha +- Adds discovered dependency file for a build script [#1012](https://github.com/yonaskolb/XcodeGen/pull/1012) @polac24 @fggeraissate #### Changed - **Breaking**: Info.plists with custom prefixes are no longer added to the Copy Bundle Resources build phase [#945](https://github.com/yonaskolb/XcodeGen/pull/945) @anivaros diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 58ade4d9..573c0b8d 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -565,6 +565,7 @@ Each script can contain: - [ ] **showEnvVars**: **Bool** - whether the environment variables accessible to the script show be printed to the build log. Defaults to yes - [ ] **runOnlyWhenInstalling**: **Bool** - whether the script is only run when installing (`runOnlyForDeploymentPostprocessing`). Defaults to no - [ ] **basedOnDependencyAnalysis**: **Bool** - whether to skip the script if inputs, context, or outputs haven't changed. Defaults to yes +- [ ] **discoveredDependencyFile**: **String** - discovered dependency .d file. Defaults to none Either a **path** or **script** must be defined, the rest are optional. @@ -586,6 +587,7 @@ targets: - $(DERIVED_FILE_DIR)/file2 outputFileLists: - $(SRCROOT)/outputFiles.xcfilelist + discoveredDependencyFile: $(DERIVED_FILE_DIR)/target.d postCompileScripts: - script: swiftlint name: Swiftlint diff --git a/Sources/ProjectSpec/BuildScript.swift b/Sources/ProjectSpec/BuildScript.swift index 4b7fdc8d..f22211bc 100644 --- a/Sources/ProjectSpec/BuildScript.swift +++ b/Sources/ProjectSpec/BuildScript.swift @@ -16,6 +16,7 @@ public struct BuildScript: Equatable { public var runOnlyWhenInstalling: Bool public let showEnvVars: Bool public let basedOnDependencyAnalysis: Bool + public let discoveredDependencyFile: String? public enum ScriptType: Equatable { case path(String) @@ -32,7 +33,8 @@ public struct BuildScript: Equatable { shell: String? = nil, runOnlyWhenInstalling: Bool = runOnlyWhenInstallingDefault, showEnvVars: Bool = showEnvVarsDefault, - basedOnDependencyAnalysis: Bool = basedOnDependencyAnalysisDefault + basedOnDependencyAnalysis: Bool = basedOnDependencyAnalysisDefault, + discoveredDependencyFile: String? = nil ) { self.script = script self.name = name @@ -44,6 +46,7 @@ public struct BuildScript: Equatable { self.runOnlyWhenInstalling = runOnlyWhenInstalling self.showEnvVars = showEnvVars self.basedOnDependencyAnalysis = basedOnDependencyAnalysis + self.discoveredDependencyFile = discoveredDependencyFile } } @@ -66,6 +69,7 @@ extension BuildScript: JSONObjectConvertible { runOnlyWhenInstalling = jsonDictionary.json(atKeyPath: "runOnlyWhenInstalling") ?? BuildScript.runOnlyWhenInstallingDefault showEnvVars = jsonDictionary.json(atKeyPath: "showEnvVars") ?? BuildScript.showEnvVarsDefault basedOnDependencyAnalysis = jsonDictionary.json(atKeyPath: "basedOnDependencyAnalysis") ?? BuildScript.basedOnDependencyAnalysisDefault + discoveredDependencyFile = jsonDictionary.json(atKeyPath: "discoveredDependencyFile") } } @@ -96,6 +100,10 @@ extension BuildScript: JSONEncodable { dict["script"] = string } + if let discoveredDependencyFile = discoveredDependencyFile { + dict["discoveredDependencyFile"] = discoveredDependencyFile + } + return dict } } diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 5be56cce..933d3e46 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -479,7 +479,8 @@ public class PBXProjGenerator { shellScript: shellScript, runOnlyForDeploymentPostprocessing: buildScript.runOnlyWhenInstalling, showEnvVarsInLog: buildScript.showEnvVars, - alwaysOutOfDate: !buildScript.basedOnDependencyAnalysis + alwaysOutOfDate: !buildScript.basedOnDependencyAnalysis, + dependencyFile: buildScript.discoveredDependencyFile ) return addObject(shellScriptPhase) } diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index 964356a9..594fdf96 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -2239,6 +2239,7 @@ CBE633966E8F3819F15270A3 /* MyScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; + dependencyFile = "$(DERIVED_FILE_DIR)/target.d"; files = ( ); inputFileListPaths = ( @@ -2254,7 +2255,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"You ran a script!\"\n"; + shellScript = "echo \"You ran a script!\"\ntouch \"${DERIVED_FILE_DIR}/target.d\"\n"; }; CF3AABFD4A48983B322677DA /* MyScript */ = { isa = PBXShellScriptBuildPhase; diff --git a/Tests/Fixtures/TestProject/project.yml b/Tests/Fixtures/TestProject/project.yml index 688657f1..841d1bc8 100644 --- a/Tests/Fixtures/TestProject/project.yml +++ b/Tests/Fixtures/TestProject/project.yml @@ -149,10 +149,12 @@ targets: - name: MyScript script: | echo "You ran a script!" + touch "${DERIVED_FILE_DIR}/target.d" inputFileLists: - App_iOS/inputList.xcfilelist outputFileLists: - App_iOS/outputList.xcfilelist + discoveredDependencyFile: $(DERIVED_FILE_DIR)/target.d EntitledApp: type: application diff --git a/Tests/ProjectSpecTests/ProjectSpecTests.swift b/Tests/ProjectSpecTests/ProjectSpecTests.swift index c06b7546..7284a799 100644 --- a/Tests/ProjectSpecTests/ProjectSpecTests.swift +++ b/Tests/ProjectSpecTests/ProjectSpecTests.swift @@ -409,7 +409,18 @@ class ProjectSpecTests: XCTestCase { shell: "/bin/bash", runOnlyWhenInstalling: true, showEnvVars: true, - basedOnDependencyAnalysis: false)], + basedOnDependencyAnalysis: false), + BuildScript(script: .path("cmd.sh"), + name: "Dependency script", + inputFiles: ["foo"], + outputFiles: ["bar"], + inputFileLists: ["foo.xcfilelist"], + outputFileLists: ["bar.xcfilelist"], + shell: "/bin/bash", + runOnlyWhenInstalling: true, + showEnvVars: true, + basedOnDependencyAnalysis: true, + discoveredDependencyFile: "dep.d")], buildRules: [BuildRule(fileType: .pattern("*.xcassets"), action: .script("pre_process_swift.py"), name: "My Build Rule", diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index 0a189ea5..7324374c 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -1145,20 +1145,29 @@ class ProjectGeneratorTests: XCTestCase { var scriptSpec = project scriptSpec.targets[0].preBuildScripts = [BuildScript(script: .script("script1"))] scriptSpec.targets[0].postCompileScripts = [BuildScript(script: .script("script2"))] - scriptSpec.targets[0].postBuildScripts = [BuildScript(script: .script("script3"))] + scriptSpec.targets[0].postBuildScripts = [ + BuildScript(script: .script("script3")), + BuildScript(script: .script("script4"), discoveredDependencyFile: "$(DERIVED_FILE_DIR)/target.d") + ] let pbxProject = try scriptSpec.generatePbxProj() - let nativeTarget = try unwrap(pbxProject.nativeTargets.first(where: { $0.buildPhases.count >= 3 })) + let nativeTarget = try unwrap(pbxProject.nativeTargets.first(where: { $0.buildPhases.count >= 4 })) let buildPhases = nativeTarget.buildPhases let scripts = pbxProject.shellScriptBuildPhases - try expect(scripts.count) == 3 + try expect(scripts.count) == 4 let script1 = scripts.first { $0.shellScript == "script1" }! let script2 = scripts.first { $0.shellScript == "script2" }! let script3 = scripts.first { $0.shellScript == "script3" }! + let script4 = scripts.first { $0.shellScript == "script4" }! try expect(buildPhases.contains(script1)) == true try expect(buildPhases.contains(script2)) == true try expect(buildPhases.contains(script3)) == true + try expect(buildPhases.contains(script4)) == true + try expect(script1.dependencyFile).beNil() + try expect(script2.dependencyFile).beNil() + try expect(script3.dependencyFile).beNil() + try expect(script4.dependencyFile) == "$(DERIVED_FILE_DIR)/target.d" } $0.it("generates targets with cylical dependencies") {