Skip to content

Commit

Permalink
Merge branch 'master' into erneestoc/test-macro-expansion-override
Browse files Browse the repository at this point in the history
  • Loading branch information
erneestoc authored Jul 3, 2024
2 parents 32d3566 + f884222 commit 72aa193
Show file tree
Hide file tree
Showing 27 changed files with 394 additions and 261 deletions.
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,39 @@

## Next Version

- Removed `xcodegen dump --type graphviz` feature. @giginet

## 2.41.0

### Added

- Added `xcodegen cache` command that writes the cache. Useful for `post-commit` git hook integration #1476 @yonaskolb

### Changed

- Include folders in file sorting #1466 @jflan-dd

### Fixed

- Fixed `supportedDestinations` validation when it contains watchOS for multiplatform apps. #1470 @tatsuky

## 2.40.1

### Fixed

- Reverted `.xcprivacy` handling. They will now again be treated as resources by default @yonaskolb

## 2.40.0

### Added

- Added support for local Swift packages at the project root by specifying a "" group #1413 @hiltonc
- Added a custom `shell` to a scheme's pre and post actions #1430 @balazs-vimn

### Changed

- `.xcprivacy` files are now not added to any build phases by default #1464 @yonaskolb

## 2.39.1

### Added
Expand Down
1 change: 0 additions & 1 deletion Docs/Examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

These are a bunch of real world examples of XcodeGen project specs. Feel free to add your own via PR.

