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

Working directory in multi-component project #1584

Closed
dcastro opened this issue Mar 17, 2021 · 9 comments
Closed

Working directory in multi-component project #1584

dcastro opened this issue Mar 17, 2021 · 9 comments
Labels
multi-component Issues relating to multi-component support status: blocked Not actionable, because blocked by upstream/GHC etc. type: bug Something isn't right: doesn't work as intended, documentation is missing/outdated, etc..

Comments

@dcastro
Copy link

dcastro commented Mar 17, 2021

Your environment

Output of haskell-language-server --probe-tools or haskell-language-server-wrapper --probe-tools:

$ haskell-language-server-8.10.4 --probe-tools

haskell-language-server version: 1.0.0.0 (GHC: 8.10.4) (PATH: /home/dc/.ghcup/bin/haskell-language-server-8.10.4~1.0.0) (GIT hash: 4cd1cf934638881e52b3eba9f70157a4b799c0e9)
Tool versions found on the $PATH
cabal:          3.4.0.0
stack:          2.5.1
ghc:            8.10.4

Which lsp-client do you use: VS code

Describe your project (alternative: link to the project):

Contents of hie.yaml:

cradle:
  stack:
    - path: "./code/first/src"
      component: "first:lib"

    - path: "./code/second/src"
      component: "second:lib"

Steps to reproduce

I've created a demo repo here: https://github.com/dcastro/hls-working-dir
It's a multi-component repo, with cabal.project/stack.yaml at the root, and then two components in ./code/first and ./code/second.

  1. Open the repo
  2. The Main module contains a TH splice that displays the working directory used while compiling the project
  3. HLS says the working dir is: /home/dc/dev/other/hls-working-dir
  4. Now build the project with stack build/cabal build all
  5. Stack/cabal say the working dir is: /home/dc/dev/other/hls-working-dir/code/first

image

$ stack build

first> configure (lib)
first> Configuring first-0.1.0.0...
first> build (lib)
first> Preprocessing library for first-0.1.0.0..
first> Building library for first-0.1.0.0..
first> [2 of 2] Compiling Main
first> 
first> /home/dc/dev/other/hls-working-dir/code/first/src/Main.hs:8:3: error:
first>     /home/dc/dev/other/hls-working-dir/code/first
first>   |
first> 8 | $(runIO getCurrentDirectory >>= fail)
first>   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
first> 

Expected behaviour

I expected both HLS, stack and cabal to report the same working dir.

Actual behaviour

HLS uses a different working dir than stack and cabal.

This means that any TH code that reads files from the filesystem will show up as an error in HLS, but compile successfully with stack/cabal.

Include debug information

Execute in the root of your project the command haskell-language-server --debug . and paste the logs here:

Debug output:
$ haskell-language-server-8.10.4 --debug

haskell-language-server version: 1.0.0.0 (GHC: 8.10.4) (PATH: /home/dc/.ghcup/bin/haskell-language-server-8.10.4~1.0.0) (GIT hash: 4cd1cf934638881e52b3eba9f70157a4b799c0e9)
ghcide setup tester in /home/dc/dev/other/hls-working-dir.
Report bugs at https://github.com/haskell/haskell-language-server/issues

Step 1/4: Finding files to test in /home/dc/dev/other/hls-working-dir
Found 3 files

Step 2/4: Looking for hie.yaml files that control setup
Found 1 cradle
  (/home/dc/dev/other/hls-working-dir/hie.yaml)

Step 3/4: Initializing the IDE

Step 4/4: Type checking the files
2021-03-17 13:01:16.531176261 [ThreadId 4] DEBUG hls:   Set files of interest to: [(NormalizedFilePath "/home/dc/dev/other/hls-working-dir/Setup.hs",OnDisk),(NormalizedFilePath "/home/dc/dev/other/hls-working-dir/code/first/src/Main.hs",OnDisk),(NormalizedFilePath "/home/dc/dev/other/hls-working-dir/code/second/src/Main.hs",OnDisk)]
2021-03-17 13:01:16.53260669 [ThreadId 39] INFO hls:    File:     
Hidden:   no
Range:    1:1-2:1
Source:   compiler
Severity: DsError
Message: 
  Internal error, getIdeGlobalExtras, no entry for IdeConfigurationVar
  CallStack (from HasCallStack):
  errorIO, called at src/Development/IDE/Core/Shake.hs:284:20 in
  ghcide-1.0.0.0-inplace:Development.IDE.Core.Shake
