Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running a stand-alone subcommand with zx #1592

Closed
p3k opened this issue Aug 31, 2021 · 8 comments
Closed

Running a stand-alone subcommand with zx #1592

p3k opened this issue Aug 31, 2021 · 8 comments

Comments

@p3k
Copy link

p3k commented Aug 31, 2021

We are trying to combine CommanderJS and zx in subcommand and I noticed the zx extensions are not available then:

// foo.mjs (called by `zx ./foo.mjs info`)

#!/usr/bin/env zx

import { program } from "commander/esm.mjs";

program.command("info", "output information").alias("i")
// foo-info.mjs

#!/usr/bin/env zx

console.log(typeof $);
// undefined

As a work-around we certainly could import the extensions again (e.g. with import { $ } from "zx") but it feels a bit redundant and wrong.

Is there an option to run a stand-alone subcommand with the correct binary? Or make CommanderJS respect the shebang #!/usr/bin/env zx?

@shadowspawn
Copy link
Collaborator

shadowspawn commented Aug 31, 2021

If you make foo-info.mjs executable and remove the file extension, then the file will be executed directly and the shebang will apply. (This does not work on Windows.)

// foo-info
#!/usr/bin/env zx

console.log(typeof $);
% zx foo.mjs i
function

If the file has a source extension then process.argv[0] is used to process it, which is node in this case.

const sourceExt = ['.js', '.ts', '.tsx', '.mjs', '.cjs'];

@p3k
Copy link
Author

p3k commented Aug 31, 2021

great, that works! thanks for the explanation, @shadowspawn

the only downside seems to be missing syntax highlighting due to the undefined file extension for editors…

@shadowspawn
Copy link
Collaborator

For interest...

Commander expects by default that argv[0] is the utility, argv[1] is the script name, and argv[2] is the first of the user supplied arguments.

But when launched by zx there is an extra argument which is zx itself.

// foo.mjs
console.log(process.argv);
% zx foo.mjs install
[ '/usr/local/bin/node', '/usr/local/bin/zx', 'foo.mjs', 'install' ]

I think if zx replaced the node argument instead of adding afterwards, Commander would work ok with the file extension.

@p3k
Copy link
Author

p3k commented Aug 31, 2021

I think if zx replaced the node argument instead of adding afterwards, Commander would work ok with the file extension.

good point. maybe this is due to zx being an npm module run by node, anyway…?

does this mean, i could tamper with the argv array myself and make this work somehow?

@shadowspawn
Copy link
Collaborator

If you can modify process.argv, yes. But is it read-only in esm?

@p3k
Copy link
Author

p3k commented Aug 31, 2021

If you can modify process.argv, yes. But is it read-only in esm?

looking good, e.g.

console.log(process.argv.length) // 4
process.argv.shift();
console.log(process.argv.length) // 3

@p3k
Copy link
Author

p3k commented Aug 31, 2021

and now zx works with scripts having file extension, too! awesome.

@shadowspawn shadowspawn changed the title Running a stand-alone subcommand Running a stand-alone subcommand with zx Aug 31, 2021
@shadowspawn
Copy link
Collaborator

An answer was provided, and no further activity in a month. Closing this as resolved.

Feel free to open a new issue if it comes up again, with new information and renewed interest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants