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)
- Updating SwiftPM dependency
- `asString` has been renamed to `pathString`
- `Utility` module has been renamed to `SPMUtility`
Test Plan:
- Verify unit tests pass `swift test`
- Verify acceptance tests pass `bundle exec rake features`
Resolves https://github.com/tuist/tuist/issues/254
- When creating new Xcode projects manually from the UI, the product names do not include the extension
- Renaming existing `productName` references to `productNameWithExtension`
Test Plan:
- Ensure unit tests pass via `swift test`
- Ensure acceptance tests pass via `bundle exec rake features`
* Support Swift 5
* Fix test
* Don't check if the versions match when both local and remote versions are greater or equal than 5
* Updating fixtures for Swift 5 support
- Included a build script to allow re-creating the pre-built `Framework2` framework
- Updated build script for pre-built static library to require less manual steps
* Updates for Swift 5
- `swift package tools-version --set-current`
* Relaxed error output checks in acceptance tests
* Adding trace for acceptance test (to aid troubleshooting)
* skipping build during error message acceptance test
- Adding a step to build tuist separately ahead of calling run
- When running tuist via `swift run` we now skip the build
* Disable Swiftformat
- `GraphNode` subclasses like `TargetNode` that share a common path could mistakenly be identified as equal
- This is due to the static `==` method being called on `GraphNode` rather than the subclass
- To ensure the appropriate method is called, we can create an `isEqual` method to call, and override it in all subclasses
- Additionally we need to perform the equality check twice reversing the sides and ensuring they match - this ensures we call the appropriate subclass implementation
Test Plan:
- Verify unit tests pass
Reference: https://forums.swift.org/t/implement-equatable-protocol-in-a-class-hierarchy/13844/6
Resolves https://github.com/tuist/tuist/issues/202
### Short description
Resources to include in an application can be in the form of files as well as folder references.
### Solution
Add support for folder references within target resources. For consistency, we can use `FileElement` which has already been used in `Project` and `Workspace` to define additional files.
e.g.
```swift
import ProjectDescription
let project = Project(
name: "MainApp",
targets: [
Target(
name: "App",
platform: .iOS,
product: .app,
bundleId: "io.tuist.App",
infoPlist: "Config/App-Info.plist",
sources: "Sources/**",
resources: [
"Resources/*.png",
.folderReference(path: "Examples")
])
]
)
```
### Test Plan
- Verify unit tests pass via `swift test`
- Verify acceptance tests pass via `bundle exec rake features`
- Run `tuist generate` within `fixtures/ios_app_with_framework_and_resources`
- Inspect the generated workspace
- Verify `MainApp` has a folder reference to `Examples` which is also included in the **Copy Bundle Resources** phase
Part of https://github.com/tuist/tuist/issues/202
### Short description
Often projects may include additional files or folder references that don't need to be part of any build phase (e.g. design references, documentation etc...)
### Solution
`Workspace.swift` manifest now supports `additionalFiles`, the same concept can be added to the `Project.swift` manifest with the same rules.
- `.glob(pattern: "Documentation/**")`: glob pattern to one or more files
- `.folderReference(path: "Designs")`: single path to a directory that is added as a folder reference
Example:
```swift
let project = Project(name: "App",
targets: [
// ...
],
additionalFiles: [
"Dangerfile.swift"
"Documentation/**",
.folderReference(path: "Designs")
])
```
### Implementation
- [x] Update `Project` manifest to include `additionalFiles`
- [x] Update models to translate globs to paths
- [x] Update `ProjectFileElements` to include `additionalFiles`
- [x] Include fixture
- [x] Update documentation
- [x] Update changelog
### Test Plan
- Run `tuist generate` within `fixtures/ios_app_with_custom_workspace/App`
- Open the generated workspace
- Verify `Dangerfile.swift` is included in the project but isn't part of the resource phase
- Verify `Documentation` files are included (with the appropriate group structure that reflects the file system) and that the files aren't copied to resources
- Verify `Server` folder reference is included
### Short description
Tuist is a command line tool that offers several useful features related to managing Xcode projects at scale. The generation features are worthy of bundling in a library to enable external tools to leverage it and build on top of it.
### Solution
The `TuistGenerator` library has been previously created and several changes have been incrementally made to allow seamlessly migrating all the generation related code to it.
### Test Plan
- Ensure unit tests continue to pass
`swift test`
- Ensure acceptance tests continue to pass
`bundle exec rake features`
- Manually generate any of the projects within `fixtures`
`tuist generate`
### Notes
`TuistGenerator` is not yet stable - breaking changes will most likely be made.
- A few additional build settings are needed when linking against pre-built static libraries
- `LIBRARY_SEARCH_PATHS` needs to point to the directory containing the `.a` file
- `SWIFT_INCLUDE_PATHS` need to point to the directory containing the `.swiftmodule` file
Test Plan:
- Generate `fixtures/ios_app_with_static_libraries`
- Verify the application builds
- Verify the `LIBRARY_SEARCH_PATHS` and `SWIFT_INCLUDE_PATHS` settings are set on target `A`