2021-03-17 13:01:16.533792889 [ThreadId 72] INFO hls:   Consulting the cradle for "Setup.hs"
Output from setting up the cradle Cradle {cradleRootDir = "/home/dc/dev/other/hls-working-dir", cradleOptsProg = CradleAction: Stack}
2021-03-17 13:01:16.534178941 [ThreadId 72] DEBUG hls:  Session loading result: Left [CradleError {cradleErrorDependencies = [], cradleErrorExitCode = ExitSuccess, cradleErrorStderr = ["Multi Cradle: No prefixes matched","pwd: /home/dc/dev/other/hls-working-dir","filepath: /home/dc/dev/other/hls-working-dir/Setup.hs","prefixes:","(\"./code/first/src\",Stack {component = Just \"first:lib\", stackYaml = Nothing})","(\"./code/second/src\",Stack {component = Just \"second:lib\", stackYaml = Nothing})"]}]
2021-03-17 13:01:16.534826852 [ThreadId 81] INFO hls:   File:     /home/dc/dev/other/hls-working-dir/Setup.hs
Hidden:   no
Range:    1:1-2:1
Source:   cradle
Severity: DsError
Message: 
  Multi Cradle: No prefixes matched
  pwd: /home/dc/dev/other/hls-working-dir
  filepath: /home/dc/dev/other/hls-working-dir/Setup.hs
  prefixes:
  ("./code/first/src",Stack {component = Just "first:lib", stackYaml = Nothing})
  ("./code/second/src",Stack {component = Just "second:lib", stackYaml = Nothing})
2021-03-17 13:01:16.534876926 [ThreadId 74] INFO hls:   Consulting the cradle for "code/second/src/Main.hs"
Output from setting up the cradle Cradle {cradleRootDir = "/home/dc/dev/other/hls-working-dir", cradleOptsProg = CradleAction: Stack}
> Configuring GHCi with the following packages: second
> /home/dc/dev/other/hls-working-dir/.stack-work/install/x86_64-linux-tinfo6/20194adcbf6ca631e5bb7cc88cd14f127e7d4c89a1f70886adceb0693d3d2d43/8.10.4/pkgdb:/home/dc/.stack/snapshots/x86_64-linux-tinfo6/20194adcbf6ca631e5bb7cc88cd14f127e7d4c89a1f70886adceb0693d3d2d43/8.10.4/pkgdb:/home/dc/.stack/programs/x86_64-linux/ghc-tinfo6-8.10.4/lib/ghc-8.10.4/package.conf.d
2021-03-17 13:01:18.429861177 [ThreadId 74] DEBUG hls:  Session loading result: Right (ComponentOptions {componentOptions = ["-i","-odir=/home/dc/dev/other/hls-working-dir/.stack-work/odir","-hidir=/home/dc/dev/other/hls-working-dir/.stack-work/odir","-hide-all-packages","-i/home/dc/dev/other/hls-working-dir/code/second/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build","-i/home/dc/dev/other/hls-working-dir/code/second/src","-i/home/dc/dev/other/hls-working-dir/code/second/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/autogen","-i/home/dc/dev/other/hls-working-dir/code/second/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/global-autogen","-stubdir=/home/dc/dev/other/hls-working-dir/code/second/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build","-package-id=base-4.14.1.0","-package-id=directory-1.3.6.0","-package-id=template-haskell-2.16.0.0","-optP-include","-optP/home/dc/dev/other/hls-working-dir/.stack-work/ghci/2888e6d4/cabal_macros.h","-ghci-script=/tmp/haskell-stack-ghci/bedfa1a2/ghci-script","-package-db","/home/dc/dev/other/hls-working-dir/.stack-work/install/x86_64-linux-tinfo6/20194adcbf6ca631e5bb7cc88cd14f127e7d4c89a1f70886adceb0693d3d2d43/8.10.4/pkgdb","-package-db","/home/dc/.stack/snapshots/x86_64-linux-tinfo6/20194adcbf6ca631e5bb7cc88cd14f127e7d4c89a1f70886adceb0693d3d2d43/8.10.4/pkgdb","-package-db","/home/dc/.stack/programs/x86_64-linux/ghc-tinfo6-8.10.4/lib/ghc-8.10.4/package.conf.d"], componentRoot = "/home/dc/dev/other/hls-working-dir", componentDependencies = ["package.yaml","stack.yaml"]},"/home/dc/.stack/programs/x86_64-linux/ghc-tinfo6-8.10.4/lib/ghc-8.10.4")
2021-03-17 13:01:18.501473791 [ThreadId 74] INFO hls:   Using interface files cache dir: /home/dc/.cache/ghcide/main-d32fccf584082d59658cb320b742423df9c79d7c
2021-03-17 13:01:18.501679887 [ThreadId 74] INFO hls:   Making new HscEnv[main]
2021-03-17 13:01:18.515637525 [ThreadId 74] DEBUG hls:  New Component Cache HscEnvEq: (([],Just HscEnvEq 34),fromList [("/home/dc/dev/other/hls-working-dir/hie.yaml",Just 2021-03-17 12:49:15.018563682 UTC),("package.yaml",Nothing),("stack.yaml",Just 2021-03-17 12:32:57.263046606 UTC)])
2021-03-17 13:01:18.521670309 [ThreadId 74] DEBUG hls:  Known files updated: fromList [(TargetModule Main,["/home/dc/dev/other/hls-working-dir/code/second/src/Main.hs"]),(TargetFile NormalizedFilePath "/home/dc/dev/other/hls-working-dir/code/second/src/Main.hs",["/home/dc/dev/other/hls-working-dir/code/second/src/Main.hs"]),(TargetModule Paths_second,["/home/dc/dev/other/hls-working-dir/code/second/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/autogen/Paths_second.hs"])]
2021-03-17 13:01:18.522070163 [ThreadId 22] DEBUG hls:  Finishing build session(exception: AsyncCancelled)
2021-03-17 13:01:18.522211089 [ThreadId 74] DEBUG hls:  Restarting build session (aborting the previous one took 0.00s)
2021-03-17 13:01:18.524305468 [ThreadId 137] INFO hls:  Consulting the cradle for "Setup.hs"
Output from setting up the cradle Cradle {cradleRootDir = "/home/dc/dev/other/hls-working-dir", cradleOptsProg = CradleAction: Stack}
2021-03-17 13:01:18.524742378 [ThreadId 137] DEBUG hls: Session loading result: Left [CradleError {cradleErrorDependencies = [], cradleErrorExitCode = ExitSuccess, cradleErrorStderr = ["Multi Cradle: No prefixes matched","pwd: /home/dc/dev/other/hls-working-dir","filepath: /home/dc/dev/other/hls-working-dir/Setup.hs","prefixes:","(\"./code/first/src\",Stack {component = Just \"first:lib\", stackYaml = Nothing})","(\"./code/second/src\",Stack {component = Just \"second:lib\", stackYaml = Nothing})"]}]
2021-03-17 13:01:18.525457879 [ThreadId 155] INFO hls:  Consulting the cradle for "code/first/src/Main.hs"
Output from setting up the cradle Cradle {cradleRootDir = "/home/dc/dev/other/hls-working-dir", cradleOptsProg = CradleAction: Stack}
> first> configure (lib)
> Configuring first-0.1.0.0...
> first> initial-build-steps (lib)
> Configuring GHCi with the following packages: first
> /home/dc/dev/other/hls-working-dir/.stack-work/install/x86_64-linux-tinfo6/20194adcbf6ca631e5bb7cc88cd14f127e7d4c89a1f70886adceb0693d3d2d43/8.10.4/pkgdb:/home/dc/.stack/snapshots/x86_64-linux-tinfo6/20194adcbf6ca631e5bb7cc88cd14f127e7d4c89a1f70886adceb0693d3d2d43/8.10.4/pkgdb:/home/dc/.stack/programs/x86_64-linux/ghc-tinfo6-8.10.4/lib/ghc-8.10.4/package.conf.d
2021-03-17 13:01:21.24462362 [ThreadId 155] DEBUG hls:  Session loading result: Right (ComponentOptions {componentOptions = ["-i","-odir=/home/dc/dev/other/hls-working-dir/.stack-work/odir","-hidir=/home/dc/dev/other/hls-working-dir/.stack-work/odir","-hide-all-packages","-i/home/dc/dev/other/hls-working-dir/code/first/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build","-i/home/dc/dev/other/hls-working-dir/code/first/src","-i/home/dc/dev/other/hls-working-dir/code/first/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/autogen","-i/home/dc/dev/other/hls-working-dir/code/first/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/global-autogen","-stubdir=/home/dc/dev/other/hls-working-dir/code/first/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build","-package-id=base-4.14.1.0","-package-id=directory-1.3.6.0","-package-id=template-haskell-2.16.0.0","-optP-include","-optP/home/dc/dev/other/hls-working-dir/.stack-work/ghci/8f20e758/cabal_macros.h","-ghci-script=/tmp/haskell-stack-ghci/392ca6d4/ghci-script","-package-db","/home/dc/dev/other/hls-working-dir/.stack-work/install/x86_64-linux-tinfo6/20194adcbf6ca631e5bb7cc88cd14f127e7d4c89a1f70886adceb0693d3d2d43/8.10.4/pkgdb","-package-db","/home/dc/.stack/snapshots/x86_64-linux-tinfo6/20194adcbf6ca631e5bb7cc88cd14f127e7d4c89a1f70886adceb0693d3d2d43/8.10.4/pkgdb","-package-db","/home/dc/.stack/programs/x86_64-linux/ghc-tinfo6-8.10.4/lib/ghc-8.10.4/package.conf.d"], componentRoot = "/home/dc/dev/other/hls-working-dir", componentDependencies = ["package.yaml","stack.yaml"]},"/home/dc/.stack/programs/x86_64-linux/ghc-tinfo6-8.10.4/lib/ghc-8.10.4")
2021-03-17 13:01:21.312181093 [ThreadId 155] INFO hls:  Using interface files cache dir: /home/dc/.cache/ghcide/main-aaa986f486c0fe39d104e66c71149da983cd4444
2021-03-17 13:01:21.312480688 [ThreadId 155] INFO hls:  Using interface files cache dir: /home/dc/.cache/ghcide/main-aaa986f486c0fe39d104e66c71149da983cd4444
2021-03-17 13:01:21.312653974 [ThreadId 155] INFO hls:  Making new HscEnv[main,main]
2021-03-17 13:01:21.326166204 [ThreadId 155] DEBUG hls: New Component Cache HscEnvEq: (([],Just HscEnvEq 65),fromList [("/home/dc/dev/other/hls-working-dir/hie.yaml",Just 2021-03-17 12:49:15.018563682 UTC),("package.yaml",Nothing),("stack.yaml",Just 2021-03-17 12:32:57.263046606 UTC)])
2021-03-17 13:01:21.329694816 [ThreadId 155] DEBUG hls: New Component Cache HscEnvEq: (([],Just HscEnvEq 66),fromList [("/home/dc/dev/other/hls-working-dir/hie.yaml",Just 2021-03-17 12:49:15.018563682 UTC),("package.yaml",Nothing),("stack.yaml",Just 2021-03-17 12:32:57.263046606 UTC)])
2021-03-17 13:01:21.339352386 [ThreadId 155] DEBUG hls: Known files updated: fromList [(TargetModule Main,["/home/dc/dev/other/hls-working-dir/code/second/src/Main.hs","/home/dc/dev/other/hls-working-dir/code/second/src/Main.hs"]),(TargetFile NormalizedFilePath "/home/dc/dev/other/hls-working-dir/code/second/src/Main.hs",["/home/dc/dev/other/hls-working-dir/code/second/src/Main.hs"]),(TargetModule Paths_second,["/home/dc/dev/other/hls-working-dir/code/second/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/autogen/Paths_second.hs","/home/dc/dev/other/hls-working-dir/code/second/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/autogen/Paths_second.hs"]),(TargetFile NormalizedFilePath "/home/dc/dev/other/hls-working-dir/code/first/src/Main.hs",["/home/dc/dev/other/hls-working-dir/code/first/src/Main.hs"]),(TargetModule Paths_first,["/home/dc/dev/other/hls-working-dir/code/first/.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0/build/autogen/Paths_first.hs"])]
2021-03-17 13:01:21.339839261 [ThreadId 106] DEBUG hls: Finishing build session(exception: AsyncCancelled)
2021-03-17 13:01:21.339973498 [ThreadId 155] DEBUG hls: Restarting build session (aborting the previous one took 0.00s)
2021-03-17 13:01:21.342675628 [ThreadId 228] INFO hls:  Consulting the cradle for "Setup.hs"
Output from setting up the cradle Cradle {cradleRootDir = "/home/dc/dev/other/hls-working-dir", cradleOptsProg = CradleAction: Stack}
2021-03-17 13:01:21.343015257 [ThreadId 228] DEBUG hls: Session loading result: Left [CradleError {cradleErrorDependencies = [], cradleErrorExitCode = ExitSuccess, cradleErrorStderr = ["Multi Cradle: No prefixes matched","pwd: /home/dc/dev/other/hls-working-dir","filepath: /home/dc/dev/other/hls-working-dir/Setup.hs","prefixes:","(\"./code/first/src\",Stack {component = Just \"first:lib\", stackYaml = Nothing})","(\"./code/second/src\",Stack {component = Just \"second:lib\", stackYaml = Nothing})"]}]
2021-03-17 13:01:21.583997285 [ThreadId 330] INFO hls:  File:     /home/dc/dev/other/hls-working-dir/code/first/src/Main.hs
Hidden:   no
Range:    8:3-8:37
Source:   typecheck
Severity: DsError
Message:  /home/dc/dev/other/hls-working-dir
2021-03-17 13:01:21.58432283 [ThreadId 347] INFO hls:   finish: User TypeCheck (took 0.24s)
2021-03-17 13:01:21.584790128 [ThreadId 350] INFO hls:  finish: GetHie (took 0.00s)
Files that failed:
2021-03-17 13:01:21.585068681 [ThreadId 356] INFO hls:  finish: GenerateCore (took 0.00s)
 * /home/dc/dev/other/hls-working-dir/Setup.hs
 * /home/dc/dev/other/hls-working-dir/code/first/src/Main.hs

Completed (1 file worked, 2 files failed)
haskell-language-server-8.10.4: allocatestack.c:384: advise_stack_range: Assertion `freesize < size' failed.
[1]    194601 abort (core dumped)  haskell-language-server-8.10.4 --debug

Paste the logs from the lsp-client, e.g. for VS Code

LSP logs:
<paste your logs here>
@jneira jneira added type: bug Something isn't right: doesn't work as intended, documentation is missing/outdated, etc.. type: setup labels Mar 17, 2021
@michaelpj
Copy link
Collaborator

Duplicate, I think: #481

@jneira
Copy link
Member

jneira commented Mar 17, 2021

mmm i think that one only was reproduced using stack but no cabal 🤔

@dcastro
Copy link
Author

dcastro commented Mar 18, 2021

Yup, if I change my hie.yaml to this, HLS still displays the same working dir:

cradle:
  cabal:
    - path: "./code/first/src"
      component: "lib:first"

    - path: "./code/second/src"
      component: "lib:second"

I also tried stack repl and cabal repl. While stack repl indeed shows the wrong path (as pointed out in #481), cabal repl seems to behave correctly:

$ cabal repl lib:first
...
src/Main.hs:8:3: error:
    /home/dc/dev/other/hls-working-dir/code/first
  |
8 | $(runIO getCurrentDirectory >>= fail)
  |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

$ stack repl first:lib
...

/home/dc/dev/other/hls-working-dir/code/first/src/Main.hs:8:3: error:
    /home/dc/dev/other/hls-working-dir
  |
8 | $(runIO getCurrentDirectory >>= fail)
  |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

@michaelpj
Copy link
Collaborator

Yeah, I vaguely remember it being an issue that cabal and stack don't even agree on this.

@fendor
Copy link
Collaborator

fendor commented Mar 18, 2021

I think I remember having similar problem with hie-bios itself, stack does not cd into the relative directory while cabal does. No idea though why it works with stack build then.

@Vlix
Copy link

Vlix commented Apr 7, 2021

Using makeRelativeToProject will at least make it consistent between stack and cabal.
Not sure what the goal was outside of this minimal reproduction?

@dcastro
Copy link
Author

dcastro commented Apr 7, 2021

@Vlix Yup, ended up using makeRelativeToProject, thanks to @jneira's comment on #481 :) Thanks, it worked wonders!

@mpickering
Copy link
Contributor

I don't see that there is a realistic prospect of "fixing" this within HLS because of the fundamental issue that setCurrentDirectory is not thread local, this makes it impossible to compile multiple packages in parallel whilst modifying their local directories as cabal-install would when building them individually.

We should instead off an API in template-haskell which allows the user to implement a non-hacky version of makeRelativeToProject.

@Ailrun Ailrun added status: blocked Not actionable, because blocked by upstream/GHC etc. and removed old_type: setup labels Jul 13, 2022
@michaelpj michaelpj added the multi-component Issues relating to multi-component support label Jan 11, 2024
@michaelpj
Copy link
Collaborator

I'm going to close this as wontfix, since I think we're not going to do anything here.

@michaelpj michaelpj closed this as not planned Won't fix, can't repro, duplicate, stale May 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
multi-component Issues relating to multi-component support status: blocked Not actionable, because blocked by upstream/GHC etc. type: bug Something isn't right: doesn't work as intended, documentation is missing/outdated, etc..
Projects
None yet
Development

No branches or pull requests

7 participants