Open brandonkal opened 4 years ago
I thought about this before, but it would incur a change in behavior and tiny performance penalty.
Right now, mask just passes source strings to runtimes via arguments (most commonly -c
). This means that mask doesn't have to write to a temp file and execute it at all, which is a bit more work.
AFAIK shebangs are only effective when executing a file. Since mask doesn't write temp files to execute, this isn't possible yet.
Mask already supports the most common runtimes and it's easy to add more if needed. I'm unsure how important adding shebang support really is at this point.
It would only be a tiny performance penalty on the first run.
For example, the Deno runtime compiles and type-checks code before executing. If it is passed a file, it can cache compilation for that file path, significantly speeding up subsequent runs. Unfortunately booting up the typescript compiler for deno is measurably slow for the first file. So for Deno TypeScript to work with a good user experience, writing to files would be required. At that point, general shebang support makes sense to me.
Adding hashbang and pound-bang keywords to make issue more searchable.
Just an FYI that shebangs are currently supported in my fork: https://github.com/brandonkal/inkjet
No PR? This was my request too! Even if easy to add runtimes (you already support the most popular ones) some may be too niche. Use cases:
Yeah, I do think adding support for shebangs will be useful.
My concern above regarding the tiny perf hit to write to a temp file can be avoided by checking if the code block starts with a shebang and only write+execute a temp file in that case.
After I commented I realized 1 of your biggest DX improvements over Maid is injecting arguments by name. Shebang might be nice for corner cases like awk or transpiled JS but it'd be sad to forgo that feature in .NET or Deno. I wonder if there's a way to query GitHub for any popular ones not mentioned here 🤔
Since argument injection is just setting environment variables, I would assume that executing a temp file which contains a shebang would still be able to use those set env vars. Though, I could be wrong... haven't tried this before 😅
Ah I see that in add_utility_variables
now. I imagined it was something trickier. Now I understand about the temp file too. It looks like there are minor bugs with the current command config though:
I think a more general and flexible solution could be a cascading lookup for commands:
$XDG_CONFIG_HOME
(or the Windows equivalent) …Default:
[deno]
langs = ['ts', 'typescript']
[deno.command]
# WARNING: eval implies --allow-all
sh = 'deno eval'
# in this case same on Windows
ps = 'deno eval'
cmd = 'deno eval'
[node]
...
User:
[deno]
command = '''deno eval $SCRIPT --print'''
maskfile.md
Default:
```ts
"this is denoooo"
```
Shebang (temp file):
```ts
#!/usr/bin/env deno run --allow-read --allow-write
console.log("this is denoooo with permissions")
```
Inline command (no temp file and shorter):
```ts ts-node -p
"this is noooode"
```
PowerShell is cross-platform but it's configured for Windows.
Yeah, Windows and PowerShell support were added together early last year. If someone opens an issue for PowerShell support on linux/macOS, it should be a quick change.
Your fallback assumes the target shell is the same as the calling shell.
Hmmm, I'm not quite sure I follow. Are you talking about this fallback block below? I think this actually relies on the code block lang code to determine the executor
... so if someone uses "fish" as the lang code, that will be the shell that is invoked.
I think a more general and flexible solution could be a cascading lookup for commands
Yeah, I'll need to think about this a bit more. I feel like adding shebang support is enough to cover 95% of use cases without having to resort to introducing a config file. FWIW I've tried to keep mask super minimal and only require a single maskfile.md
to operate. Supporting a user-specific config file for mask would result in maskfiles being less portable and more dependent on the individual users sharing the exact same config setup.
I think this actually relies on the code block lang code to determine the
executor
My bad I misread it.
If someone opens an issue
Seems silly okay ...
Supporting a user-specific config file
My main point is you save yourself work making it a config file:
stdin
.Neat project I'll circle back when I have a concrete use case ✌🏼
A code block that starts with a shebang should be interpretted as an executable file. This enables mask to support any interpreter.
Ref: https://github.com/casey/just#writing-recipes-in-other-languages