Skip to content

Commit

Permalink
Remove "new-style" haskell_import and related code
Browse files Browse the repository at this point in the history
This mechanism was introduced in #442 and was meant to be a stepping
stone towards removing the special treatment of prebuilt dependencies.
It was plagued by performance problems related to Nix and never saw
adoption beyond this project's test suite. With the advent of
`stack_install` and `haskell_cabal_library`, we can finally get rid of
it.
  • Loading branch information
mboes committed May 22, 2019
1 parent b27dbc6 commit 6160824
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 343 deletions.
118 changes: 0 additions & 118 deletions haskell/import.bzl

This file was deleted.

225 changes: 0 additions & 225 deletions haskell/nixpkgs.bzl
Original file line number Diff line number Diff line change
@@ -1,235 +1,10 @@
"""Workspace rules (Nixpkgs)"""

load("@bazel_skylib//lib:dicts.bzl", "dicts")
load(
"@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl",
"nixpkgs_package",
)

def haskell_nixpkgs_package(
name,
attribute_path,
nix_file_deps = [],
repositories = {},
build_file_content = None,
build_file = None,
**kwargs):
"""Load a single haskell package.
The package is expected to be in the form of the packages generated by
`genBazelBuild.nix`
"""
repositories = dicts.add(
{"bazel_haskell_wrapper": "@io_tweag_rules_haskell//haskell:nix/default.nix"},
repositories,
)

nixpkgs_args = dict(
name = name,
attribute_path = attribute_path,
build_file_content = build_file_content,
nix_file_deps = nix_file_deps + ["@io_tweag_rules_haskell//haskell:nix/default.nix"],
repositories = repositories,
**kwargs
)

if build_file_content:
nixpkgs_args["build_file_content"] = build_file_content
elif build_file:
nixpkgs_args["build_file"] = build_file
else:
nixpkgs_args["build_file_content"] = """
package(default_visibility = ["//visibility:public"])
load("@io_tweag_rules_haskell//haskell:import.bzl", haskell_import_new = "haskell_import")
load(":BUILD.bzl", "targets")
targets()
"""

nixpkgs_package(
**nixpkgs_args
)

def _bundle_impl(repository_ctx):
build_file_content = """
package(default_visibility = ["//visibility:public"])
"""
for package in repository_ctx.attr.packages:
build_file_content += """
alias(
name = "{package}",
actual = "@{base_repo}-{package}//:pkg",
)
""".format(
package = package,
base_repo = repository_ctx.attr.base_repository,
)
repository_ctx.file("BUILD", build_file_content)

_bundle = repository_rule(
attrs = {
"packages": attr.string_list(),
"base_repository": attr.string(),
},
implementation = _bundle_impl,
)
"""
Generate an alias from `@base_repo//:package` to `@base_repo-package//:pkg` for
each one of the input package
"""

def haskell_nixpkgs_packages(name, base_attribute_path, packages, **kwargs):
"""Import a set of haskell packages from nixpkgs.
This takes as input the same arguments as
[nixpkgs_package](https://github.com/tweag/rules_nixpkgs#nixpkgs_package),
expecting the `attribute_path` to resolve to a set of haskell packages
(such as `haskellPackages` or `haskell.packages.ghc822`) preprocessed by
the `genBazelBuild` function. It also takes as input a list of packages to
import (which can be generated by the `gen_packages_list` function).
"""
for package in packages:
haskell_nixpkgs_package(
name = name + "-" + package,
attribute_path = base_attribute_path + "." + package,
**kwargs
)
_bundle(
name = name,
packages = packages,
base_repository = name,
)

def _is_nix_platform(repository_ctx):
return repository_ctx.which("nix-build") != None

