Exclude the resource from a build phase. Keep in the project

Question

Imagine the typical project/target with a Resources folder inside.

-- Sources
    --- ...
-- Resources
    -- Assets.xcassets
    -- Assets.car // <- Precompiled asset catalog
    -- ...
...

As our project got bigger we want to precompile the assets catalog into the Assets.car to improve our compilation time using some kind of a .lock file.

We also need to use a standard UI for asset catalogs inside Xcode to add new assets.

This poses an issue when we have both Assets.car and Assets.xcassets when declaring our target as

Target(
    name: "Sample",
    destinations: [.iPhone],
    product: .app,
    productName: "SampleApp",
    bundleId: "com.sample.app",
    sources: ["Sources/**"],
    resources: ["Resources/**"],
)

will give us the error in compile time

Multiple commands produce the same output... since we now have duplicate Assets.car resources

Using ResourceFileElement.glob(pattern: "Resources/**", excluding: ["Resources/Assets.xcasset"]) will fix the compile error but will leave us without the asset catalog UI and it would be too hard to add new assets.

Expectation

A way to override the Copy bundle resources build phase. Basically keep the Assets.xcasset inside a project structure but omit it in the build phase. Then we can copy the Assets.car as a copyAction of the target.

Context

  • Tuist version: 4.27.0+

Desired project structure

  • No Assets.xcasset in the copy bundle resources
  • Assets.car in the custom copy phase

Hey @havebeenfitz :wave:

Have you considered adding your Assets.xcassets as additionalFiles? That should keep them in the generated Xcode project without adding them to the Copy Bundle Resources build phase.

Thank you @marekfort, I missed that option. Tried it and it works as expected!

This does not seem to work properly for me.

I have 3 Localizable files and want to keep SomeLanguage in the project file structure, but it is not yet production ready. So with XcodeGen i used to omit it from the buildPhase, now while migrating to Tuist I am having an issue that when using additionalFiles it is added both to the project but also the buildPhase including it in the final app.

Is there any other way to add files to the project navigator but keep it out of the buildPhase

e.g.

resource: [ .glob(pattern: “Modules/Presentation/Assets/Resources/",
excluding: [
"Modules/Presentation/Assets/Resources/en.lproj/
”,
“Modules/Presentation/Assets/Resources/dk.lproj/"
]),
additionalFiles: [
"Modules/Presentation/Assets/Resources/en.lproj/
”,
“Modules/Presentation/Assets/Resources/dk.lproj/**”
]

This adds resources but exclude two specific languages as resources and adds them as additionalFiles.

This re-adds them to the buildPhase, same effect if added as additionalFiles to the project instead of target. :man_shrugging:

@alessdiimperio Have you tried removing the resources glob? I wonder if it’s the excluding pattern that’s off. Worth testing out, although I understand you need to retain that glob. But maybe you can figure out what’s going out by shuffling the directories and globs a bit.

additionalFiles is still the only way you can achieve what you want. If you need more help, you’ll need to create a reproducible sample that we could take a look at. I can’t provide more guidance based on the context you provided.

Here is a simple example of my issue.

en.lproj, sv.lproj and Base.lproj are all added to the target, however en.lproj should be excluded as it’s only added as an additionalFile and not as resource

Hey @alessdiimperio!

Yes, that looks like a bug. Would you mind raising an issue and providing as much detail in there as possible, including the reproducible sample?