swift-sh icon indicating copy to clipboard operation
swift-sh copied to clipboard

It would be good if the script could detect it's running via swift-sh

Open helje5 opened this issue 5 years ago • 8 comments

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?

helje5 avatar Jan 12 '20 21:01 helje5

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.

mxcl avatar Jan 14 '20 14:01 mxcl

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.

helje5 avatar Jan 14 '20 14:01 helje5

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.

mxcl avatar Jan 14 '20 18:01 mxcl

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.

mxcl avatar Jan 14 '20 18:01 mxcl

let is not good enough because libraries may want to inspect that setting. needs to be more global.

helje5 avatar Jan 14 '20 19:01 helje5

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.

mxcl avatar Jan 14 '20 20:01 mxcl

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)

helje5 avatar Jan 15 '20 11:01 helje5

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 🙃

Frizlab avatar Jun 02 '20 10:06 Frizlab