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

Multi target haskell_repl #736

Merged
merged 16 commits into from
Mar 20, 2019
Merged

Multi target haskell_repl #736

merged 16 commits into from
Mar 20, 2019

Conversation

aherrmann
Copy link
Member

@aherrmann aherrmann commented Mar 8, 2019

Closes #380

  • Adds a new rule haskell_repl which constructs a ghci wrapper that loads multiple targets by source.
    Example usage
    haskell_repl(
        name = "my-repl",
        # Collect all transitive Haskell dependencies from these targets.
        deps = [
            "//package-a:target-1",
            "//package-b:target-2",
        ],
        # Load targets by source that match these patterns.
        include = [
            "//package-a/...",
            "//packaga-b/...",
            "//common/...",
        ],
        # Don't load targets by source that match these patterns.
        exclude = [
            "//package-a/vendored/...",
        ],
    )
    
    • Packages which are not loaded by source, will be loaded as compiled packages using -package-id, -package-db flags.
    • Prebuilt package dependencies are always loaded as -package.
    • Packages from external workspaces are never loaded by source, i.e. always as compiled packages.
    • All packages loaded by source contribute their compiler_flags and repl_ghci_flags.
    • Sets the RUNFILES_DIR environment variable, so that code that requires runfiles can be tested in the REPL.
  • Modifies the pre-existing ghci_repl_wrapper.sh so it can be used for the multi target repl.

Now accepts transitive_cc_dependencies instead of build_info, so that it
can be used for the multi target REPL as well.
This variable was unused.
Before the GHCi wrapper located the ghci script relative to the working
directory, which was expected to be the workspace directory. This worked
fine for executing the `@repl` files using `bazel run` as these were
executed from the repository root and not from a dedicated exec root.

In case of a dedicated repl target this will no longer work, as the
target will be executed in its exec root. This change modifies the
wrapper to first change into the workspace directory, and to refer to
the ghci script relative to the exec root. The same is done for library
dependencies.
This allows users of the ghci wrapper to pass in additional environment
variables easily.
@aherrmann aherrmann changed the title WIP: Multi target haskell_repl Multi target haskell_repl Mar 12, 2019
@SebastianKG
Copy link
Contributor

Above is a problem I ran into when using this branch.

@aherrmann
Copy link
Member Author

@SebastianKG Thanks for testing this. That commit is out-of-date with this PR. Could you retry on the current state of this PR (branch workspace_repl) with the following commands?

$ nix-shell --pure --run 'bazel run //tests/multi_repl:c_only_repl'
$ nix-shell --pure --run 'bazel run //tests/multi_repl:c_multi_repl'

It's surprising that the :add command lists no source files. This PR includes tests which load the REPLs that pass on CI.

Loads all targets given in the deps attribute as well as all
dependencies in the local workspace as sources into GHCi.
@aherrmann
Copy link
Member Author

Noticed an issue with the generated package-db flags in the repl wrapper. Those were relative to execution directory instead of the execroot, which could lead to missing package dbs. I've fixed it by making those paths relative to the execroot.

Names such as `tmpDir` or `h` are likely to shadown names from loaded
modules, which will cause errors if `-Werror=name-shadowing` is active.
@SebastianKG
Copy link
Contributor

Awesome, I gave it another look, and your latest code seems to load the correct modules. Great work!

Copy link
Contributor

@Profpatsch Profpatsch left a comment

Choose a reason for hiding this comment

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

Impressive piece of code!

I am unsure about the include/exclude parsing though. It feels like we are leaving bazel here to do our own stuff, which is going to bite us because we can never implement exactly the same target logic that bazel implements.
If I remember correctly, there is a way to call bazel query from within bazel rules, via some builtin primitive. If its possible, we should use that at least. If not, we should open an upstream feature request describing our use-case and mark the attributes with an experimental- prefix for now (until we know whether there is going to be an upstream feature).

Regarding old-style @repl syntax, is this new way a superset of that? Then we could deprecate it.
There’s also haskell/private/actions/repl.bzl. Is that file used after this change or can we remove it?

haskell/repl.bzl Show resolved Hide resolved
haskell/repl.bzl Outdated Show resolved Hide resolved
haskell/repl.bzl Show resolved Hide resolved
haskell/repl.bzl Show resolved Hide resolved
haskell/repl.bzl Show resolved Hide resolved
haskell/repl.bzl Outdated Show resolved Hide resolved
haskell/repl.bzl Show resolved Hide resolved
haskell/repl.bzl Outdated Show resolved Hide resolved
haskell/repl.bzl Outdated Show resolved Hide resolved
haskell/repl.bzl Outdated Show resolved Hide resolved
Copy link
Member Author

@aherrmann aherrmann left a comment

Choose a reason for hiding this comment

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

@Profpatsch Thanks for the great comments. I've addressed them all PTAL.

haskell/repl.bzl Show resolved Hide resolved
haskell/repl.bzl Outdated Show resolved Hide resolved
haskell/repl.bzl Show resolved Hide resolved
haskell/repl.bzl Show resolved Hide resolved
haskell/repl.bzl Show resolved Hide resolved
haskell/repl.bzl Outdated Show resolved Hide resolved
haskell/repl.bzl Outdated Show resolved Hide resolved
haskell/repl.bzl Outdated Show resolved Hide resolved
haskell/repl.bzl Outdated Show resolved Hide resolved
haskell/repl.bzl Outdated Show resolved Hide resolved
thufschmitt pushed a commit that referenced this pull request Mar 19, 2019
More for demonstrations purposes than anything else because it's
superseded by #736
Copy link
Contributor

@thufschmitt thufschmitt left a comment

Choose a reason for hiding this comment

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

Awesome! 👍

(I'd like some of this to be merged with #757 at some point, but that's future work).

@@ -1,5 +1,6 @@
"""GHCi REPL support"""

load(":private/context.bzl", "render_env")
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it be possible to factor all this file out with the new haskell_repl rule?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not quite at the moment. haskell_repl is its own rule and can return a DefaultInto and thereby properly use runfiles. haskell/private/actions/repl.bzl creates an extra output in the regular haskell_* rules and cannot return a dedicated DefaultInfo with runfiles. Instead it has to use the ln trick to force it's dependencies and refer to them in bazel-out.

I agree that there is duplication that we don't want to keep around in the long term. One possible way forward could be to drop haskell/private/actions/repl.bzl completely and replace it by the haskell/repl.bzl aspect, similar to haskell/haddock.bzl. But, I'd prefer to do that in a separate PR.

haskell/repl.bzl Outdated Show resolved Hide resolved
haskell/repl.bzl Show resolved Hide resolved
Note, in some instances this adds static libraries to the link commands
that were previously filtered out. A corresponding comment stated that
GHCi cannot load static libraries. However, this is not true. GHCi can
load static PIC libraries.
@Profpatsch
Copy link
Contributor

Great, great work

@aherrmann aherrmann merged commit 16b27bb into master Mar 20, 2019
@aherrmann aherrmann deleted the workspace_repl branch March 20, 2019 12:28
thufschmitt pushed a commit that referenced this pull request Mar 20, 2019
More for demonstrations purposes than anything else because it's
superseded by #736
@thufschmitt thufschmitt mentioned this pull request Mar 20, 2019
4 tasks
@shmish111
Copy link
Contributor

Love it!

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.

5 participants