about summary refs log tree commit diff
path: root/third_party/bazel/rules_haskell/docs/haskell-use-cases.rst
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/bazel/rules_haskell/docs/haskell-use-cases.rst')
-rw-r--r--third_party/bazel/rules_haskell/docs/haskell-use-cases.rst283
1 files changed, 0 insertions, 283 deletions
diff --git a/third_party/bazel/rules_haskell/docs/haskell-use-cases.rst b/third_party/bazel/rules_haskell/docs/haskell-use-cases.rst
deleted file mode 100644
index a8c4340cf70f..000000000000
--- a/third_party/bazel/rules_haskell/docs/haskell-use-cases.rst
+++ /dev/null
@@ -1,283 +0,0 @@
-.. _use-cases:
-
-Common Haskell Build Use Cases
-==============================
-
-Picking a compiler
-------------------
-
-Unlike Bazel's native C++ rules, rules_haskell does not auto-detect
-a Haskell compiler toolchain from the environment. This is by design.
-We require that you declare a compiler to use in your ``WORKSPACE``
-file.
-
-There are two common sources for a compiler. One is to use the
-official binary distributions from `haskell.org`_. This is done using
-the `ghc_bindist`_ rule.
-
-The compiler can also be pulled from Nixpkgs_, a set of package
-definitions for the `Nix package manager`_. Pulling the compiler from
-Nixpkgs makes the build more hermetic, because the transitive closure
-of the compiler and all its dependencies is precisely defined in the
-``WORKSPACE`` file. Use `rules_nixpkgs`_ to do so (where ``X.Y.Z``
-stands for any recent release)::
-
-  load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-
-  http_archive(
-      name = "io_tweag_rules_nixpkgs",
-      strip_prefix = "rules_nixpkgs-X.Y.Z",
-      urls = ["https://github.com/tweag/rules_nixpkgs/archive/vX.Y.Z.tar.gz"],
-  )
-
-  load(
-      "@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl",
-      "nixpkgs_git_repository",
-      "nixpkgs_package"
-  )
-
-  nixpkgs_git_repository(
-      name = "nixpkgs",
-      revision = "18.09", # Any tag or commit hash
-  )
-
-  nixpkgs_package(
-      name = "ghc",
-      repositories = { "nixpkgs": "@nixpkgs//:default.nix" }
-      attribute_path = "haskell.compiler.ghc843", # Any compiler version
-      build_file = "@io_tweag_rules_haskell//haskell:ghc.BUILD",
-  )
-
-  register_toolchains("//:ghc")
-
-This workspace description specifies which Nixpkgs version to use,
-then exposes a Nixpkgs package containing the GHC compiler. The
-description assumes that there exists a ``BUILD`` file at the root of
-the repository that includes the following::
-
-  haskell_toolchain(
-    name = "ghc",
-    # Versions here and in WORKSPACE must match.
-    version = "8.4.3",
-    # Use binaries from @ghc//:bin to define //:ghc toolchain.
-    tools = ["@ghc//:bin"],
-  )
-
-.. _Bazel+Nix blog post: https://www.tweag.io/posts/2018-03-15-bazel-nix.html
-.. _Nix package manager: https://nixos.org/nix
-.. _Nixpkgs: https://nixos.org/nixpkgs/manual/
-.. _ghc_bindist: http://api.haskell.build/haskell/ghc_bindist.html#ghc_bindist
-.. _haskell.org: https://haskell.org
-.. _haskell_binary: http://api.haskell.build/haskell/haskell.html#haskell_binary
-.. _haskell_library: http://api.haskell.build/haskell/haskell.html#haskell_library
-.. _rules_nixpkgs: https://github.com/tweag/rules_nixpkgs
-
-Loading targets in a REPL
--------------------------
-
-Rebuilds are currently not incremental *within* a binary or library
-target (rebuilds are incremental across targets of course). Any change
-in any source file will trigger a rebuild of all source files listed
-in a target. In Bazel, it is conventional to decompose libraries into
-small units. In this way, libraries require less work to rebuild.
-Still, for interactive development full incrementality and fast
-recompilation times are crucial for a good developer experience. We
-recommend making all development REPL-driven for fast feedback when
-source files change.
-
-Every `haskell_binary`_ and every `haskell_library`_ target has an
-optional executable output that can be run to drop you into an
-interactive session. If the target's name is ``foo``, then the REPL
-output is called ``foo@repl``.
-
-Consider the following binary target::
-
-  haskell_binary(
-      name = "hello",
-      srcs = ["Main.hs", "Other.hs"],
-      deps = ["//lib:some_lib"],
-  )
-
-The target above also implicitly defines ``hello@repl``. You can call
-the REPL like this (requires Bazel 0.15 or later)::
-
-  $ bazel run //:hello@repl
-
-This works for any ``haskell_binary`` or ``haskell_library`` target.
-Modules of all libraries will be loaded in interpreted mode and can be
-reloaded using the ``:r`` GHCi command when source files change.
-
-Building code with Hackage dependencies (using Nix)
----------------------------------------------------
-
-Each Haskell library or binary needs a simple build description to
-tell Bazel what source files to use and what the dependencies are, if
-any. Packages on Hackage don't usually ship with `BUILD.bazel` files.
-So if your code depends on them, you either need to write a build
-description for each package, generate one (see next section), or
-decide not to use Bazel to build packages published on Hackage. This
-section documents one way to do the latter.
-
-Nix is a package manager. The set of package definitions is called
-Nixpkgs. This repository contains definitions for most actively
-maintained Cabal packages published on Hackage. Where these packages
-depend on system libraries like zlib, ncurses or libpng, Nixpkgs also
-contains package descriptions for those, and declares those as
-dependencies of the Cabal packages. Since these definitions already
-exist, we can reuse them instead of rewriting these definitions as
-build definitions in Bazel. See the `Bazel+Nix blog post`_ for a more
-detailed rationale.
-
-To use Nixpkgs in Bazel, we need `rules_nixpkgs`_. See `Picking
-a compiler`_ for how to import Nixpkgs rules into your workspace and
-how to use a compiler from Nixpkgs. To use Cabal packages from
-Nixpkgs, replace the compiler definition with the following::
-
-  nixpkgs_package(
-      name = "ghc",
-      repositories = { "nixpkgs": "@nixpkgs//:default.nix" },
-      nix_file = "//:ghc.nix",
-      build_file = "@io_tweag_rules_haskell//haskell:ghc.BUILD",
-  )
-
-This definition assumes a ``ghc.nix`` file at the root of the
-repository. In this file, you can use the Nix expression language to
-construct a compiler with all the packages you depend on in scope::
-
-  with (import <nixpkgs> {});
-
-  haskellPackages.ghcWithPackages (p: with p; [
-    containers
-    lens
-    text
-  ])
-
-Each package mentioned in ``ghc.nix`` can then be imported using
-`haskell_toolchain_library`_ in ``BUILD`` files.
-
-.. _haskell_toolchain_library: http://api.haskell.build/haskell/haskell.html#haskell_toolchain_library
-
-Building code with Hackage dependencies (using Hazel)
------------------------------------------------------
-
-.. todo::
-
-   Explain how to use Hazel instead of Nix
-
-Generating API documentation
-----------------------------
-
-The `haskell_doc`_ rule can be used to build API documentation for
-a given library (using Haddock). Building a target called
-``//my/pkg:mylib_docs`` would make the documentation available at
-``bazel-bin/my/pkg/mylib_docs/index/index.html``.
-
-Alternatively, you can use the
-``@io_tweag_rules_haskell//haskell:haskell.bzl%haskell_doc_aspect``
-aspect to ask Bazel from the command-line to build documentation for
-any given target (or indeed all targets), like in the following:
-
-.. code-block:: console
-
-  $ bazel build //my/pkg:mylib \
-      --aspects @io_tweag_rules_haskell//haskell:haskell.bzl%haskell_doc_aspect
-
-.. _haskell_doc: http://api.haskell.build/haskell/haddock.html#haskell_doc
-
-Linting your code
------------------
-
-The `haskell_lint`_ rule does not build code but runs the GHC
-typechecker on all listed dependencies. Warnings are treated as
-errors.
-
-Alternatively, you can directly check a target using
-
-.. code-block:: console
-
-  $ bazel build //my/haskell:target \
-      --aspects @io_tweag_rules_haskell//haskell:haskell.bzl%haskell_lint_aspect
-
-.. _haskell_lint: http://api.haskell.build/haskell/lint.html#haskell_lint
-
-Checking code coverage
-----------------------
-
-"Code coverage" is the name given to metrics that describe how much source 
-code is covered by a given test suite.  A specific code coverage metric 
-implemented here is expression coverage, or the number of expressions in 
-the source code that are explored when the tests are run.
-
-Haskell's ``ghc`` compiler has built-in support for code coverage analysis, 
-through the hpc_ tool. The Haskell rules allow the use of this tool to analyse 
-``haskell_library`` coverage by ``haskell_test`` rules. To do so, you have a 
-few options. You can add 
-``expected_covered_expressions_percentage=<some integer between 0 and 100>`` to
-the attributes of a ``haskell_test``, and if the expression coverage percentage
-is lower than this amount, the test will fail. Alternatively, you can add
-``expected_uncovered_expression_count=<some integer greater or equal to 0>`` to
-the attributes of a ``haskell_test``, and instead the test will fail if the
-number of uncovered expressions is greater than this amount. Finally, you could
-do both at once, and have both of these checks analyzed by the coverage runner.
-To see the coverage details of the test suite regardless of if the test passes
-or fails, add ``--test_output=all`` as a flag when invoking the test, and there 
-will be a report in the test output. You will only see the report if you
-required a certain level of expression coverage in the rule attributes.
-
-For example, your BUILD file might look like this: ::
-
-  haskell_library(
-    name = "lib",
-    srcs = ["Lib.hs"],
-    deps = [
-        "//tests/hackage:base",
-    ],
-  )
-
-  haskell_test(
-    name = "test",
-    srcs = ["Main.hs"],
-    deps = [
-        ":lib",
-        "//tests/hackage:base",
-    ],
-    expected_covered_expressions_percentage = 80,
-    expected_uncovered_expression_count = 10,
-  )
-
-And if you ran ``bazel coverage //somepackage:test --test_output=all``, you 
-might see a result like this: ::
-
-  INFO: From Testing //somepackage:test:
-  ==================== Test output for //somepackage:test:
-  Overall report
-  100% expressions used (9/9)
-  100% boolean coverage (0/0)
-      100% guards (0/0)
-      100% 'if' conditions (0/0)
-      100% qualifiers (0/0)
-  100% alternatives used (0/0)
-  100% local declarations used (0/0)
-  100% top-level declarations used (3/3)
-  =============================================================================
-
-Here, the test passes because it actually has 100% expression coverage and 0
-uncovered expressions, which is even better than we expected on both counts.
-
-There is an optional ``haskell_test`` attribute called
-``strict_coverage_analysis``, which is a boolean that changes the coverage
-analysis such that even having better coverage than expected fails the test.
-This can be used to enforce that developers must upgrade the expected test
-coverage when they improve it. On the other hand, it requires changing the
-expected coverage for almost any change.
-
-There a couple of notes regarding the coverage analysis functionality:
-
-- Coverage analysis currently is scoped to all source files and all
-  locally-built Haskell dependencies (both direct and transitive) for a given
-  test rule.
-- Coverage-enabled build and execution for ``haskell_test`` targets may take
-  longer than regular. However, this has not effected regular ``run`` /
-  ``build`` / ``test`` performance.
-
-.. _hpc: <http://hackage.haskell.org/package/hpc>