From 30cfc63ae0ff47bf632201e7b8979b95d6d6161c Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Sun, 19 May 2019 23:13:34 +0200 Subject: [PATCH] Remove "new-style" haskell_import and related code 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. --- haskell/import.bzl | 118 ----------------------- haskell/nixpkgs.bzl | 225 -------------------------------------------- 2 files changed, 343 deletions(-) delete mode 100644 haskell/import.bzl diff --git a/haskell/import.bzl b/haskell/import.bzl deleted file mode 100644 index a79a9cff7..000000000 --- a/haskell/import.bzl +++ /dev/null @@ -1,118 +0,0 @@ -"""Importing prebuilt packages into bazel""" - -load("@bazel_skylib//lib:paths.bzl", "paths") -load( - "@io_tweag_rules_haskell//haskell:providers.bzl", - "HaddockInfo", - "HaskellInfo", - "HaskellLibraryInfo", - "empty_HaskellCcInfo", -) -load(":private/context.bzl", "haskell_context") -load(":private/path_utils.bzl", "copy_all", "link_forest", "ln") -load(":private/set.bzl", "set") -load(":private/version_macros.bzl", "generate_version_macros") - -def _haskell_import_impl(ctx): - hs = haskell_context(ctx) - - package_cache = ctx.actions.declare_file( - paths.join("package.conf.d", "package.cache"), - ) - - local_package_confs = link_forest( - ctx = ctx, - srcs = ctx.attr.package_confs.files, - sibling = package_cache, - ) - - local_haddock_html = ctx.actions.declare_directory("haddock-html") - copy_all( - ctx = ctx, - srcs = ctx.attr.haddock_html.files, - dest = local_haddock_html, - ) - - ctx.actions.run( - outputs = [package_cache], - inputs = local_package_confs, - mnemonic = "HaskellCreatePackageCache", - executable = hs.tools.ghc_pkg, - arguments = [ - "recache", - "--package-db", - package_cache.dirname, - ], - ) - ln(ctx, package_cache, ctx.outputs.cache) - - dependencies_caches = set.singleton(package_cache) - for dep in ctx.attr.deps: - if HaskellInfo in dep: - set.mutable_union(dependencies_caches, dep[HaskellInfo].package_databases) - - deps_ids = [ - dep[HaskellLibraryInfo].package_id - for dep in ctx.attr.deps - if HaskellLibraryInfo in dep - ] - - version_macros = set.empty() - if ctx.attr.version != None: - version_macros = set.singleton( - generate_version_macros(ctx, hs.name, ctx.attr.version), - ) - - libInfo = HaskellLibraryInfo( - package_id = ctx.attr.package_id, - version = ctx.attr.version, - ) - buildInfo = HaskellInfo( - package_ids = set.from_list([ctx.attr.package_id] + deps_ids), - package_databases = dependencies_caches, - version_macros = version_macros, - import_dirs = [], - source_files = set.empty(), - extra_source_files = set.empty(), - static_libraries = [], - static_libraries_prof = [], - dynamic_libraries = set.empty(), - interface_dirs = set.empty(), - compile_flags = [], - prebuilt_dependencies = set.empty(), - direct_prebuilt_deps = set.empty(), - cc_dependencies = empty_HaskellCcInfo(), - transitive_cc_dependencies = empty_HaskellCcInfo(), - ) - html_files = ctx.attr.haddock_html.files.to_list() - transitive_html = {ctx.attr.package_id: local_haddock_html} if html_files != [] else {} - interface_files = ctx.attr.haddock_interfaces.files.to_list() - transitive_haddocks = {ctx.attr.package_id: interface_files[0]} if interface_files != [] else {} - - haddockInfo = HaddockInfo( - package_id = ctx.attr.package_id, - transitive_html = transitive_html, - transitive_haddocks = transitive_haddocks, - ) - return [buildInfo, libInfo, haddockInfo] - -haskell_import = rule( - _haskell_import_impl, - attrs = dict( - package_id = attr.string(doc = "Workspace unique package identifier"), - deps = attr.label_list(doc = "Haskell dependencies for the package"), - version = attr.string(doc = "Package version."), - haddock_interfaces = attr.label(doc = "List of haddock interfaces"), - haddock_html = attr.label(doc = "List of haddock html dirs"), - package_confs = attr.label(doc = "List of ghc-pkg package.conf files"), - _version_macros = attr.label( - executable = True, - cfg = "host", - default = Label("@io_tweag_rules_haskell//haskell:version_macros"), - ), - ), - outputs = { - "cache": "%{name}-cache", - }, - toolchains = ["@io_tweag_rules_haskell//haskell:toolchain"], -) diff --git a/haskell/nixpkgs.bzl b/haskell/nixpkgs.bzl index bb505de39..23b350b27 100644 --- a/haskell/nixpkgs.bzl +++ b/haskell/nixpkgs.bzl @@ -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 {}; - - let wrapPackages = callPackage { }; 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 {