Skip to content

User's guide isn't clear how arguments for a "shebang" script are parsed #5326

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

Closed
phlummox opened this issue Jun 21, 2020 · 1 comment
Closed

Comments

@phlummox
Copy link

General summary/comments

Suppose you have a stack script myscript.hs:

#!/usr/bin/env stack
-- stack --verbosity info --resolver lts-13.30 script

main :: IO ()
main = print ()

The stack User's Guide says that options for stack can be specified on the second line. However, if you try the above script, the --verbosity info argument doesn't have any effect (though the --resolver lts-13.30 argument does).

At any rate - the behaviour of the above script is different, when executed, from what would happen if you ran stack --verbosity info --resolver lts-13.30 script ./myscript.hs at the shell prompt, and also from what would happen if the comment line instead said

-- stack  --resolver lts-13.30 script --verbosity info

(i.e., with --verbosity info placed after script instead of before).

This isn't (so far as I can see) documented clearly in the User's Guide, and contradicts the output of running stack --help, which clearly says that "general" stack options like --verbosity should go before the script command:

$ stack --help
stack - The Haskell Tool Stack

Usage: stack [--help] [--version] [--numeric-version] [--hpack-numeric-version]
             [--docker*] [--nix*] ([--verbosity VERBOSITY] | [-v|--verbose] |
             [--silent]) [--[no-]time-in-log] [--stack-root STACK-ROOT]
             [--work-dir WORK-DIR] [--[no-]system-ghc] [--[no-]install-ghc]
             [--arch ARCH] [--ghc-variant VARIANT] [--ghc-build BUILD]
             [-j|--jobs JOBS] [--extra-include-dirs DIR] [--extra-lib-dirs DIR]
             [--with-gcc PATH-TO-GCC] [--with-hpack HPACK]
             [--[no-]skip-ghc-check] [--[no-]skip-msys] [--local-bin-path DIR]
             [--setup-info-yaml URL] [--[no-]modify-code-page]
             [--[no-]allow-different-user] [--[no-]dump-logs]
             [--color|--colour WHEN] [--resolver RESOLVER] [--compiler COMPILER]
             [--[no-]terminal] [--stack-colors|--stack-colours STYLES]
             [--terminal-width INT] [--stack-yaml STACK-YAML] [--lock-file ARG]
             COMMAND|FILE
  ...

This can be annoying if a script-user wants to, say, pass "--verbosity debug" to diagnose some problem with the script, edits the script to add that option in the usual way, and gets no change in behaviour.

Steps to reproduce

  1. Create a script "myscript.hs":
#!/usr/bin/env stack
-- stack --verbosity info --resolver lts-13.30 script

main :: IO ()
main = print ()
  1. chmod as necessary (e.g. chmod a+rx ./myscript.hs).
  2. Run it: ./myscript.hs.

Expected

Verbose, info-level output should be produced:

Using resolver: lts-13.30 specified on command line
()

Actual

No extra output is produced:

()

The difference is more dramatic still if you use --verbosity debug, obviously :) I can't provide any verbose output from the script in the failing case, since the bug I'm reporting prevents me from doing that. I haven't experimented to see if any other options are affected, but I assume they are (which would be bad, if they said something more important, like --compiler, say).

Either the User's Guide and the --help output are missing information about the expected behaviour of stack scripts, or the behaviour is wrong - I'm not sure which.

Stack version

$ ./stack --version 
Version 2.3.1, Git revision de2a7b694f07de7e6cf17f8c92338c16286b2878 (8103 commits) x86_64 hpack-0.33.0

Method of installation

  • Official binary, downloaded from GitHub
@mpilgrem
Copy link
Member

I think I have identified what is happening. To restate the problem, in the script interpreter:

stack --resolver lts-20.18 script --verbosity info -- Script.hs

appears to respect the 'global' option --verbosity info, while:

stack --verbosity info --resolver lts-20.18 script -- Script.hs

does not.

The reason is:

  • 'global' options are actually parsed twice, once in the stack command and again in the script subcommand. The subcommand's parse result trumps the command's parse result. (That happens in Options.Applicative.Complicated.complicatedOptions and the line pure (mappend c a, b).)
  • in the interpreter, the parsing of verbosity has a default of Just LevelError. (That is set in Main.commandlineHandler.)

So, in the first example, the --verbosity info of the subcommand trumps the (hidden) default of LevelError of the stack command. In the second example the (hidden) default of LevelError of the subcommand trumps the --verbosity info of the command.

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