def _gen_imports_impl(repository_ctx):
repository_ctx.file("BUILD", "")
extra_args_raw = ""
for foo, bar in repository_ctx.attr.extra_args.items():
extra_args_raw += foo + " = " + bar + ", "
bzl_file_content = """
load("{repo_name}", "packages")
load("@io_tweag_rules_haskell//haskell:nixpkgs.bzl", "haskell_nixpkgs_packages")
def import_packages(name):
haskell_nixpkgs_packages(
name = name,
packages = packages,
{extra_args_raw}
)
""".format(
repo_name = repository_ctx.attr.packages_list_file,
extra_args_raw = extra_args_raw,
)

# A dummy 'packages.bzl' file with a no-op 'import_packages()' on unsupported platforms
bzl_file_content_unsupported_platform = """
def import_packages(name):
return
"""
if _is_nix_platform(repository_ctx):
repository_ctx.file("packages.bzl", bzl_file_content)
else:
repository_ctx.file("packages.bzl", bzl_file_content_unsupported_platform)

_gen_imports_str = repository_rule(
implementation = _gen_imports_impl,
attrs = dict(
packages_list_file = attr.label(doc = "A list containing the list of packages to import"),
# We pass the extra arguments to `haskell_nixpkgs_packages` as strings
# since we can't forward arbitrary arguments in a rule and they will be
# converted to strings anyways.
extra_args = attr.string_dict(doc = "Extra arguments for `haskell_nixpkgs_packages`"),
),
)
"""
Generate a repository containing a file `packages.bzl` which imports the given
packages list.
"""

def _gen_imports(name, packages_list_file, extra_args):
"""
A wrapper around `_gen_imports_str` which allows passing an arbitrary set of
`extra_args` instead of a set of strings
"""
extra_args_str = {label: repr(value) for (label, value) in extra_args.items()}
_gen_imports_str(
name = name,
packages_list_file = packages_list_file,
extra_args = extra_args_str,
)

def haskell_nixpkgs_packageset(name, base_attribute_path, repositories = {}, **kwargs):
"""Import all the available haskell packages.
The arguments are the same as the arguments of ``nixpkgs_package``, except
for the ``base_attribute_path`` which should point to an `haskellPackages`
set in the nix expression
Example:
In `haskellPackages.nix`:
```nix
with import <nixpkgs> {};
let wrapPackages = callPackage <bazel_haskell_wrapper> { }; in
{ haskellPackages = wrapPackages haskell.packages.ghc822; }
```
In your `WORKSPACE`
```bazel
# Define a nix repository to fetch the packages from
load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl",
"nixpkgs_git_repository")
nixpkgs_git_repository(
name = "nixpkgs",
revision = "9a787af6bc75a19ac9f02077ade58ddc248e674a",
)
load("@io_tweag_rules_haskell//haskell:nixpkgs.bzl",
"haskell_nixpkgs_packageset",
# Generate a list of all the available haskell packages
haskell_nixpkgs_packageset(
name = "hackage-packages",
repositories = {"@nixpkgs": "nixpkgs"},
nix_file = "//haskellPackages.nix",
base_attribute_path = "haskellPackages",
)
load("@hackage-packages//:packages.bzl", "import_packages")
import_packages(name = "hackage")
```
Then in your `BUILD` files, you can access to the whole of hackage as
`@hackage//:{your-package-name}`
"""

repositories = dicts.add(
{"bazel_haskell_wrapper": "@io_tweag_rules_haskell//haskell:nix/default.nix"},
repositories,
)

nixpkgs_package(
name = name + "-packages-list",
attribute_path = base_attribute_path + ".packageNames",
repositories = repositories,
build_file_content = """
exports_files(["all-haskell-packages.bzl"])
""",
fail_not_supported = False,
**kwargs
)
_gen_imports(
name = name,
packages_list_file = "@" + name + "-packages-list//:all-haskell-packages.bzl",
extra_args = dict(
repositories = repositories,
base_attribute_path = base_attribute_path,
**kwargs
),
)

def _ghc_nixpkgs_haskell_toolchain_impl(repository_ctx):
compiler_flags_select = "select({})".format(
repository_ctx.attr.compiler_flags_select or {
Expand Down

0 comments on commit 6160824

Please sign in to comment.