diff --git a/CHANGELOG.md b/CHANGELOG.md index 95807fa5..84803b9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Next Version #### Added +- Added pre and post command options. Useful for running `pod install` in combination with `--use-cache` [#759](https://github.com/yonaskolb/XcodeGen/pull/759) @yonaskolb - Support for language and region settings on a target basis [#728](https://github.com/yonaskolb/XcodeGen/pull/728) @FranzBusch - Added option to generate only Info.plist files with `--only-plists` [#739](https://github.com/yonaskolb/XcodeGen/pull/739) @namolnad - Added the option to specify a `simulateLocation` in a scheme [#722](https://github.com/yonaskolb/XcodeGen/issues/722) @basvankuijck diff --git a/Docs/FAQ.md b/Docs/FAQ.md index f059687e..6f47f1f5 100644 --- a/Docs/FAQ.md +++ b/Docs/FAQ.md @@ -12,9 +12,12 @@ Absolutely. You will get the most out of XcodeGen by adding your project to your If files were added or removed in the new checkout you will most likely need to run `xcodegen` again so that your project will reference all your files. Unfortunately this is a manual step at the moment, but in the future this could be automated. For now you can always add xcodegen as a git `post-checkout` hook. +It's recommended to use `--use-cache` so that the project is not needlessly generated. ## Can I use CocoaPods -Yes, simply generate your project and then run `pod install` which will integrate with your project and create a workspace. +Yes, you will just need to run `pod install` after the project is generated to integrate Cocoapods changes. + +It's recommended to use a combination of `--use-cache` and the `postGenCommand` option which will only generate the project if required, and then only run `pod install` if the project has been regenerated. ## Can I use Crashlytics Yes, but you need to use a little trick when using CocoaPods. Add this script in your `Podfile`: diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index d134be84..4d9be823 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -123,12 +123,15 @@ Note that target names can also be changed by adding a `name` property to a targ - [ ] **generateEmptyDirectories**: **Bool** - If this is `true` then empty directories will be added to project too else will be missed. Defaults to `false`. - [ ] **findCarthageFrameworks**: **Bool** - When this is set to `true`, all the invididual frameworks for Carthage dependencies will automatically be found. This property can be overriden individually for each carthage dependency - for more details see See **findFrameworks** in the [Dependency](#dependency) section. Defaults to `false`. - [ ] **localPackagesGroup**: **String** - The group name that local packages are put into. This defaults to `Packages` +- [ ] **preGenCommand**: **String** - A bash command to run before the project has been generated. If the project isn't generated due to no changes when using the cache then this won't run. This is useful for running things like generating resources files before the project is regenerated. +- [ ] **postGenCommand**: **String** - A bash command to run after the project has been generated. If the project isn't generated due to no changes when using the cache then this won't run. This is useful for running things like `pod install` only if the project is actually regenerated. ```yaml options: deploymentTarget: watchOS: "2.0" tvOS: "10.0" + postGenCommand: pod install ``` ### Configs diff --git a/Sources/ProjectSpec/SpecOptions.swift b/Sources/ProjectSpec/SpecOptions.swift index 24d124ec..5229b740 100644 --- a/Sources/ProjectSpec/SpecOptions.swift +++ b/Sources/ProjectSpec/SpecOptions.swift @@ -28,6 +28,8 @@ public struct SpecOptions: Equatable { public var generateEmptyDirectories: Bool public var findCarthageFrameworks: Bool public var localPackagesGroup: String? + public var preGenCommand: String? + public var postGenCommand: String? public enum ValidationType: String { case missingConfigs @@ -84,7 +86,9 @@ public struct SpecOptions: Equatable { groupSortPosition: GroupSortPosition = groupSortPositionDefault, generateEmptyDirectories: Bool = generateEmptyDirectoriesDefault, findCarthageFrameworks: Bool = findCarthageFrameworksDefault, - localPackagesGroup: String? = nil + localPackagesGroup: String? = nil, + preGenCommand: String? = nil, + postGenCommand: String? = nil ) { self.minimumXcodeGenVersion = minimumXcodeGenVersion self.carthageBuildPath = carthageBuildPath @@ -105,6 +109,8 @@ public struct SpecOptions: Equatable { self.generateEmptyDirectories = generateEmptyDirectories self.findCarthageFrameworks = findCarthageFrameworks self.localPackagesGroup = localPackagesGroup + self.preGenCommand = preGenCommand + self.postGenCommand = postGenCommand } } @@ -133,6 +139,8 @@ extension SpecOptions: JSONObjectConvertible { generateEmptyDirectories = jsonDictionary.json(atKeyPath: "generateEmptyDirectories") ?? SpecOptions.generateEmptyDirectoriesDefault findCarthageFrameworks = jsonDictionary.json(atKeyPath: "findCarthageFrameworks") ?? SpecOptions.findCarthageFrameworksDefault localPackagesGroup = jsonDictionary.json(atKeyPath: "localPackagesGroup") + preGenCommand = jsonDictionary.json(atKeyPath: "preGenCommand") + postGenCommand = jsonDictionary.json(atKeyPath: "postGenCommand") } } @@ -154,6 +162,8 @@ extension SpecOptions: JSONEncodable { "tabWidth": tabWidth.flatMap { Int($0) }, "defaultConfig": defaultConfig, "localPackagesGroup": localPackagesGroup, + "preGenCommand": preGenCommand, + "postGenCommand": postGenCommand, ] if settingPresets != SpecOptions.settingPresetsDefault { diff --git a/Sources/XcodeGenCLI/Commands/GenerateCommand.swift b/Sources/XcodeGenCLI/Commands/GenerateCommand.swift index 8f5c1dfd..c01c7b9a 100644 --- a/Sources/XcodeGenCLI/Commands/GenerateCommand.swift +++ b/Sources/XcodeGenCLI/Commands/GenerateCommand.swift @@ -79,6 +79,11 @@ class GenerateCommand: ProjectCommand { throw GenerationError.validationError(error) } + // run pre gen command + if let command = project.options.preGenCommand { + try Task.run(bash: command, directory: projectDirectory.absolute().string) + } + // generate plists info("⚙️ Generating plists...") let fileWriter = FileWriter(project: project) @@ -119,6 +124,11 @@ class GenerateCommand: ProjectCommand { info("Failed to write cache: \(error.localizedDescription)") } } + + // run post gen command + if let command = project.options.postGenCommand { + try Task.run(bash: command, directory: projectDirectory.absolute().string) + } } func info(_ string: String) { diff --git a/Tests/Fixtures/TestProject/project.yml b/Tests/Fixtures/TestProject/project.yml index 028060e4..8ec7d286 100644 --- a/Tests/Fixtures/TestProject/project.yml +++ b/Tests/Fixtures/TestProject/project.yml @@ -9,6 +9,8 @@ options: deploymentTarget: watchOS: 4.0 groupSortPosition: top + preGenCommand: echo "This is a pre-gen command" + postGenCommand: scripts/script.sh fileGroups: - Configs - FileGroup diff --git a/Tests/Fixtures/TestProject/scripts/script.sh b/Tests/Fixtures/TestProject/scripts/script.sh old mode 100644 new mode 100755 diff --git a/Tests/ProjectSpecTests/SpecLoadingTests.swift b/Tests/ProjectSpecTests/SpecLoadingTests.swift index 2460beeb..57ff59bf 100644 --- a/Tests/ProjectSpecTests/SpecLoadingTests.swift +++ b/Tests/ProjectSpecTests/SpecLoadingTests.swift @@ -1070,7 +1070,9 @@ class SpecLoadingTests: XCTestCase { watchOS: "3.0", macOS: "10.12.1" ), - findCarthageFrameworks: true + findCarthageFrameworks: true, + preGenCommand: "swiftgen", + postGenCommand: "pod install" ) let expected = Project(name: "test", options: options) let dictionary: [String: Any] = ["options": [ @@ -1081,6 +1083,8 @@ class SpecLoadingTests: XCTestCase { "developmentLanguage": "ja", "deploymentTarget": ["iOS": 11.1, "tvOS": 10.0, "watchOS": "3", "macOS": "10.12.1"], "findCarthageFrameworks": true, + "preGenCommand": "swiftgen", + "postGenCommand": "pod install", ]] let parsedSpec = try getProjectSpec(dictionary) try expect(parsedSpec) == expected