asdf-haskell
asdf-haskell copied to clipboard
Forward quoted shell parameters to installed tools
The install script installs shims which forward arguments to stack
, but the current forwarding isn't perfect. Specifically, if you try to pass a multi-word or quoted argument through these shims, those words get split up on IFS
and the words get passed along individually.
For example, ghc
supports evaluating expressions directly with the -e
flag, such that
$ ghc -e 'putStrLn "Hello, world!"'
Hello, world!
However, because these shims use $*
, any quoted parameters are first expanded, then split on IFS
, and then forwarded along:
$ ghc -e 'putStrLn "Hello, world!"'
target ‘"Hello,’ is not a module name or a source file
That's because with $*
, the above command effectively expands to
exec $local_bin/stack exec ghc -- -e putStrLn Hello, world!
and each word is forwarded individually; -e
applies only to the putStrLn
argument, and ghc
chokes on Hello,
, expecting a source file. Instead, using "$@"
for all parameters correctly keeps multi-word and quoted input as-is, allowing all arguments to be correctly forwarded to the underlying binaries.
This affects installing haskell-language-server
, as haskell-language-server-wrapper
attempts to discover the full path to GHC via stack exec ghc -- -v0 -package-env=- -e "do e <- System.Environment.getExecutablePath ; System.IO.putStr e"
and GHC gets each of those words as a separate parameter:
$ haskell-language-server-wrapper --debug .
No 'hie.yaml' found. Try to discover the project type!
Run entered for haskell-language-server-wrapper(haskell-language-server-wrapper) Version 1.6.1.1, Git revision 016ccde658860dc73d9fdd7ee840b145eff01733 (2663 commits) x86_64 ghc-8.10.7
Current directory: /Users/itai/Sync/Development/Code/Haskell/euler-hs
Operating system: darwin
Arguments: ["--debug","."]
Cradle directory: /Users/itai/Sync/Development/Code/Haskell/euler-hs
Cradle type: Stack
Tool versions found on the $PATH
cabal: Not found
stack: 2.7.3
ghc: 8.10.7
Consulting the cradle to get project GHC version...
Project GHC version: 8.10.7
haskell-language-server exe candidates: ["haskell-language-server-8.10.7","haskell-language-server"]
Launching haskell-language-server exe at:/Users/itai/.asdf/installs/haskell/8.10.7/bin/haskell-language-server-8.10.7
Failed to get project GHC executable path: CradleError {cradleErrorDependencies = [], cradleErrorExitCode = ExitFailure 1, cradleErrorStderr = ["Error when calling stack exec ghc -- -v0 -package-env=- -e do e <- System.Environment.getExecutablePath ; System.IO.putStr e","","Warning: ignoring unrecognised input `System.Environment.getExecutablePath'\nWarning: ignoring unrecognised input `System.IO.putStr'\ntarget \8216e\8217 is not a module name or a source file\n"]}
With these changes, on my system, I see the expected
$ stack exec ghc -- "-v0" "-package-env=-" "-e" "do e <- System.Environment.getExecutablePath ; System.IO.putStr e"
/Users/itai/.asdf/installs/haskell/8.10.7/stack/programs/x86_64-osx/ghc-8.10.7/lib/ghc-8.10.7/bin/ghc
and I can confirm that haskell-language-server-wrapper
runs successfully.
What is the difference between $* and $@? on the Unix & Linux StackExchange has some really instructive examples of why you might want to prefer "$@"
over $*
(and "$*"
, and even plain $@
).
@smorimoto could you please take a look and merge this? I faced the same issue, took me a day to track it down to the shims being created. Apologies if I'm reaching out to the wrong person, please let me know if anything needs to be done to take this forward. Thanks!