Part of https://github.com/tuist/tuist/issues/425
- Renaming the generated manifest target to include an `_` separator instead `-` which produces an invalid product name.
- This was causing Xcode to automatically re-name it when opening the project
Test Plan:
- Generate `fixtures/ios_app_with_tests` via `tuist generate`
- Run `git add . -f` to stage the generated project
- Open the project in Xcode
- Verify the manifest target `App_manifest` doesn't get renamed by Xcode within the Scheme and project
- Verify the manifest target can still build successfully
* Implement class to generate the dotgraph as a string
* Add GraphCommand
* Register command
* Add command to export the graph
* Fix graph syntax error
* Don't generate manifest targets when printing the graph
* Add tests
* Update CHANGELOG
* Add documentation
* Add the graph.dot file to the gitignore
* Address comments
* Don't lint when generating the graph
* Add command to output the graph to the standard output
* Make Graph and nodes conform Encodable
* Print the graph as a json
* Some fixes after rebasing
* Pass file and line arguments
* Keep models and attributes as internal
* Extract the node classes into their own files
* Add DotGraph* elements
* Extract FrameworkNode from GraphNode
* Add tests
* Address comments
Resolves https://github.com/tuist/tuist/issues/417
- Updating SDK dependency paths to be based on the developer directory and the platform SDK root path
Test Plan:
- generate the fixture `fixtures/ios_app_with_sdk` via `tuist generate`
- Verify the linked system frameworks and libraries have the correct path set based on the platform
Resolves https://github.com/tuist/tuist/issues/174
Continuation of https://github.com/tuist/tuist/pull/272 by @steprescott
### Short description
In some cases specifying the status of the frameworks or libraries to link against is needed (e.g. weakly linking frameworks).
### Solution
- A new `.sdk` dependency type is being introduced
usage:
```swift
Target(name: "App",
platform: .iOS,
product: .app,
bundleId: "io.tuist.App",
infoPlist: "Info.plist",
sources: "Sources/**",
dependencies: [
.sdk(name: "CloudKit.framework", status: .required),
.sdk(name: "StoreKit.framework", status: .optional),
.sdk(name: "libc++.tbd"),
])
```
### Test Plan
- Verify unit tests pass via `swift test`
- Verify acceptance tests pass via `bundle rake exec features`
- Manually generate `fixtures/ios_app_with_sdk` via `tuist generate`
- Verify the appropriate libraries are included in the generated project
### Notes
Credit goes to @steprescott and [`XcodeGen`](https://github.com/yonaskolb/XcodeGen) - this PR is based on their work!
Resolves https://github.com/tuist/tuist/issues/414
`BuildPhaseGenerator` will not generate empty `settings` attribute for source `PBXBuildFile` elements when compiler flags are not specified.
Test Plan:
- Close Xcode
- Generate `fixtures/ios_app_with_frameworks` fixture
- Open generated .xcodeproj in a non-Xcode editor (i.e vim), ensure empty `settings ={}` attributes have not been generated
- Adding Xcode10 constants to maintain backwards compatibiltiy (Xcode 11 is still in beta!)
Test Plan:
- Verify unit tests pass via `swift test`
- Verify acceptance tests pass via `bundle exec rake features`
Resolves https://github.com/tuist/tuist/issues/409
### Short description
Calling `tuist generate` on the same project multiple times can yield a different `.xcodeproj` file each time.
### Solution
Sort elements ahead of adding them to their corresponding xcodeproj container.
### Implementation
- Update generator integration tests to shuffle sources / headers
- Sort files added within `BuildPhaseGenerator`
- Update generator integration tests to shuffle additional files
- Update `ProjectFilesSortener` to be stable
- Update `LinkGenerator` to sort dependencies
### Test Plan
- Ensure unit tests pass via `swift test`
- Ensure acceptance tests pass via `bundle exec rake features`
Generate the fixture `fixtures/ios_app_with_tests/` and verify the generated project is identical each time
```
$ cd fixtures/ios_app_with_tests/
$ touch Sources/Source{A..Z}.swift
$ for i in {1..5}; do tuist generate > /dev/null && md5 App.xcodeproj/project.pbxproj; done
```
# Short description
The `FileManager` `url(for:in:appropriateFor:create:)` method, when configured to create a temporary directory, fails after 1000 calls with: Error Domain=NSCocoaErrorDomain Code=512 "The file couldn’t be saved."
http://openradar.appspot.com/50553219
# Solution
We need to ensure the temporary directory is removed after `FileHandler.replace` method finished.
- Removing empty test file (seems to upset SwiftFormat)
- Doing a sweep of swiftformat fixes
- Bumping circleci image to Xcode 10.2.1
Test Plan:
- Verify tuist builds via `swift build`
- Verify tests pass via `swift tests`
- Verify swiftformat runs without issues
- Verify swiftformat runs on CI
Resolves https://github.com/tuist/tuist/issues/387
- We now pass the `-q` (quiet) option to `unzip` to suppress the verbose output
Test Plan:
- build this version locally
- run `swift run tuistenv update`
- Verify the logs don't display the unzipped files
Resolves https://github.com/tuist/tuist/issues/390
### Short description
The `DefaultSettingsProvider` `targetSettings` combines the build settings for the specified build variant with the build settings for variants. If there is a common build setting with `$(inherited)` in its value, the value is appended twice.
### Solution
In the `SettingsHelper` before combining build settings by appending the new value to the existing one check if the value are equal
### Implementation
- Change `SettingsHelper` to check if setting values are equal before appending
- Add unit test to cover this case
### Test Plan
- Verify unit tests pass via swift tests
Resolves https://github.com/tuist/tuist/issues/350
- Added a new protocol `DefaultSettingsProviding` that allows to control default settings at project and target level with a default implementation. `.recommended` set of settings is exactly the same as what Tuist currently generates so this it's not a breaking change.
- Moved some of the settings helpers to a separated class `SettingsHelper`.
- Extended `Settings` manifest so the users can control the default set of settings.
- Including a resource bundle as one of the elements in the "Copy Bundle Resources" build phase doesn't get it built!
- When within the same project, the solution is to add the resource bundle target as an explicit target dependency
- This is not possible when the dependency is between two different projects
- To workaround this issue, a similar technique currently employed by static products can be used
- The resource bundle is now included in a copy files phase - which get Xcode to build it!
- The logic used for static products has been generalized slightly to allow accommodating the resource bundle targets
Test Plan:
- Run the unit tests via `swift test`
Note: this is not yet exposed via the project description manifests
- Use multiline strings to allow to use json without escaping characters (`\"`)
- Add `file` and `line` parameters to `assertCodableEqualToJson` to improve error reporting
* Define Info.plist in the ProjectDescription target
* Update infoPlist attribute type
* Update models to use the new type, InfoPlist
* Update changelog
Resolves https://github.com/tuist/tuist/issues/349
- Update `func embeddableFrameworks(path: AbsolutePath, name: String, system: Systeming)` of `Graph` to return ordered references
- Update method generating products file references so it can generate sorted list of products of the project targets and the dependencies
- Add integration test to make sure the project does not change after regeneration
Test Plan:
- Run unit tests via `swift test`
- Run acceptance tests via `bundle exec rake features`
- Manually generate `fixtures/ios_app_with_frameworks` via `tuist generate` at least two times without making any changes to the project
- Verify the generated workspace and projects are stable (do not change after regeneration)
### Short description
Custom debug settings were populated with release default settings (provided by XcodeProj). The issue was introduced while implementing custom configurations (https://github.com/tuist/tuist/pull/320). It does not affect Tuist users as we still support only `.debug` and `.release` configurations.
### Solution
- Fixed incorrect code converting build configuration into XcodeProj variant in `ConfigGenerator`
- Added unit and integration tests
Resolves https://github.com/tuist/tuist/issues/337
- The graph linter didn't account for which targets could link static products
- This led to raising an incorrect lint warning
- A `canLinkStaticProducts` method has been added to share rules between the linter and graph during link generation
- `GraphLinter` has been updated to no longer keep state internally
Test Plan:
- Run unit tests via `swift lint`
- Run acceptance tests via `bundle exec rake features`
- Manually generate `fixtures/ios_app_with_static_frameworks` via `tuist generate`
- Verify no lint warnings are displayed
Resolves https://github.com/tuist/tuist/issues/361
### Short description
Localized resources can up getting duplicated within the resources build phase and the project files elements.
The reason this was occurring:
- Give a path to a resource e.g. `/resources/en.lproj/foo.png`
- `/resources/en.lproj/` is used detected
- All files within `/resources/en.lproj/` are enumerated and added
- When another path to a resource is encountered e.g. `/resources/en.lproj/bar.png`
- The same process is repeated, resulting in duplicate file elements!
### Solution
- Update project files element logic to better accommodate multiple localized files
- Add a cache to keep track of which build files were added the resources build phase to prevent adding duplicates.
- Improved file element missing file warnings for directories
e.g. `resources: ["Resources/en.lproj"]` would yield the following warnings:
```
Warning: 'Resources/en.lproj' is a directory, try using: 'Resources/en.lproj/**' to list its files
```
### Test Plan
- Verify unit tests pass via `swift tests`
- Verify acceptance tests pass via `bundle rake exec features`
- Manually generate `fixtures/ios_app_with_framework_and_resources` via `tuist generate`
- Verify the generated project includes the localized string files without any duplicates
Resolves https://github.com/tuist/tuist/issues/352
- Specifying a permissive glob pattern (e.g. `Headers/**`) for headers would incorrectly include all files and folders as headers
- Limiting the paths to header files resolves this issue
- Adding Objective-C classes to test out headers within the fixtures
Test Plan:
- Verify unit tests pass via `swift build`
- Verify acceptance tests pass via `bundle exec rake features`
- Manually generate `fixtures/ios_app_with_frameworks` via `tuist generate`
- Verify `Framework2` has the appropriate public, private & project headers set
Part of: https://github.com/tuist/tuist/issues/290
- Previously only bundle target dependencies within the same projects worked
- This was due to leveraging `targetDependencies` method on `Graph` which only returns the target dependencies with the same project
- Updating `Graph` to include a new method to return all bundle resource dependencies
Test Plan:
- Run unit tests via `swift test` and verify they pass
Note: bundle resources are not yet exposed to the manifests
Resolves https://github.com/tuist/tuist/issues/345
- Using the `**/*` style patterns are "eager" they will list out files recursively including ones within `.xcassets`
- The order in which the `ProjectFileElements` elements are processes isn't guaranteed
- If a file within the `.xcassets` is encountered first, e.g. `App/Resources/Assets.xcassets/assetCatalogLogo.imageset/tuist.png` before `App/Resources/Assets.xcassets`, `App/Resources/Assets.xcassets` is mistaken for a group and isn't added as a file element
- To mitigate this, the logic that determines if a group or file is added checks for `.xcassets` files
Test Plan:
- Verify unit tests pass
- Verify acceptance tests pass
- Run `tuist generate` within `fixtures/ios_app_with_framework_and_resources`
- Verify the generation passes
- Verify the asset catalog is included in the generated `MainApp` within the workspace
Resolves https://github.com/tuist/tuist/issues/329
### Short description 📝
To keep an eye on how long the generation process takes as users add more dependencies to their projects and as Tuist developers add more features to Tuist itself, it would be useful to print out the total generation time.
### Solution
Print out the total time taken to generate a project within the generate command.
### Implementation
- Introduce `Clock` and `ClockTimers` to allow obtaining current date and time differences
- Time the generate process within the generate command
### Test Plan
- Verify unit tests and acceptance tests pass
- Run `tuist generate` within any of the fixtures in `fixtures`
- Verify the generation time is displayed in the console output
Resolves https://github.com/tuist/tuist/issues/330 and https://github.com/tuist/tuist/issues/322
### Short description:
- This issue can occur when files like `README` without extensions exist within the project
- Additionally another issue can be encountered in the event folders contain a `.` in their name
- To solve this we now only create groups if the file element component being added is a leaf (i.e. `/path/to/a` when `path` and `to` are added, they will be added as groups, and `a` will be added as a file element)
## Test Plan:
- Verify unit tests pass `swift test`
- Verify acceptance tests pass `bundle rake features`
- Manually generate `fixtures/ios_app_with_framework_and_resources` via `tuist generate`
- Verify `resource_without_extension` and `resource.txt` are included as resources within the project
- Manually generate `fixtures/ios_app_with_custom_workspace` via `tuist generate`
- Verify the `CHANGELOG` file appears as a file and not a group
* Headers build phase should be put on top of Compile build phase
* Add test
* Add changelog
* Set Code Sign On Copy to true for Embbed Frameworks
* Add changelog
* Update CHANGELOG
Resolves https://github.com/tuist/tuist/issues/324
- Using `replaceItemAt` has a caveat where it requires the item and its replacement to be on the same volume (see https://developer.apple.com/documentation/foundation/filemanager/2293212-replaceitemat)
- To mitigate this, the documentation suggests creating a temporary file within that volume
- The item can be moved there first
- Then a `replaceItemAt` can be performed
Test Plan:
- Manually create a RAM disk e.g. `diskutil erasevolume HFS+ “RAMDisk” `hdiutil attach -nomount ram://524288`` (this creates a 250MB RAM disk)
- Create a new folder within that disk
- run `tuist --init`
- run `tuist generate`
- Verify the generation succeeds
Part of https://github.com/tuist/tuist/issues/160
### Short description
As mentioned in https://github.com/tuist/tuist/issues/160, currently, Tuist only supports debug and release build configurations. This can be seen as a limitation for some projects. We'd like to avoid this limitation and allow users to control the configurations themselves and base them on xcconfig files if needed.
### Solution
Added `Settings` property to `Project` and `Target` generator models. `Settings` contains `base` property for settings that are common for all the configurations. `configurations` property stores dictionary mapping `BuildConfiguration` (i.e. Release, Debug, Beta etc.) to `Configuration`. The structure won't preserve the order of the configurations but can help avoid situation when the same configuration is set twice (which would require additional linting). Maintaining the original order would be particularly difficult in cases when the defined configurations orders are different in project and target settings. To keep the ordering stable, the generator sorts the configurations alphabetically.
To make the implementation backward compatible, `GeneratorModelLoader` always passes `release` and `debug` configurations with the settings defined in the manifest.
```swift
return TuistGenerator.Settings(base: base, configurations: [.debug: debug, .release: release]
```
Part of: https://github.com/tuist/tuist/issues/290
### Short description
Static frameworks & libraries currently can't host resources, one common technique to work around this is by introducing resource bundle targets to host the resources instead.
### Solution
To aid solving this wholistically, an incremental step is to introduce the bundle product type to `TuistGenerator` (generator library).
### Implementation
- Add bundle product type
- Add lint rules
### Notes
- The `.bundle` product type is not yet exposed in the manifests - this may be done separately once more foundations are in place to support resources holistically (See #290)