- [num42/RxUserDefaults](https://github.com/num42/RxUserDefaults/blob/master/Examples/CocoaPodsExample.yml)
- [toshi0383/Bitrise-iOS](https://github.com/toshi0383/Bitrise-iOS/blob/master/project.yml)
- [johndpope/swift-models](https://github.com/johndpope/swift-models/tree/stable/Inference)
- [atelier-socle/AppRepositoryTemplate](https://github.com/atelier-socle/AppRepositoryTemplate/blob/master/project.yml)
Expand Down
12 changes: 8 additions & 4 deletions Docs/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ Absolutely. You will get the most out of XcodeGen by adding your project to your
>Note that you can run `xcodegen` as a step in your build process on CI.
## What happens when I switch branches
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.
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.

It's recommended to set up some [git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) to automate the process:
- run `xcodegen generate --use-cache` on the following hooks. This will make sure the project is up to date when checking out, merging and rebasing
- `post-checkout`
- `post-rewrite`
- `post-merge`
- run `xcodegen cache` on `pre-commit`. This will make sure that when switching branches the cache will be updated in case you made local changes, or are ammending a commit that added a new file.

## Can I use CocoaPods
Yes, you will just need to run `pod install` after the project is generated to integrate Cocoapods changes.
Expand Down
15 changes: 10 additions & 5 deletions Docs/ProjectSpec.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ Note that target names can also be changed by adding a `name` property to a targ
- [ ] **transitivelyLinkDependencies**: **Bool** - If this is `true` then targets will link to the dependencies of their target dependencies. If a target should embed its dependencies, such as application and test bundles, it will embed these transitive dependencies as well. Some complex setups might want to set this to `false` and explicitly specify dependencies at every level. Targets can override this with [Target](#target).transitivelyLinkDependencies. Defaults to `false`.
- [ ] **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 individual frameworks for Carthage framework dependencies will automatically be found. This property can be overridden 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`
- [ ] **localPackagesGroup**: **String** - The group name that local packages are put into. This defaults to `Packages`. Use `""` to specify the project root.
- [ ] **fileTypes**: **[String: [FileType](#filetype)]** - A list of default file options for specific file extensions across the project. Values in [Sources](#sources) will overwrite these settings.
- [ ] **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.
Expand Down Expand Up @@ -483,6 +483,7 @@ This will provide a mix of default build settings for the chosen platform destin
- `macOS`
- `macCatalyst`
- `visionOS`
- `watchOS`

```yaml
targets:
Expand All @@ -499,7 +500,7 @@ targets:
destinationFilters: [iOS]
```

Note that the definition of supported destinations can be applied to every type of bundle making everything more easy to manage (app targets, unit tests, UI tests etc).
Note that the definition of supported destinations can be applied to almost every type of bundle making everything more easy to manage (app targets, unit tests, UI tests etc). App targets currently do not support the watchOS destination. Create a separate target using `platform` for watchOS apps. See Apple's [Configuring a multiplatform app](https://developer.apple.com/documentation/xcode/configuring-a-multiplatform-app-target) for details.

### Sources

Expand Down Expand Up @@ -1140,12 +1141,16 @@ schemes:
MyTarget2: [run, archive]
run:
config: prod-debug
commandLineArguments: "--option value"
commandLineArguments:
"-MyEnabledArg": true
"-MyDisabledArg": false
environmentVariables:
RUN_ENV_VAR: VALUE
test:
config: prod-debug
commandLineArguments: "--option testValue"
commandLineArguments:
"-MyEnabledArg": true
"-MyDisabledArg": false
gatherCoverageData: true
coverageTargets:
- MyTarget1
Expand Down Expand Up @@ -1240,7 +1245,7 @@ Swift packages are defined at a project level, and then linked to individual tar
### Local Package

- [x] **path**: **String** - the path to the package in local. The path must be directory with a `Package.swift`.
- [ ] **group** : **String**- Optional path that specifies the location where the package will live in your xcode project.
- [ ] **group** : **String**- Optional path that specifies the location where the package will live in your xcode project. Use `""` to specify the project root.

```yml
packages:
Expand Down
8 changes: 1 addition & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
TOOL_NAME = XcodeGen
export EXECUTABLE_NAME = xcodegen
VERSION = 2.39.1
VERSION = 2.41.0

PREFIX = /usr/local
INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME)
SHARE_PATH = $(PREFIX)/share/$(EXECUTABLE_NAME)
CURRENT_PATH = $(PWD)
REPO = https://github.com/yonaskolb/$(TOOL_NAME)
RELEASE_TAR = $(REPO)/archive/$(VERSION).tar.gz
SHA = $(shell curl -L -s $(RELEASE_TAR) | shasum -a 256 | sed 's/ .*//')
SWIFT_BUILD_FLAGS = --disable-sandbox -c release --arch arm64 --arch x86_64
BUILD_PATH = $(shell swift build $(SWIFT_BUILD_FLAGS) --show-bin-path)
EXECUTABLE_PATH = $(BUILD_PATH)/$(EXECUTABLE_NAME)
Expand Down Expand Up @@ -42,10 +40,6 @@ release:
publish: archive brew
echo "published $(VERSION)"

brew:
brew update
brew bump-formula-pr --url=$(RELEASE_TAR) XcodeGen

archive: build
./scripts/archive.sh "$(EXECUTABLE_PATH)"
swift package plugin --allow-writing-to-package-directory generate-artifact-bundle \
Expand Down
9 changes: 0 additions & 9 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@
"version" : "0.0.6"
}
},
{
"identity" : "graphviz",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SwiftDocOrg/GraphViz.git",
"state" : {
"revision" : "70bebcf4597b9ce33e19816d6bbd4ba9b7bdf038",
"version" : "0.2.0"
}
},
{
"identity" : "jsonutilities",
"kind" : "remoteSourceControl",
Expand Down
2 changes: 0 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ let package = Package(
.package(url: "https://github.com/tuist/XcodeProj.git", exact: "8.13.0"),
.package(url: "https://github.com/jakeheis/SwiftCLI.git", from: "6.0.3"),
.package(url: "https://github.com/mxcl/Version", from: "2.0.0"),
.package(url: "https://github.com/SwiftDocOrg/GraphViz.git", exact: "0.2.0"),
.package(url: "https://github.com/freddi-kit/ArtifactBundleGen", exact: "0.0.6")
],
targets: [
Expand All @@ -41,7 +40,6 @@ let package = Package(
"XcodeProj",
"PathKit",
"XcodeGenCore",
"GraphViz",
], resources: [
.copy("SettingPresets")
]),
Expand Down
26 changes: 2 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ The project spec is a YAML or JSON file that defines your targets, configuration
- ✅ Distribute your spec amongst multiple files for easy **sharing** and overriding
- ✅ Easily create **multi-platform** frameworks
- ✅ Integrate **Carthage** frameworks without any work
- ✅ Export **Dependency Diagrams** to view in [Graphviz](https://www.graphviz.org)

Given an example project spec:

Expand Down Expand Up @@ -113,7 +112,7 @@ swift run xcodegen
Add the following to your Package.swift file's dependencies:

```swift
.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.39.1"),
.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.41.0"),
```

And then import wherever needed: `import XcodeGenKit`
Expand All @@ -136,28 +135,7 @@ Options:
- **--use-cache**: Used to prevent unnecessarily generating the project. If this is set, then a cache file will be written to when a project is generated. If `xcodegen` is later run but the spec and all the files it contains are the same, the project won't be generated.
- **--cache-path**: A custom path to use for your cache file. This defaults to `~/.xcodegen/cache/{PROJECT_SPEC_PATH_HASH}`

There are other commands as well such as `xcodegen dump` which lets out output the resolved spec in many different formats, or write it to a file. Use `xcodegen help` to see more detailed usage information.

## Dependency Diagrams
<details>
<summary>Click to expand!</summary>

#### How to export dependency diagrams:

To stdout:

```
xcodegen dump --type graphviz
```

To a file:

```
xcodegen dump --type graphviz --file Graph.viz
```

During implementation, `graphviz` formatting was validated using [GraphvizOnline](https://dreampuf.github.io/GraphvizOnline/), [WebGraphviz](http://www.webgraphviz.com), and [Graphviz on MacOS](https://graphviz.org).
</details>
There are other commands as well such as `xcodegen dump` which lets one output the resolved spec in many different formats, or write it to a file. Use `xcodegen help` to see more detailed usage information.

## Editing
```shell
Expand Down
1 change: 0 additions & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@
1. Push commit and tag to github
1. Create release from tag on GitHub using the version number and relevant changelog contents
1. Run `make archive` and upload `xcodegen.zip` and `xcodegen.artifactbundle.zip` to the github release
1. Run `make brew` which will open a PR on homebrew core
6 changes: 5 additions & 1 deletion Sources/ProjectSpec/Scheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,12 @@ public struct Scheme: Equatable {
public var script: String
public var name: String
public var settingsTarget: String?
public init(name: String, script: String, settingsTarget: String? = nil) {
public var shell: String?
public init(name: String, script: String, shell: String? = nil, settingsTarget: String? = nil) {
self.script = script
self.name = name
self.settingsTarget = settingsTarget
self.shell = shell
}
}

Expand Down Expand Up @@ -403,6 +405,7 @@ extension Scheme.ExecutionAction: JSONObjectConvertible {
script = try jsonDictionary.json(atKeyPath: "script")
name = jsonDictionary.json(atKeyPath: "name") ?? "Run Script"
settingsTarget = jsonDictionary.json(atKeyPath: "settingsTarget")
shell = jsonDictionary.json(atKeyPath: "shell")
}
}

Expand All @@ -412,6 +415,7 @@ extension Scheme.ExecutionAction: JSONEncodable {
"script": script,
"name": name,
"settingsTarget": settingsTarget,
"shell": shell
]
}
}
Expand Down
6 changes: 6 additions & 0 deletions Sources/ProjectSpec/SpecValidation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ extension Project {
errors.append(.unexpectedTargetPlatformForSupportedDestinations(target: target.name, platform: target.platform))
}

if let supportedDestinations = target.supportedDestinations,
target.type.isApp,
supportedDestinations.contains(.watchOS) {
errors.append(.containsWatchOSDestinationForMultiplatformApp(target: target.name))
}

if target.supportedDestinations?.contains(.macOS) == true,
target.supportedDestinations?.contains(.macCatalyst) == true {

Expand Down
3 changes: 3 additions & 0 deletions Sources/ProjectSpec/SpecValidationError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public struct SpecValidationError: Error, CustomStringConvertible {
case invalidTargetSchemeTest(target: String, testTarget: String)
case invalidTargetPlatformForSupportedDestinations(target: String)
case unexpectedTargetPlatformForSupportedDestinations(target: String, platform: Platform)
case containsWatchOSDestinationForMultiplatformApp(target: String)
case multipleMacPlatformsInSupportedDestinations(target: String)
case missingTargetPlatformInSupportedDestinations(target: String, platform: Platform)
case invalidSchemeTarget(scheme: String, target: String, action: String)
Expand Down Expand Up @@ -66,6 +67,8 @@ public struct SpecValidationError: Error, CustomStringConvertible {
return "Target \(target.quoted) has multiple definitions of mac platforms in supported destinations"
case let .missingTargetPlatformInSupportedDestinations(target, platform):
return "Target \(target.quoted) has platform \(platform.rawValue.quoted) that is missing in supported destinations"
case let .containsWatchOSDestinationForMultiplatformApp(target):
return "Multiplatform app \(target.quoted) cannot contain watchOS in \"supportedDestinations\". Create a separate target using \"platform\" for watchOS apps"
case let .invalidConfigFile(configFile, config):
return "Invalid config file \(configFile.quoted) for config \(config.quoted)"
case let .invalidSchemeTarget(scheme, target, action):
Expand Down
2 changes: 1 addition & 1 deletion Sources/XcodeGen/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import ProjectSpec
import XcodeGenCLI
import Version

let version = Version("2.39.1")
let version = Version("2.41.0")
let cli = XcodeGenCLI(version: version)
cli.execute()
44 changes: 44 additions & 0 deletions Sources/XcodeGenCLI/Commands/CacheCommand.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Foundation
import PathKit
import ProjectSpec
import SwiftCLI
import XcodeGenKit
import XcodeProj
import Version

class CacheCommand: ProjectCommand {

@Key("--cache-path", description: "Where the cache file will be loaded from and save to. Defaults to ~/.xcodegen/cache/{SPEC_PATH_HASH}")
var cacheFilePath: Path?

init(version: Version) {
super.init(version: version,
name: "cache",
shortDescription: "Write the project cache")
}

override func execute(specLoader: SpecLoader, projectSpecPath: Path, project: Project) throws {

let cacheFilePath = self.cacheFilePath ?? Path("~/.xcodegen/cache/\(projectSpecPath.absolute().string.md5)").absolute()

var cacheFile: CacheFile?

// generate cache
do {
cacheFile = try specLoader.generateCacheFile()
} catch {
throw GenerationError.projectSpecParsingError(error)
}

// write cache
if let cacheFile = cacheFile {
do {
try cacheFilePath.parent().mkpath()
try cacheFilePath.write(cacheFile.string)
success("Wrote cache to \(cacheFilePath)")
} catch {
info("Failed to write cache: \(error.localizedDescription)")
}
}
}
}
5 changes: 1 addition & 4 deletions Sources/XcodeGenCLI/Commands/DumpCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,13 @@ class DumpCommand: ProjectCommand {
output = try Yams.dump(object: project.toJSONDictionary())
case .summary:
output = project.debugDescription
case .graphviz:
output = GraphVizGenerator().generateModuleGraphViz(targets: project.targets)
}

if let file = file {
try file.parent().mkpath()
try file.write(output)
} else {
stdout.print(output)
success(output)
}
}
}
Expand All @@ -61,7 +59,6 @@ private enum DumpType: String, ConvertibleFromString, CaseIterable {
case parsedJSON = "parsed-json"
case parsedYaml = "parsed-yaml"
case summary
case graphviz

static var defaultValue: DumpType { .yaml }
}
Loading

0 comments on commit 72aa193

Please sign in to comment.