Part of: https://github.com/tuist/tuist/issues/820
- Creating a small command line tool to generate large fixtures
- Add github action to build & test the fixture generator whenever its sources or ProjectDescription's sources change
Usage:
```sh
swift run FixtureGenerator --projects 10 --targets 10 --sources 100
```
Test Plan:
- Run `swift run` within `fixtures/fixture_generator`
- Run `tuist generate` within fixtures/fixture_generator/Fixture`
- Verify the generated fixure is valid
- Experiment with different number of sources / targets / projects to benchmark Tuist
- Project headers in Xcode have no attributes by default
- As it happens, setting any arbitrary value defaults to "Project" visibility
- To make generated project more inline with Xcode, we can omitt setting attributes for project headers
Test Plan:
- Run `tuist generate` within `fixtures/ios_app_with_frameworks/Framework2`
- Verify the generated project has `MyProjectClass.h` set to "Project" visibility in the generated project
### Short description
We've noticed the scheme generation is not always stable. The order of testable targets in a scheme could change after re-generating the project.
It's reproducible when multiple testable targets depend on the same target (framework, or app) within a single project.
i.e.
- ProjectA:
- AppTarget
- UnitTestsTarget (dependencies: [AppTarget])
- UITestsTarget (dependencies: [AppTarget])
### Solution
- Sorted testable targets
- Updated one of the unit tests to reproduce the issues, and avoid regression in the future
- Updated the integration tests to cover multiple testable targets user case
Resolves: https://github.com/tuist/tuist/issues/887
- Test targets declare their host applications as a dependency
- This lead to a few graph queries transitively including depdencies of the application in the test targets
- When performing dependency searches, we can skip dependency tree of nodes that can embed products (e.g. Applications)
Test Plan:
- Run `tuist generate` within `fixtures/ios_app_with_transitive_framework`
- Open the generated workspace
- Verify that `AppUITests` has no precompiled frameworks included
### Short description 📝
While working on https://github.com/bloomberg/xcdiff/pull/40, we discovered that some of the build files are missing `RemoveHeadersOnCopy` attribute. The attribute determines if the headers should be striped from the archive, and if not set, can lead to headers leakage. The attribute is not visible in the Xcode UI, but added automatically every time a certain bundle types are added to a copy files build phase (i.e. .framework, .appex).
Oddly the attribute is not added for `.xcframework`, but it's probably an Xcode issue (FB7533618).
### Solution 📦
Added "RemoveHeadersOnCopy" attribute for build files in embed precompiled frameworks, embed watch content, and embed app extensions build phases.
### Implementation 👩💻👨💻
- [x] Update TuistGenerator to add `RemoveHeadersOnCopy`
- [x] Update acceptance tests
- [x] Update CHANGELOG
Resolves https://github.com/tuist/tuist/issues/569
### Short description 📝
It should be possible to run tests if target has any test targets.
### Solution 📦
This PR finds all related test targets to the test scheme. It was already done for test targets themselves, but the functionality was extended to include all other targets.
### Implementation 👩💻👨💻
- [x] Added implementation
- [x] Added tests
### Test Plan 🛠
Run with `app_with_framework_and_tests` fixture and check that in generated schemes:
#### Previous behaviour didn't break
1. `AppTests` scheme has `AppTests` as a testable target.
1. `FrameworkTests` scheme has `FrameworkTests` as a testable target.
#### New behaviour works as expected
1. `App` scheme has `AppTests` as a testable target.
1. `Framework` scheme has `FrameworkTests` as a testable target.
- Generated projects were missing an exhaustive list of known regions.
- This causes Xcode to immediately modify generated projects on launch to fix this.
- Based on localizable resources we can infer the knownRegions of the project
- While adding localizable resource file elements we can keep track of the languages encountered
- This can then be used to set a complete set of knownRegions
Test Plan:
- Run `tuist generate` within `fixtures/ios_app_with_framework_and_resources`
- Verify the generated project MainApp has both "English" and "French" in the list of localizations in the project's info tab
Part of: https://github.com/tuist/tuist/issues/628
- Added watchOS App / Extension defaults to the info plist content provider
- Watch apps reference their host applications bundle identifier in the info plist `WKCompanionAppBundleIdentifier` key
- Watch app extensions reference their host watch apps bundle identifier in the info plist `NSExtension.NSExtensionAttributes.WKAppBundleIdentifier`
- As such the parent project is now used to perform lookups for those hosts to extract their bundle identifiers
- Updated fixture to leverage generated info.plist files
Test Plan:
- run `tuist generate` within `fixtures/ios_app_with_watchapp2`
- Verify the info.plist files generated in `Derrived/InfoPlists` matche the ones created by Xcode
(They were previously checked in under `Support`)
- In the even two library dependencies shared the same `publicHeaders` path (e.g. `libcrypto.a` and `libssl.a` in OpenSSL) duplicate entries were added to the `HEADER_SEARCH_PATHS` build setting
- This was regressed due to an earlier change https://github.com/tuist/tuist/pull/751
- previously the uniquing was happening in the settings helper when build settings were extended multiple times
- To resolve this, we now ensure we unique paths being added
- Additionally a test is included to ensure this doesn't regress in the future
Test Plan:
- Verify the unit tests pass
A bit of a contrived manual test case
update the fixture in `fixtures/ios_app_with_static_libraries/Modules/A/Project.swift`
```swift
let project = Project(name: "A",
targets: [
Target(name: "A",
platform: .iOS,
product: .staticLibrary,
bundleId: "io.tuist.A",
infoPlist: "Info.plist",
sources: "Sources/**",
dependencies: [
.project(target: "B", path: "../B"),
.library(path: "../C/prebuilt/C/libC.a",
publicHeaders: "../C/prebuilt/C",
swiftModuleMap: "../C/prebuilt/C/C.swiftmodule"),
// Add a duplicate
.library(path: "../C/prebuilt/C/libC.a",
publicHeaders: "../C/prebuilt/C",
swiftModuleMap: "../C/prebuilt/C/C.swiftmodule")
])
])
```
This of course causes a duplicate binary (hence why it wasn't included) but can help illustrate a situation where two `.library` dependencies point to the same `publicHeaders` path.
Resolves https://github.com/tuist/tuist/issues/667
### Short description 📝
A follow up to https://github.com/tuist/tuist/pull/730 where workspace schemes are exposed in the `ProjectDescription`. This is the final step of the steps included in the issue.
### Solution 📦
Expose `TargetReference` for both project and workspace schemes. Users can use `.project(path: "sometime/somepath", name: "targetname")` to reference targets within custom workspace schemes.
Due to how the generation process works (especially how `generatedProjects` are populated in the `ProjectGenerator`), `.project(path: .., name: ..)` we cannot reference remote targets in project schemes yet without some changes in the `ProjectGenerator`. This is not a problem for workspace schemes. Since the `ProjectDescription` `Scheme` is shared by both workspaces and projects, I've added a scheme linting rule to check that targets defined in custom project schemes are within the current project i.e., not referencing remote targets in other projects.
### Implementation 👩💻👨💻
- [X] Update `ProjectDescription` to support `TargetReference`
- [X] Add Project scheme linter for the referencing remote targets invalid case
- [X] Update fixture `ios_app_with_custom_scheme` to add workspace scheme
Resolves https://github.com/tuist/tuist/issues/750
- The previous logic was setting the `$(inherited)` and the derived search paths seperately
- This caused the derrived search paths to replace any existing custom settings
- To solve this, we can set the derived search paths and the `$(inherited)` setting as one setting
- This allows the extend helper method to extend existing settings
Test Plan:
- Run `tuist generate` within `fixtures/ios_app_with_static_libraries`
- Inspect the generated workspace, Module A should have a `$(SRCROOT/CustomHeader` header search path
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`