Swift CLI - $PATH is incomplete

Viewed 76

I'm building a CLI tool as a Swift Package. Part of the process requires me to invoke some processes (such as gsutil). When I try to invoke those, I always end up with *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'launch path not accessible'

Some further analysis revealed that regular commands suchs as pwd or which work just fine. As pictured below, if I try to echo $PATH, I get an incomplete result.

debugging The value of $PATH while running the project directly

/Applications/Xcode-beta.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin\n

is completely different from my actual $PATH variable:

echo $PATH
/Users/skwiggs/google-cloud-sdk/bin:/Users/skwiggs/.npm-global/bin:/Users/skwiggs/.rbenv/bin:/Users/skwiggs/.rbenv/shims:/Users/skwiggs/google-cloud-sdk/bin:/Users/skwiggs/.npm-global/bin:/Users/skwiggs/.rbenv/bin:/Users/skwiggs/.rbenv/shims:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/share/dotnet:~/.dotnet/tools:/Library/Apple/usr/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands

How can I ensure that my env variables are correctly set while debugging my CLI tool?

2 Answers

Running the tool directly from a shell will pass it the expected $PATH value, so this issue only happens when debugging.

If you want to debug your program with the correct $PATH value, you can add an Environment Variable in the active scheme. That variable is only used while debugging, so it's safe to override it (it will be ignored when invoking your product from a shell).

  1. Open a terminal
  2. Run echo $PATH
  3. Copy the output

Then, open XCode

Scheme -> Edit Scheme -> Run -> Environment Variables -> Add.

Name PATH Value <paste the value from terminal>

scheme environment variable

Build & run, you can now debug as if your project was invoked from a shell.

(keep in mind you'll have to do this for every new project where this behaviour is needed, and any change to your $PATH will have to be retrofitted to your projects)

If you're using Swift, you can access your environment variables directly using

guard let path = ProcessInfo.processInfo.environment["PATH"] else {
    return
}
// ...
Related