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

Allow global Stack arguments with a script #2318

Merged

Conversation

puffnfresh
Copy link
Contributor

Stack has support for running Haskell scripts directly, when you pass a
filename as an argument.

Previously this worked by having a fallback: if any argument couldn't be
parsed as a valid option, check if the first argument was a file.

Sadly this broke for cases such as:

stack --nix example.hs

And this means something different:

stack example.hs --nix

Now Stack will split the arguments into two:

  1. All arguments until the first existing file
  2. The first existing file and all arguments afterwards

So the above example gets parsed as:

  1. ["--nix"]
  2. ["example.hs"]

The first section will be reparsed as options. The second section will
be used like it was previously.

This fixes the specific case of running interpreter scripts when having
the Nix option enabled globally. Stack would correctly start a
nix-shell. A nix-shell respawns Stack with some extra global
arguments (extra-lib-dirs and extra-include-dirs) but Stack would treat
them as file arguments, because just one of the arguments (the script)
was a file.


Fixes #2316

Stack has support for running Haskell scripts directly, when you pass a
filename as an argument.

Previously this worked by having a fallback: if any argument couldn't be
parsed as a valid option, check if the first argument was a file.

Sadly this broke for cases such as:

    stack --nix example.hs

And this means something different:

    stack example.hs --nix

Now Stack will split the arguments into two:

1. All arguments until the first existing file
2. The first existing file and all arguments afterwards

So the above example gets parsed as:

1. `["--nix"]`
2. `["example.hs"]`

The first section will be reparsed as options. The second section will
be used like it was previously.

This fixes the specific case of running interpreter scripts when having
the Nix option enabled globally. Stack would correctly start a
nix-shell. A nix-shell respawns Stack with some extra global
arguments (extra-lib-dirs and extra-include-dirs) but Stack would treat
them as file arguments, because just one of the arguments (the script)
was a file.
@sjakobi
Copy link
Member

sjakobi commented Jul 6, 2016

This does not appear to fix the my similar issue in #2343.

Could this fix be generalized for commands like stack -v script.hs?

@harendra-kumar
Copy link
Collaborator

@sjakobi that seems to be a different problem special to verbosity level. We turn down the noise when in interpreter mode so that we do not see unnecessary output along with the script output. But that seems to override even if we want to turn it on.

        globalOptsParser kind (if isInterpreter
                                then Just $ LevelOther "silent"
                                else Nothing)

See #1487 and #1472. I see your comments in 1472 for exactly the same problem earlier.

@harendra-kumar
Copy link
Collaborator

@puffnfresh there are other alternatives to achieve the same thing but they are not as convenient:

  • modify the command line in the script before running it.
  • copy and paste the command line from the script and add to it before running. Not convenient and especially hard when the command in the script is a multiline command.

This fix, as I see it, adds value in conveniently augmenting the existing command line inside the script. There are a few things to note about it though:

  • This is limited to prefixing options to the existing stack command inside the script i.e. add global arguments. Any subcommand arguments are still controlled only from within the script.
  • If a global argument refers to an executable file, that file will be executed instead. This might come as a surprise to the users. That's the artifact of a hack. It was a hack already though, this fix builds upon that.

I am inclined towards merging it, except if someone has a concern about the second point.

-- nix-shell) - we need to find the first argument which is a file, everything
-- afterwards is an argument to the script, everything before is an argument
-- to Stack
(stackArgs, fileArgs) <- spanM (fmap not . D.doesFileExist) args
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use takeWhileM from monad-loops. monad-loops is already a dependency of stack via monad-logger.

The spanM function can be added to monad-loops package.

@harendra-kumar
Copy link
Collaborator

We should also add a note about this new behavior in the script interpreter section of the GUIDE.

@harendra-kumar
Copy link
Collaborator

Its been pending for a while, I am just going ahead and merging this.

@harendra-kumar harendra-kumar merged commit 84cefa9 into commercialhaskell:master Jul 20, 2016
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

Successfully merging this pull request may close these issues.

Nix and shebangs don't work together
3 participants