-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Arguments array - should the program name be included? #2123
Comments
@rsp just for clarification with recent changes to CLI Deno behaves like example no. 2
|
@bartlomieju so it will be more like Node which would mean skipping two elements to get the actual program arguments. I'm wondering if that is a good use of (Update: I would understand the logic of having full |
@rsp agreed. |
@bartlomieju I agree that scripts shouldn't care about the interpreter flags, it was just an example for completeness sake. I think that ideally
For example for the command:
Plus it would be nice to have some consistency in the names because those will probably never change. (For the permissions API I agree that scripts should use |
I can't say I have a strong opinion on this, but we should figure it out before 1.0... I'm adding this issue to the blockers. |
Maybe the same as sh and bash is just okay.
> sh test.sh -v
test.sh -v > ./test.sh -v
test.sh -v > sh -v test.sh
#!/bin/sh
echo $0 $@
test.sh > sh -a <(cat test.sh) -b
/dev/fd/61 -b Shell name and shell options will be hidden, index 0 always for the script file, follows the arguments for script. |
I agree with @rsp about the args and program path, but I vote against having access to the deno name/path. Programs shouldn't care about their interpreter, and should not be aware of it. Also, what happens when the script is ran directly with a shebang line? |
@NotWearingPants actually when the script is run directly with a shebang line (as I also tend to agree that what sh/bash/ruby/perl is doing is the most reasonable way, as also @Fenzland commented above. Mainly because I rarely treat the script name as one of the arguments so if the invocation: $ deno run script.ts x y would not give us the arguments as Update: As @bartlomieju showed in April, Deno worked like Node: $ deno run --allow-read script.ts arg1 arg2
["deno", "script.ts", "arg1", "arg2"] Now it seems that it works like Python: $ deno run --allow-read script.ts arg1 arg2
[ "script.ts", "arg1", "arg2" ] I believe it would be most useful to work like sh, Bash, Perl and Ruby: $ deno run --allow-read script.ts arg1 arg2
[ "arg1", "arg2" ] because I don't see any value in confusing the script name with one of its arguments (the only argument would be a consistency with C but this is higher level language and user experience is more important than reusing a single array to serve two purposes). I am talking about the array returned by I wanted to clarify as this is listed as one of the blockers for Major features necessary for 1.0 #2473. |
By the way, some edge cases: Eval has the full script in
REPL has nothing at
I couldn't run REPL with args to see what's in Deno.args:
I tried eval with arguments, take 1:
Eval with arguments, take 2:
Maybe the I think having only arguments to our program in Deno.args (as opposed to have all arguments to our program program prefixed with some arguments to (Edit: removed redundant examples) |
Interesting values of
In REPL it throws:
|
Just the actual arguments seems like the most reasonable approach given Deno's goals. Including any more arguments (and especially hard-coding The entire command line might be important to include in certain cases (i.e. for printing out a warning that a script is being run an incorrect way). But this should be an advanced feature, and what it contains will probably change as Deno evolves over time (for example, some |
I also want |
In some cases, it is necessary to obtain the complete command So I think it is necessary to include /usr/bin/env deno run example.ts |
@axetroy Necessary, but maybe given through some op as @sholladay suggested. Not necessarily in |
There could be a new |
Bash has the actual arguments as positional parameters but it actually has the script name in |
Just wanted to summarize some of the viewpoints expressed on this thread so far. It looks like there are users who:
It doesn't really appear like there's a right or wrong here, as each of these has valid and common use cases. It's probably best to come up with an API that can support all of these three cases with as little confusion between them as possible. (For each use case, it should be clear which API to use.) Would the following combination address everyone's needs?
|
Just another note on why I think Deno will hopefully become a tool used by beginners and people who haven't used the command line before. But these people will probably be somewhat familiar with JavaScript functions and arguments. Passing just the args to the script in Note that many of these users might not really care about the command-line environment at all. They don't care about what's in a program's real argv. All they care about is that they wrote a JavaScript function that runs in the browser, and they want to get it to work in a terminal too. Deno should make it easy for users who don't care about the command line to write robust command-line programs. This should matter even for people who do care about the command line -- you want to be able to use code written by good JS developers without worrying that it'll break simply because they don't know how the command line works. |
Great points @szhu, I can see the advantages of having only the script arguments in |
We've discussed this and we're going to change the API so that |
So what's the procedure for users who do want/need the path of the originally-invoked script? I assume it's not shelling out to EDIT: Never mind, I saw the comment mentioning |
Deno.execPath === "/usr/local/bin/deno";
Deno.scriptPath === "/home/Alhadis/test.mjs"; |
One breaking change could be to make .args a method and then it could take options e.g. include script, include deno flags, deno executable etc. Deno.args() // current Deno.args
Deno.args({ includeScript: true }) // etc |
@hayd Not a fan. I think 'soft' design decisions like that compound as complexity. |
Instead of a braking change with: Deno.args({ includeScript: true }) we [location.pathname, ...Deno.args] if we need an array like this. |
👍 We should document this in Deno.args, and how to splice in the permissions as well. |
RE permissions/deno flags, this came up for me in wanting to query whether --lock was passed. |
Is there a reason that the program name is included in
Deno.args
?In comparison to Node (that includes the
node
binary path inprocess.argv
) Deno removes thedeno
binary path from theDeno.args
and puts it inDeno.execPath
. The TS/JS program name is available inlocation.pathname
but unlike theDeno.execPath
it is still left in theDeno.args
. Is there a reason for that or is it just a coincidence of not havinglocation.pathname
in the past?If we want to be able to write short one-liners with
deno eval
then it would be useful to use.map()
andforEach()
onDeno.args
directly instead ofDeno.args.slice(1).forEach(...)
- is it still possible to change the currentDeno.args
to include only the arguments to the program or is it too late for that?Possible options
When a script asks for its arguments, there are few possible answers to give.
Let's say we run hypothetically
deno run -RWX script.ts arg
(using syntax from #2081)What should be in
Deno.args
?argv[]
of the process["deno", "run", "-RWX", "script.ts", "arg"]
["deno", "script.ts", "arg"]
["script.ts", "arg"]
["arg"]
I would argue that from the point of view of a script the most important is an array or its actual arguments (
["arg"]
in the examples above) like in Perl, Ruby and shells and it's convenient that we don't need to skip the first one like in Python and Deno or the first two like in Node, and while it's sometimes useful to know the location of the script and the interpreter, they don't need to be in the same array because they are not really arguments (to the program in question, only to the compiler).Additionally, the paths to the runtime and the script if present can be left as they were in the actual
argv[]
of the process, or can they be expanded to the full path (as is done by Node, but not by$0
in Bash or Perl - they leave it as it was in real invocation) and not by Deno (currently) inDeno.args[0]
(unlikelocation.pathname
).Examples in other runtimes
Examples of argument arrays in Deno and other runtimes:
(note that only Node includes the path to
node
binary)Examples of program names in Deno and other runtimes:
(note that only Node expands the path)
The text was updated successfully, but these errors were encountered: