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

Usage with haskell-language-server #1560

Closed
aveltras opened this issue Jun 27, 2021 · 9 comments
Closed

Usage with haskell-language-server #1560

aveltras opened this issue Jun 27, 2021 · 9 comments

Comments

@aveltras
Copy link
Contributor

Hi,

I'm trying to get a basic project working with a combination of nix and bazel.
Source is available here: https://github.com/aveltras/haskell-bazel-nix/tree/0dbf04db0662dc3e782d34ac4efc1a71f03adc8f

The nix-shell is providing haskell-language-server binary matching GHC.
I'm using the configuration explained here: https://rules-haskell.readthedocs.io/en/latest/haskell-use-cases.html#configuring-ide-integration-with-ghcide

When running "haskell-language-server" in the repo for the first time, it reports "Completed (1 file worked, 0 files failed)" as expected (the one file being the Main.hs in backend directory.
The problem is that, once ran for the first time, bazel add 4 symlinks in the workspace which point to the cache directory in my user directory.
Running "haskell-language-server" then finds 2 hie.yaml (one at the root of my workspace and one by following newly added symlinks until it reaches "external/rules_haskell/hie.yaml" somewhere in bazel cache directory), the second one is obviously not wanted here as the "haskell-language-server" then reports errors for "rules_haskell" code on top of my workspace.

Does anyone have a workaround for this problem ?

@aherrmann
Copy link
Member

To clarify, is this only an issue when you invoke HLS on the command-line so that it tries to load all sources in the current tree, or is it also a problem when you use HLS in your IDE/editor?

It sounds like a good solution to this type of issue would be for HLS to be told to ignore certain paths. Perhaps HLS could be instructed to ignore this external/rules_haskell/hie.yaml using a multi-cradle setup with a none cradle. The README contains an example that could perhaps be adapted to your use-case:

cradle:
  multi:
    - path: "./src"
      config: { cradle: {cabal: {component: "lib:hie-bios"}} }
    - path: "./test"
      config: { cradle: {cabal: {component: "test:bios-tests"}} }
    - path: "./test/test-files"
      config: { cradle: { none: } }

Note the none cradle for ./test/test-files that instructs hie-bios and thereby HLS to not load that directory.

@aveltras
Copy link
Contributor Author

I tried using the None cradle already but it didn't seem to have any impact.
The issue is also present when using the editor as it warned me than it was watching more than 2000 files I think, which never happens on a normal usage.
I also tried telling bazel not to generate those symlinks but it seemed to have an adverse effect on the @repl targets.
https://github.com/aveltras/haskell-bazel-nix/blob/0dbf04db0662dc3e782d34ac4efc1a71f03adc8f/.bazelrc

I think the issue might be better suited for haskell-language-server or hie-bios repository since this is mostly related to hie workspace detection.

Feel free to close this, I'm however still interested in hearing workarounds from other users.

@aherrmann
Copy link
Member

I also tried telling bazel not to generate those symlinks but it seemed to have an adverse effect on the @repl targets.
https://github.com/aveltras/haskell-bazel-nix/blob/0dbf04db0662dc3e782d34ac4efc1a71f03adc8f/.bazelrc

Indeed, the ghci wrapper assumes that bazel-out exists to find generated files like .so files for library dependencies.

For the hie-bios files haskell_repl provides the hie_bios_path_prefix attribute that can be used to point hie-bios to alternative output paths. See #1531 and #1432. However, that doesn't help with the @repl targets.

A possible workaround for this specific issue: You could patch the offending file out when importing rules_haskell. I.e. something along the lines of

http_archive(
    name = "rules_haskell",
    ...
    patches = [":rules-haskell-remove-hie-yaml.patch"],
    patch_args = ["-p1"],
)

I think the issue might be better suited for haskell-language-server or hie-bios repository since this is mostly related to hie workspace detection.

Agreed, this is best fixed upstream, e.g. by providing some way to configure paths that should be ignored.

Feel free to close this, I'm however still interested in hearing workarounds from other users.

👍

@aveltras
Copy link
Contributor Author

aveltras commented Jun 28, 2021

Thanks for your pointer related to patching rules_haskell.
I've tried it and it seems to be working now.
I had to remove all haskell source files though, removing hie.yaml wasn't enough.
I've written the needed steps in the readme here: https://github.com/aveltras/haskell-bazel-nix/tree/c51c67090ad9d48e8d1a9158398aadd2982b92a6
Seems a bit heavy handed but it works.
Might be useful to others.

@aherrmann
Copy link
Member

I'm glad to hear that you found a workaround.

I had to remove all haskell source files though, removing hie.yaml wasn't enough.

Hmm, would removing the hie.yaml together with a none cradle work?

The rules_haskell tree contains some Haskell source files that are needed in certain use-cases, e.g. under tools. Removing all Haskell sources would break those use-cass.

@aveltras
Copy link
Contributor Author

Ok, I'll see if I can find something.
When only removing the rules_haskell hie.yaml, running "haskell-language-server" says it only finds the hie.yaml of my repository but then goes onto checking cradle for all haskell files in rules_haskell sources (in bazel cache directory in my home).
The none cradle didn't work.

@aveltras
Copy link
Contributor Author

I've opened haskell/hie-bios#299 but I think the problem might be related to the content of .hie-bios (depicted in the linked issue).

@aveltras
Copy link
Contributor Author

@aherrmann FWIW it seems to work now on our big repo by using the following files:

hie.yaml

cradle:
  bios:
    program: ".hie-bios"

.hie-bios

#!/usr/bin/env bash
set -euo pipefail

bazel build :repl --output_groups=hie_bios
ghci_args=$(cat $(bazel info bazel-genfiles)/repl@hie-bios)
ghci_args=$(echo "$ghci_args" | grep -v "k8-fastbuild")
ghci_args=$(echo "$ghci_args" | sed 's|bazel-out|'"$(bazel info output_path)"'|g')

echo -e "$ghci_args" > $HIE_BIOS_OUTPUT

We have a repl loading all targets from the project and use it for HLS too now.
Removing the mapped sources in the bazel directories seems to help having the language server not checking outside of project files.
Haven't used it in anger yet though so that might break at some point.

@aherrmann
Copy link
Member

@aveltras Thank you for the update. Right, so the sed command replaces references to the bazel-out convenience symlink by references to the output path. Could the hie_bios_path_prefix attribute to haskell_repl be useful to you for this purpose? It was introduced in #1531 to resolve a similar issue #1432. One limitation I see so far is that it is defined in a BUILD file where you don't know the output-path, yet. Perhaps the attribute could be extended to support location expansion and make variable expansion to supply generated paths like the output-path.

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