It would be good if the script could detect it's running via swift-sh
A common hack is to use #filename to locate resources living alongside the source files. When swift-sh moves the script source to its cache, this doesn't work anymore.
Idea: Instead of copying the script itself, could you still point to the original file in the Package.swift, e.g.:
.target(name: "main", dependencies: ["cows"],
path: "/Users/helge/dev/scripts/",
sources: ["blub.swift"])
I think that would be very useful regardless?
I tried this initially, unfortunately SwiftPM insists that package sources are below the folder that contains the Package.swift file. Maybe we can figure out some clever solution to trick SwiftPM, otherwise not much can be done without changes to SwiftPM itself.
One (lot of work) solution would be to generate a module that contains path information that can be imported by the script.
I was wondering about that, the path thing is probably due to the sandboxing. But that was just a suggestion. What the issue is really about is the script knowing that it is running within swift-sh. Then I can adjust the library code not to use the #filename lookup.
What about this, prepend the copied script with this:
import func Darwin.setenv
Darwin.setenv("SWIFT_SH_ORIGINAL_FILE_LOCATION", ... the loc, 1)
There is a small chance that the import might collide with the script itself, but I suppose it is low. And maybe the feature could be disabled via #!/usr/bin/swift sh --no-original-location or something.
oh yes, env-var is a good solution.
We also define SWIFT_SH (or something like that), IIRC. Which could be used in conjunction with the env-var.
PR welcome.
In fact since we control the output, we could just define a let __script_path or some such. Avoids the import.
Line numbers will be off as a result unfortunately. But really we should be mangling any compiler error messages anyway.
let is not good enough because libraries may want to inspect that setting. needs to be more global.
It seems any library that depends on its location is asking for trouble, but I don’t see any reason to prohibit the env-var solution, so feel free.
Actually something which would also be really nice if argv[0] would be patched to reflect the actual file. I'll see whether I get to providing a PR myself.
(BTW: The location is for resource lookup and only used during development / quick hacks, on deployment the sources wouldn't be available and it would switch to cwd or an explicit location. The special issue w/ swift-sh is that it does both, drop the source and yet still have them - the original idea was to disable #filename resource lookup when running within swift-sh)
While waiting for proper support for this (either argv[0] override or env-based solution), I’m using the _ environment variable.
A very hacky solution but it works for me, with bash and zsh 🙃