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

Rewrite the cabal wrapper in python #1097

Merged
merged 14 commits into from Oct 23, 2019
Merged

Conversation

thufschmitt
Copy link
Member

Solves #1096 by not needing access to the standard unix tools
(and also make it easier to maintain)

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.

This really makes the code a lot easier to read, great idea.

I compared the old and new file side-by-side and noted a few things that I couldn’t see in the new version.

For review it’s easier to have a 1:1 rewrite in the first commit and then simplifications in further commits. This was still fine, but for more complex rewrites that’s an important thing to keep in mind.

Anyway, a few things:

haskell/private/cabal_wrapper.py.tpl Show resolved Hide resolved
haskell/cabal.bzl Show resolved Hide resolved
haskell/private/cabal_wrapper.sh.tpl Show resolved Hide resolved
haskell/private/cabal_wrapper.py.tpl Show resolved Hide resolved
ghc_pkg = os.path.join(execroot, "%{ghc_pkg}")

extra_args = []
current_arg = sys.argv.pop(1)
Copy link
Contributor

Choose a reason for hiding this comment

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

All the argv-modifying code should really be in one block, like in the original script.

Copy link
Member Author

Choose a reason for hiding this comment

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

It wasn't in the original script, which is why I left it that way

Copy link
Contributor

Choose a reason for hiding this comment

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

It appeared to me like it was though. Maybe I missed something.
Would make the logic a lot easier to follow.

haskell/private/cabal_wrapper.py.tpl Show resolved Hide resolved
haskell/private/cabal_wrapper.py.tpl Outdated Show resolved Hide resolved
haskell/private/cabal_wrapper.py.tpl Outdated Show resolved Hide resolved
haskell/private/cabal_wrapper.py.tpl Show resolved Hide resolved
haskell/private/cabal_wrapper.py.tpl Show resolved Hide resolved
@thufschmitt
Copy link
Member Author

For review it’s easier to have a 1:1 rewrite in the first commit and then simplifications in further commits. This was still fine, but for more complex rewrites that’s an important thing to keep in mind.

Well that's what I did as much as it was reasonable to do: There were quite a number of bashisms in the original script that didn't really translated to python or too painfully for what it's worth. But apart from that I kept the structure as identical as possible.

Anyways, I should have answered your other comments, PTAL

@thufschmitt
Copy link
Member Author

The bindist failure is a bit mysterious to me. If someone has an idea of why bazel can't find python at that point I'm all ears

@@ -97,6 +106,7 @@ stack_snapshot(
snapshot = "lts-14.0",
vendored_packages = {"split": "@split//:split"},
deps = ["@zlib.dev//:zlib"],
tools = [ "@stdenv//:bin/{}".format(tool) for tool in ["sh", "grep", "sed", "awk"]],
Copy link
Member

Choose a reason for hiding this comment

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

It's going to be quite a cost for all Nixpkgs users if they have to specify this any time they use stack_snapshot. What's the reason for this and are there no alternatives?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes I agree, I've included this out of despair, but I'd really like another solution. The issue is that some cabal packages need these tools at build time (the ones with a configure script), but afaik there's no clean way of getting them in bazel (It really sucks that there's no "bash" toolchain 😕 ).

Outside of NixOS, these tools are incidentally put into the PATH by

base_path = subprocess.check_output(["/bin/sh", "-c", "echo $PATH"], env={}).strip().decode()
, but that's an awful hack that doesn't work on NixOS.

If you know any way of giving the rule access to a standard bash environment, I'm all ears

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.

Mostly good from my side'

@aherrmann
Copy link
Member

@regnat @Profpatsch Regarding the problem of missing shell utils in ./configure style packages:

Using /bin/sh -c "echo $PATH" is a nice trick, but it fails on NixOS, because the default PATH is empty, and fails on Windows, because /bin/sh does not exist. On Windows we might be able to work around this using @bazel_tools//tools/sh:toolchain_type to find the shell. However, on Nix that still fails due to empty PATH.

Another approach would be a shell utils toolchain. Sadly there's no standard toolchain for this. I gave it a shot to create one here. The toolchain captures standard Unix tools and creates a PATH that is passed into the Cabal wrapper template here and appended to the PATH environment variable here.

Currently, the toolchain just plucks those tools out of PATH in a repository rule, but it should be straight forward to create a rules_nixpkgs variant. Another issue with this is Cabal might discover cc and similar from this new PATH, so we'll have to explicitly tell Cabal to use the cc_toolchain cc.

Otherwise, this seems to be working. Windows passes, and the missing Unix tools issue is solved on nixpkgs. Darwin fails because we're not pointing to the cc_toolchain.

Let me know what you think of that approach.

@thufschmitt
Copy link
Member Author

Let me know what you think of that approach.

That definitely looks like the right approach, although it's a shame that we have to implement this unix_toolchain ourselves

Another issue with this is Cabal might discover cc and similar from this new PATH, so we'll have to explicitly tell Cabal to use the cc_toolchain cc

Wasn't it already the case with use_default_shell_env ?

@aherrmann
Copy link
Member

Let me know what you think of that approach.

That definitely looks like the right approach, although it's a shame that we have to implement this unix_toolchain ourselves

Indeed, maybe it could be factored out at some point and made reusable.

Another issue with this is Cabal might discover cc and similar from this new PATH, so we'll have to explicitly tell Cabal to use the cc_toolchain cc

Wasn't it already the case with use_default_shell_env ?

Good point, in principle yes. I think it didn't cause failures so far because it kept picking a compatible compiler. E.g. with use_default_shell_env under nix-shell we were getting the default PATH defined in the Nix expression, which includes a Nix provided gcc.

@Profpatsch
Copy link
Contributor

@regnat should we add @aherrmann’s proposal to this, I guess once that is done we can merge.

@aherrmann
Copy link
Member

@Profpatsch @regnat I have the nixpkgs integration of that unix toolchain almost ready. I'll ping here when it's up.

@aherrmann
Copy link
Member

@regnat As discussed, I've rebased this PR on #1117 and fixed a few small issues. It should be green on CI now (see https://github.com/tweag/rules_haskell/commits/cabal_python). PTAL

Copy link
Member Author

@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 can't approve because I'm the original author, but 👍

haskell/cabal.bzl Show resolved Hide resolved
Copy link
Member

@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.

Great! I can approve, but I added a bunch of changes myself. So, I think it would be good to have another pair of eyes on this. Maybe @Profpatsch

@mboes mboes added the merge-queue merge on green CI label Oct 23, 2019
thufschmitt and others added 7 commits October 23, 2019 12:56
Solves #1096 by not needing access to the standard unix tools
(and also make it easier to maintain)
- Rewrite the script to be compatible with python2
- Add a big hack to get back a "standard" path so that the wrapper
  scripts for ghc still work
network has a configure phase and expects some base unix tools to be
available
@mergify mergify bot merged commit e6b2e2b into master Oct 23, 2019
@mergify mergify bot deleted the cabal_wrapper_no_default_env branch October 23, 2019 13:38
@mergify mergify bot removed the merge-queue merge on green CI label Oct 23, 2019
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.

None yet

4 participants