Access to absolute path for TargetScript

Why is this needed?

In Build Phase scripts there is a need to understand in which directory the Workspace is located.
There is no way to find out this directory using Xcode’s built-in environment variables, as far as I know. (SRCROOT is the .xcodeproj directory of the project, not the workspace)

For example, I have a SwiftGen script in the build phase, in which I need to specify the path to a custom stenicl template.

swiftgen run xcassets \
        --quiet \
        --templatePath "/Users/ernest0n/Projects/MY_PROJECT/Tuist/ProjectDescriptionHelpers/TargetScript/SwiftGen/Templates/Assets.stencil" \
        --output "/Users/ernest0n/Projects/MY_PROJECT/iOSApp/Sources/Generated/Assets+Generated.swift" \
        "/Users/ernest0n/Projects/MY_PROJECT/iOSApp/Resources/Assets"

All custom templates are located in the root directory of the project and in the script I need to know where this folder with templates is located, without using ../ to return to the previous directory, because the manifests of my projects can be located at different levels of the file structure.

Another example: Execute the swiftlint command from the root directory, not the specific xcodeproj directory.

cd "/Users/ernest0n/Projects/MY_PROJECT

swiftlint lint --config "/Users/ernest0n/Projects/MY_PROJECT/.swiftlint.yml" \

This way the linter will scan the files of the entire project, not the specific xcodeproj, which may be located in a child directory.

Proposal

Add an extension to Path to get the path to absolute and relative paths:

// Users/<username>/my-project/
Path.rootDirectory.absoluteString 

// ./
Path.rootDirectory.relativeString

// Users/<username>/my-project/Modules/Core/
Path.manifestDirectory.absoluteString

// ./Modules/Core/
Path.manifestDirectory.relativeString

// ./Modules/Core/Resources/Foo.strings
// Path.relativeToManifest("Resources/Foo.strings").relativeString

Thanks @Ernest0N for sharing this idea.

My suggestion is that your scripts don’t contain absolute paths, because this creates an implicit dependency between the project and the environment, going against aiming for hemerticity, which is something you’ll most likely want to have in your project.

How are you currently solving this? I’d go as far as to suggest not to run those things in build phases. Script build phases are compilation units in your graph, that might make your Swift UI previews work unreliably. So the fewer, the better. I know it sounds odd, considering it’s possible, but not everything that’s possible in Xcode is a good idea if you want the tool to work reliably,