feat(third_party/bazel): Check in rules_haskell from Tweag

This commit is contained in:
Vincent Ambo 2019-07-04 11:18:12 +01:00
parent 2eb1dc26e4
commit f723b8b878
479 changed files with 51484 additions and 0 deletions

View file

@ -0,0 +1,322 @@
load(":inline_tests.bzl", "sh_inline_test")
load("@bazel_tools//tools/build_rules:test_rules.bzl", "rule_test")
load("//tests:rule_test_exe.bzl", "rule_test_exe")
load(
"@io_tweag_rules_haskell//haskell:c2hs.bzl",
"c2hs_toolchain",
)
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_binary",
"haskell_doctest_toolchain",
"haskell_proto_toolchain",
"haskell_test",
"haskell_toolchain",
)
load(
"//:constants.bzl",
"test_ghc_version",
)
package(default_testonly = 1)
haskell_doctest_toolchain(
name = "doctest-toolchain",
doctest = "@hackage-doctest//:bin",
tags = ["requires_doctest"],
)
# This toolchain is morally testonly. However, that would break our
# tests of haskell_library_rules: aspects of non-testonly
# proto_library rules (from com_google_protobuf) can't themselves be
# testonly.
haskell_proto_toolchain(
name = "protobuf-toolchain",
testonly = 0,
plugin = "@hackage-proto-lens-protoc//:bin/proto-lens-protoc",
protoc = "@com_google_protobuf//:protoc",
tags = ["requires_hackage"],
deps = [
"//tests/hackage:base",
"//tests/hackage:bytestring",
"//tests/hackage:containers",
"//tests/hackage:deepseq",
"//tests/hackage:mtl",
"//tests/hackage:text",
"@hackage//:data-default-class",
"@hackage//:lens-family",
"@hackage//:lens-family-core",
"@hackage//:lens-labels",
"@hackage//:proto-lens",
],
)
c2hs_toolchain(
name = "c2hs-toolchain",
c2hs = "@hackage-c2hs//:bin",
tags = ["requires_c2hs"],
)
rule_test_exe(
name = "test-binary-simple",
size = "small",
generates = ["binary-simple"],
rule = "//tests/binary-simple",
)
rule_test_exe(
name = "test-binary-custom-main",
size = "small",
generates = ["binary-custom-main"],
rule = "//tests/binary-custom-main",
)
rule_test(
name = "test-binary-with-lib",
size = "small",
generates = ["binary-with-lib"],
rule = "//tests/binary-with-lib",
)
rule_test(
name = "test-binary-with-prebuilt",
size = "small",
generates = ["binary-with-prebuilt"],
rule = "//tests/binary-with-prebuilt",
tags = ["requires_hackage"],
)
rule_test(
name = "test-binary-with-main",
size = "small",
generates = ["binary-with-main"],
rule = "//tests/binary-with-main",
)
rule_test(
name = "test-binary-with-sysdeps",
size = "small",
generates = ["binary-with-sysdeps"],
rule = "//tests/binary-with-sysdeps",
tags = ["requires_zlib"],
)
sh_test(
name = "test-binary-with-data",
size = "small",
srcs = ["//tests/binary-with-data"],
args = ["$(location //tests/binary-with-data:bin1)"],
data = ["//tests/binary-with-data:bin1"],
tags = ["requires_hackage"],
)
rule_test(
name = "test-library-deps",
size = "small",
generates = select({
"@bazel_tools//src/conditions:darwin": [
"libHStestsZSlibrary-depsZSlibrary-deps-ghc{}.dylib".format(test_ghc_version),
"libHStestsZSlibrary-depsZSlibrary-deps.a",
],
"@bazel_tools//src/conditions:windows": [
"libHStestsZSlibrary-depsZSlibrary-deps-ghc{}.dll".format(test_ghc_version),
"libHStestsZSlibrary-depsZSlibrary-deps.a",
],
"//conditions:default": [
"libHStestsZSlibrary-depsZSlibrary-deps-ghc{}.so".format(test_ghc_version),
"libHStestsZSlibrary-depsZSlibrary-deps.a",
],
}),
rule = "//tests/library-deps",
)
rule_test(
name = "test-hsc",
size = "small",
generates = ["hsc"],
rule = "//tests/hsc",
)
rule_test(
name = "test-haddock",
size = "small",
generates = [
"haddock/index",
"haddock/testsZShaddockZShaddock-lib-a",
"haddock/testsZShaddockZShaddock-lib-b",
"haddock/testsZShaddockZShaddock-lib-deep",
],
rule = "//tests/haddock",
tags = ["requires_hackage"],
)
rule_test(
name = "test-haskell_lint-library",
size = "small",
generates = [
"lint-log-lib-b",
],
rule = "//tests/haskell_lint:lint-lib-b",
)
rule_test(
name = "test-haskell_lint-binary",
size = "small",
generates = [
"lint-log-bin",
],
rule = "//tests/haskell_lint:lint-bin",
)
rule_test(
name = "test-haskell_doctest",
size = "small",
generates = [
"doctest-log-doctest-lib-lib-b",
],
rule = "//tests/haskell_doctest:doctest-lib",
tags = ["requires_doctest"],
)
rule_test(
name = "test-haskell_test",
size = "small",
generates = ["haskell_test"],
rule = "//tests/haskell_test:haskell_test",
)
rule_test(
name = "test-java_classpath",
size = "small",
generates = ["java_classpath"],
rule = "//tests/java_classpath",
)
rule_test(
name = "test-cc_haskell_import-cc-link",
size = "small",
generates = ["cc-bin"],
rule = "//tests/cc_haskell_import:cc-bin",
tags = ["requires_threaded_rts"],
)
sh_test(
name = "test-cc_haskell_import_python",
size = "small",
srcs = ["scripts/exec.sh"],
args = ["tests/cc_haskell_import/python_add_one"],
data = [
"//tests/cc_haskell_import:python_add_one",
"@bazel_tools//tools/bash/runfiles",
],
tags = ["requires_threaded_rts"],
)
sh_inline_test(
name = "test-haskell_binary-with-link-flags",
size = "small",
args = ["$(location //tests/binary-with-link-flags:binary-with-link-flags)"],
data = ["//tests/binary-with-link-flags"],
script = """\
set -e
# Fails if executable was linked without -threaded flag.
$1 +RTS -N
""",
)
rule_test(
name = "test-lhs",
size = "small",
generates = ["lhs-bin"],
rule = "//tests/lhs:lhs-bin",
)
rule_test(
name = "test-hs-boot",
size = "small",
generates = ["hs-boot"],
rule = "//tests/hs-boot:hs-boot",
)
rule_test(
name = "test-textual-hdrs",
size = "small",
generates = ["textual-hdrs"],
rule = "//tests/textual-hdrs:textual-hdrs",
)
rule_test(
name = "test-two-libs",
size = "small",
generates = ["two-libs"],
rule = "//tests/two-libs:two-libs",
)
genrule(
name = "run-bin-with-lib",
outs = ["dummy"],
cmd = """sh -c '
set -e
$(location //tests/binary-with-lib:binary-with-lib)
touch $(location dummy)
'""",
tools = ["//tests/binary-with-lib"],
)
rule_test(
name = "test-run-bin-with-lib",
size = "small",
generates = ["dummy"],
rule = "//tests:run-bin-with-lib",
)
genrule(
name = "run-bin-with-lib-dynamic",
outs = ["dyn-dummy"],
cmd = """sh -c '
set -e
$(location //tests/binary-with-lib-dynamic:binary-with-lib-dynamic)
touch $(location dyn-dummy)
'""",
tools = ["//tests/binary-with-lib-dynamic"],
)
rule_test(
name = "test-run-bin-with-lib-dynamic",
size = "small",
generates = ["dyn-dummy"],
rule = "//tests:run-bin-with-lib-dynamic",
)
genrule(
name = "run-bin-with-c-lib",
outs = ["c-dummy"],
cmd = """sh -c '
set -e
$(location //tests/c-compiles)
touch $(location c-dummy)
'""",
tools = ["//tests/c-compiles"],
)
rule_test(
name = "test-run-bin-with-c-lib",
size = "small",
generates = ["c-dummy"],
rule = "//tests:run-bin-with-c-lib",
)
# This is the test runner
haskell_binary(
name = "run-tests",
srcs = ["RunTests.hs"],
tags = ["requires_hackage"],
deps = [
"//tests/hackage:base",
"//tests/hackage:process",
"@hackage//:hspec",
"@hackage//:hspec-core",
],
)

View file

@ -0,0 +1,155 @@
{-# OPTIONS -Wall #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE QuasiQuotes #-}
import Data.Foldable (for_)
import Data.List (isInfixOf, sort)
import System.Exit (ExitCode(..))
import qualified System.Process as Process
import Test.Hspec.Core.Spec (SpecM)
import Test.Hspec (hspec, it, describe, runIO, shouldSatisfy, expectationFailure)
main :: IO ()
main = hspec $ do
it "bazel lint" $ do
assertSuccess (bazel ["run", "//:buildifier"])
it "bazel test" $ do
assertSuccess (bazel ["test", "//...", "--build_tests_only"])
it "haddock links" $ do
-- Test haddock links
-- All haddock tests are stored inside //tests/haddock
-- Temporaries files appears inside /doc-.... outputs and are ignored
-- the copy / chmod is here to workaround the fact that
-- linkchecker is dropping privileges to "nobody" user if called
-- from root, which is the case on CI.
assertSuccess (safeShell
[ "bazel build --config=ci //tests/haddock/..."
, "pwd=$(pwd)"
, "cd $(mktemp -d)"
, "cp -r $pwd/bazel-ci-bin/tests/haddock ."
, "chmod -R o+r ."
, "linkchecker . --ignore-url=/doc-"
])
it "bazel test prof" $ do
assertSuccess (bazel ["test", "-c", "dbg", "//...", "--build_tests_only"])
describe "repl" $ do
it "for libraries" $ do
assertSuccess (bazel ["run", "//tests/repl-targets:hs-lib@repl", "--", "-ignore-dot-ghci", "-e", "show (foo 10) ++ bar ++ baz ++ gen"])
assertSuccess (bazel ["run", "//tests/repl-targets:hs-lib-bad@repl", "--", "-ignore-dot-ghci", "-e", "1 + 2"])
it "for binaries" $ do
assertSuccess (bazel ["run", "//tests/repl-targets:hs-bin@repl", "--", "-ignore-dot-ghci", "-e", ":main"])
assertSuccess (bazel ["run", "//tests/binary-indirect-cbits:binary-indirect-cbits@repl", "--", "-ignore-dot-ghci", "-e", ":main"])
-- Test `compiler_flags` from toolchain and rule for REPL
it "compiler flags" $ do
assertSuccess (bazel ["run", "//tests/repl-flags:compiler_flags@repl", "--", "-ignore-dot-ghci", "-e", ":main"])
-- Test `repl_ghci_args` from toolchain and rule for REPL
it "repl flags" $ do
assertSuccess (bazel ["run", "//tests/repl-flags:repl_flags@repl", "--", "-ignore-dot-ghci", "-e", "foo"])
describe "multi_repl" $ do
it "loads transitive library dependencies" $ do
let p' (stdout, _stderr) = lines stdout == ["tests/multi_repl/bc/src/BC/C.hs"]
outputSatisfy p' (bazel ["run", "//tests/multi_repl:c_only_repl", "--", "-ignore-dot-ghci", "-e", ":show targets"])
it "loads transitive source dependencies" $ do
let p' (stdout, _stderr) = sort (lines stdout) == ["tests/multi_repl/a/src/A/A.hs","tests/multi_repl/bc/src/BC/B.hs","tests/multi_repl/bc/src/BC/C.hs"]
outputSatisfy p' (bazel ["run", "//tests/multi_repl:c_multi_repl", "--", "-ignore-dot-ghci", "-e", ":show targets"])
it "startup script" $ do
assertSuccess (safeShell ["./tests/run-start-script.sh"])
describe "failures" $ do
all_failure_tests <- bazelQuery "kind(rule, //tests/failures/...) intersect attr('tags', 'manual', //tests/failures/...)"
for_ all_failure_tests $ \test -> do
it test $ do
assertFailure (bazel ["build", "test"])
-- Test that the repl still works if we shadow some Prelude functions
it "repl name shadowing" $ do
let p (stdout, stderr) = not $ any ("error" `isInfixOf`) [stdout, stderr]
outputSatisfy p (bazel ["run", "//tests/repl-name-conflicts:lib@repl", "--", "-ignore-dot-ghci", "-e", "stdin"])
it "bazel test examples" $ do
assertSuccess (bazel ["test", "@io_tweag_rules_haskell_examples//..."])
it "bazel test tutorial" $ do
assertSuccess (bazel ["test", "@io_tweag_rules_haskell_tutorial//..."])
-- * Bazel commands
-- | Returns a bazel command line suitable for CI
-- This should be called with the action as first item of the list. e.g 'bazel ["build", "//..."]'.
bazel :: [String] -> Process.CreateProcess
-- Note: --config=ci is intercalated between the action and the list
-- of arguments. It should appears after the action, but before any
-- @--@ following argument.
bazel (command:args) = Process.proc "bazel" (command:"--config=ci":args)
bazel [] = Process.proc "bazel" []
-- | Runs a bazel query and return the list of matching targets
bazelQuery :: String -> SpecM a [String]
bazelQuery q = lines <$> runIO (Process.readProcess "bazel" ["query", q] "")
-- * Action helpers
-- | Ensure that @(stdout, stderr)@ of the command satisfies a predicate
outputSatisfy
:: ((String, String) -> Bool)
-> Process.CreateProcess
-> IO ()
outputSatisfy predicate cmd = do
(exitCode, stdout, stderr) <- Process.readCreateProcessWithExitCode cmd ""
case exitCode of
ExitSuccess -> (stdout, stderr) `shouldSatisfy` predicate
ExitFailure _ -> expectationFailure (formatOutput exitCode stdout stderr)
-- | The command must success
assertSuccess :: Process.CreateProcess -> IO ()
assertSuccess = outputSatisfy (const True)
-- | The command must fail
assertFailure :: Process.CreateProcess -> IO ()
assertFailure cmd = do
(exitCode, stdout, stderr) <- Process.readCreateProcessWithExitCode cmd ""
case exitCode of
ExitFailure _ -> pure ()
ExitSuccess -> expectationFailure ("Unexpected success of a failure test with output:\n" ++ formatOutput exitCode stdout stderr)
-- | Execute in a sub shell the list of command
-- This will fail if any of the command in the list fail
safeShell :: [String] -> Process.CreateProcess
safeShell l = Process.shell (unlines ("set -e":l))
-- * Formatting helpers
formatOutput :: ExitCode -> String -> String -> String
formatOutput exitcode stdout stderr =
let
header = replicate 20 '-'
headerLarge = replicate 20 '='
in unlines [
headerLarge
, "Exit Code: " <> show exitcode
, headerLarge
, "Standard Output"
, header
, stdout
, headerLarge
, "Error Output"
, header
, stderr
, header]

View file

@ -0,0 +1,17 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
package(default_testonly = 1)
haskell_test(
name = "binary-custom-main",
srcs = ["Main.hs"],
expected_covered_expressions_percentage = 50,
tags = [
"coverage-compatible",
],
visibility = ["//visibility:public"],
deps = ["//tests/hackage:base"],
)

View file

@ -0,0 +1,4 @@
module Main (main) where
main :: IO ()
main = return ()

View file

@ -0,0 +1,14 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
package(default_testonly = 1)
haskell_test(
name = "binary-dynamic",
srcs = ["Main.hs"],
linkstatic = False,
visibility = ["//visibility:public"],
deps = ["//tests/hackage:base"],
)

View file

@ -0,0 +1,3 @@
module Main where
main = putStrLn "hello world"

View file

@ -0,0 +1,13 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
package(default_testonly = 1)
haskell_test(
name = "binary-exe-path",
srcs = ["Main.hs"],
visibility = ["//visibility:public"],
deps = ["//tests/hackage:base"],
)

View file

@ -0,0 +1,5 @@
module Main where
import System.Environment
main = getExecutablePath >>= putStrLn

View file

@ -0,0 +1,36 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_binary",
"haskell_library",
)
haskell_binary(
name = "binary-indirect-cbits",
srcs = ["Main.hs"],
linkstatic = False,
visibility = ["//visibility:public"],
deps = [
"//tests/hackage:base",
"//tests/library-with-cbits",
],
)
haskell_binary(
name = "binary-indirect-cbits-partially-static",
srcs = ["Main.hs"],
linkstatic = False,
deps = [
"//tests/hackage:base",
"//tests/library-with-cbits:library-with-cbits-static",
],
)
haskell_binary(
name = "binary-indirect-cbits-fully-static",
srcs = ["Main.hs"],
linkstatic = True,
deps = [
"//tests/hackage:base",
"//tests/library-with-cbits:library-with-cbits-static",
],
)

View file

@ -0,0 +1,5 @@
import AddOne
main :: IO ()
main = do
putStrLn $ show $ addOne 2

View file

@ -0,0 +1,5 @@
module Wrapper
( module AddOne
) where
import AddOne

View file

@ -0,0 +1,9 @@
module Wrapper2
( module AddOne
, addOne2
) where
import AddOne
import qualified Wrapper
addOne2 = Wrapper.addOne

View file

@ -0,0 +1,118 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
"haskell_test",
)
load("//tests:inline_tests.bzl", "sh_inline_test")
# test whether `linkstatic` works as expected
package(default_testonly = 1)
cc_library(
name = "c-lib",
srcs = ["c-lib.c"],
)
haskell_library(
name = "HsLib",
srcs = ["HsLib.hs"],
deps = [
"//tests/hackage:base",
],
)
haskell_test(
name = "binary-static",
srcs = ["Main.hs"],
linkstatic = True,
deps = [
":HsLib",
":c-lib",
"//tests/hackage:base",
],
)
haskell_test(
name = "binary-dynamic",
srcs = ["Main.hs"],
linkstatic = False,
deps = [
":HsLib",
":c-lib",
"//tests/hackage:base",
],
)
config_setting(
name = "debug_build",
values = {
"compilation_mode": "dbg",
},
)
# Ensure that linkstatic=True only links to static library targets.
sh_inline_test(
name = "test-binary-static-symbols",
size = "small",
args = [
"$(rootpath :binary-static)",
],
data = [
":binary-static",
],
script = """
set -eo pipefail
binary="$1"
# Symbols are prefixed with underscore on MacOS but not on Linux.
if nm -u "$binary" | grep -q "\<_\?value"; then
echo "C library dependency not linked statically: ${binary}"
exit 1
fi
if nm -u "$binary" | grep -q HsLib_value_closure; then
echo "Haskell library dependency not linked statically ${binary}"
exit 1
fi
""",
)
# Ensure that linkstatic=False only links to dynamic library targets.
sh_inline_test(
name = "test-binary-dynamic-symbols",
size = "small",
args = [
"$(rootpath :binary-dynamic)",
] + select({
":debug_build": ["dbg"],
"//conditions:default": ["rls"],
}),
data = [
":binary-dynamic",
],
script = """
set -eo pipefail
binary="$1"
mode="$2"
if [[ $mode = dbg ]]; then
# Skip test in debug builds. Debug mode forces static linking.
exit 0
fi
# Symbols are prefixed with underscore on MacOS but not on Linux.
if ! nm -u "$binary" | grep -q "\<_\?value"; then
echo "C library dependency not linked dynamically"
exit 1
fi
if ! nm -u "$binary" | grep -q HsLib_value_closure; then
echo "Haskell library dependency not linked dynamically"
exit 1
fi
""",
)
test_suite(
name = "binary-linkstatic-flag",
tests = [
":test-binary-dynamic-symbols",
":test-binary-static-symbols",
],
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,4 @@
module HsLib (value) where
value :: Int
value = 13

View file

@ -0,0 +1,9 @@
{-# LANGUAGE ForeignFunctionInterface #-}
module Main (main) where
import qualified HsLib
foreign import ccall "value" value :: Int
main = print $ HsLib.value + value

View file

@ -0,0 +1 @@
int value() { return 29; }

View file

@ -0,0 +1,15 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
package(default_testonly = 1)
haskell_test(
name = "binary-simple",
srcs = ["Main.hs"],
expected_covered_expressions_percentage = 100,
tags = ["coverage-compatible"],
visibility = ["//visibility:public"],
deps = ["//tests/hackage:base"],
)

View file

@ -0,0 +1,3 @@
module Main where
main = putStrLn "hello world"

View file

@ -0,0 +1,18 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
package(default_testonly = 1)
haskell_test(
name = "binary-with-compiler-flags",
srcs = ["Main.hs"],
# Flags that require -threaded, which we should get from the toolchain's
# compiler_flags. Include spaces to validate proper quoting:
compiler_flags = [
"-with-rtsopts=-N2 -qg -I0 -n2m -A128m",
"-XLambdaCase",
],
deps = ["//tests/hackage:base"],
)

View file

@ -0,0 +1,13 @@
-- Expects to pull -XStandaloneDeriving from the default compiler flags.
module Main (main) where
data Foo = Foo
deriving instance Show Foo
-- Expects -XLambdaCase to be passed via the 'compiler_flags' rule attribute.
dummyId :: Foo -> Foo
dummyId = \case
Foo -> Foo
main :: IO ()
main = print $ dummyId Foo

View file

@ -0,0 +1,31 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
package(default_testonly = 1)
# XXX: on Windows those tests need `--experimental_enable_runfiles` to succeed
# XXX: see: https://github.com/tweag/rules_haskell/issues/647#issuecomment-459001362
haskell_test(
name = "bin1",
srcs = ["bin1.hs"],
# Regular file input:
data = ["bin1-input"],
visibility = ["//visibility:public"],
deps = ["//tests/hackage:base"],
)
haskell_test(
name = "binary-with-data",
srcs = ["bin2.hs"],
args = ["$(location :bin1)"],
data = [":bin1"],
tags = ["requires_hackage"],
visibility = ["//visibility:public"],
deps = [
"//tests/hackage:base",
"//tests/hackage:process",
],
)

View file

@ -0,0 +1 @@
contents

View file

@ -0,0 +1,9 @@
module Main where
import Control.Monad (unless)
main :: IO ()
main = do
contents <- readFile "tests/binary-with-data/bin1-input"
unless (contents == "contents\n")
$ error $ "Incorrect input; got " ++ show contents

View file

@ -0,0 +1,8 @@
module Main where
import System.Process (callProcess)
import System.Environment (getArgs)
main = do
[arg] <- getArgs
callProcess arg []

View file

@ -0,0 +1,26 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
"haskell_test",
)
package(default_testonly = 1)
haskell_library(
name = "lib",
srcs = ["src/Lib.hs"],
deps = [
"//tests/hackage:base",
"//tests/hackage:transformers",
],
)
haskell_test(
name = "binary-with-import",
srcs = ["Main.hs"],
visibility = ["//visibility:public"],
deps = [
":lib",
"//tests/hackage:base",
],
)

View file

@ -0,0 +1,6 @@
module Main where
import Lib (printValue)
main :: IO ()
main = printValue

View file

@ -0,0 +1,13 @@
module Lib (printValue) where
import Control.Monad (void)
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Except (ExceptT, runExceptT)
getValue :: Monad m => ExceptT e m Int
getValue = pure 42
printValue :: IO ()
printValue = void $ runExceptT $ do
value <- getValue
lift $ print value

View file

@ -0,0 +1,27 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
"haskell_test",
)
package(default_testonly = 1)
haskell_library(
name = "hs-lib",
srcs = ["HsLib.hs"],
tags = ["requires_zlib"],
deps = [
"//tests/hackage:base",
"@zlib.dev//:zlib",
],
)
haskell_test(
name = "binary-with-indirect-sysdeps",
srcs = ["Main.hs"],
tags = ["requires_zlib"],
deps = [
":hs-lib",
"//tests/hackage:base",
],
)

View file

@ -0,0 +1,8 @@
module HsLib where
import Foreign.Ptr
import Foreign.C.Types
foreign import ccall crc32 :: CLong -> Ptr () -> CInt -> IO ()
test = crc32 0 nullPtr 0

View file

@ -0,0 +1,5 @@
module Main where
import HsLib (test)
main = test

View file

@ -0,0 +1,25 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
"haskell_test",
)
package(default_testonly = 1)
haskell_library(
name = "lib",
srcs = glob(["src/*.hs"]),
linkstatic = False,
src_strip_prefix = "src",
)
haskell_test(
name = "binary-with-lib-dynamic",
srcs = ["Main.hs"],
linkstatic = False,
visibility = ["//visibility:public"],
deps = [
":lib",
"//tests/hackage:base",
],
)

View file

@ -0,0 +1,7 @@
module Main where
import Control.Monad (unless)
import Lib (value)
main = unless (value == 42)
$ error $ "Incorrect lib value. Got " <> show value

View file

@ -0,0 +1,5 @@
{-# LANGUAGE NoImplicitPrelude #-}
module Lib (value) where
value = 42

View file

@ -0,0 +1,27 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
"haskell_test",
)
package(default_testonly = 1)
haskell_library(
name = "lib",
srcs = glob(["src/*.hs"]),
src_strip_prefix = "src",
deps = [
"//tests/hackage:template-haskell",
],
)
haskell_test(
name = "binary-with-lib",
srcs = ["Main.hs"],
visibility = ["//visibility:public"],
deps = [
":lib",
"//tests/hackage:base",
"//tests/hackage:template-haskell",
],
)

View file

@ -0,0 +1,11 @@
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Control.Monad (unless)
import Lib (value)
import Language.Haskell.TH
val = $(value)
main = unless (val == 42)
$ error $ "Incorrect lib value. Got " <> show val

View file

@ -0,0 +1,8 @@
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell #-}
module Lib (value) where
import Language.Haskell.TH
value = [|42|]

View file

@ -0,0 +1,17 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
package(
default_testonly = 1,
default_visibility = ["//visibility:public"],
)
haskell_test(
name = "binary-with-link-flags",
srcs = ["Main.hs"],
compiler_flags = ["-threaded"],
visibility = ["//visibility:public"],
deps = ["//tests/hackage:base"],
)

View file

@ -0,0 +1,3 @@
module Main where
main = return ()

View file

@ -0,0 +1,14 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
package(default_testonly = 1)
haskell_test(
name = "binary-with-main",
srcs = ["MainIsHere.hs"],
main_function = "MainIsHere.this",
visibility = ["//visibility:public"],
deps = ["//tests/hackage:base"],
)

View file

@ -0,0 +1,4 @@
module MainIsHere (this) where
this :: IO ()
this = return ()

View file

@ -0,0 +1,53 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"ghc_plugin",
"haskell_library",
"haskell_test",
"haskell_toolchain_library",
)
package(default_testonly = 1)
config_setting(
name = "debug_build",
values = {
"compilation_mode": "dbg",
},
)
haskell_toolchain_library(name = "base")
haskell_toolchain_library(name = "ghc")
haskell_toolchain_library(name = "process")
haskell_library(
name = "plugin-lib",
srcs = ["Plugin.hs"],
deps = [
":base",
":ghc",
":process",
],
)
ghc_plugin(
name = "plugin",
args = ["$(location //tests/binary-simple)"],
module = "Plugin",
tools = ["//tests/binary-simple"],
deps = [":plugin-lib"],
)
haskell_test(
name = "binary-with-plugin",
srcs = ["Main.hs"],
plugins = select({
# XXX If profiling is enabled, ignore the plugin because of
# https://gitlab.haskell.org/ghc/ghc/issues/14335.
":debug_build": [],
"//conditions:default": [":plugin"],
}),
visibility = ["//visibility:public"],
deps = [":base"],
)

View file

@ -0,0 +1,3 @@
module Main where
main = putStrLn "hello world"

View file

@ -0,0 +1,15 @@
module Plugin (plugin) where
import Control.Monad (when)
import GhcPlugins
import System.Process (readProcess)
plugin :: Plugin
plugin = defaultPlugin { installCoreToDos = install }
install :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo]
install [arg] todo = do
when ('$' `elem` arg) $
fail "Make variable not expanded."
_ <- liftIO $ readProcess arg [] ""
return todo

View file

@ -0,0 +1,19 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
package(default_testonly = 1)
haskell_test(
name = "binary-with-prebuilt",
srcs = ["Main.hs"],
tags = ["requires_hackage"],
visibility = ["//visibility:public"],
deps = [
"//tests/hackage:base",
"//tests/hackage:template-haskell",
"@hackage//:streaming",
"@hackage//:void",
],
)

View file

@ -0,0 +1,6 @@
module Main where
import Data.List ()
import Language.Haskell.TH ()
main = return ()

View file

@ -0,0 +1,17 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
package(default_testonly = 1)
haskell_test(
name = "binary-with-sysdeps",
srcs = ["Main.hs"],
tags = ["requires_zlib"],
visibility = ["//visibility:public"],
deps = [
"//tests/hackage:base",
"@zlib",
],
)

View file

@ -0,0 +1,8 @@
module Main where
import Foreign.Ptr
import Foreign.C.Types
foreign import ccall crc32 :: CLong -> Ptr () -> CInt -> IO ()
main = crc32 0 nullPtr 0

View file

@ -0,0 +1,15 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
)
package(default_testonly = 1)
haskell_library(
name = "foo",
srcs = ["Foo.hs"],
deps = [
"//tests/data:ourclibrary",
"//tests/hackage:base",
],
)

View file

@ -0,0 +1,4 @@
module Foo (foo) where
foo :: Int
foo = 5

View file

@ -0,0 +1,26 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
"haskell_test",
)
package(default_testonly = 1)
haskell_library(
name = "hs-lib",
srcs = ["Lib.hs"],
deps = [
"//tests/data:ourclibrary",
"//tests/hackage:base",
],
)
haskell_test(
name = "c-compiles",
srcs = ["Main.hs"],
visibility = ["//visibility:public"],
deps = [
":hs-lib",
"//tests/hackage:base",
],
)

View file

@ -0,0 +1,10 @@
{-# LANGUAGE ForeignFunctionInterface #-}
module Lib (ten) where
import Foreign.C.Types (CInt(..))
foreign import ccall "c_add_one"
c_add_one :: CInt -> CInt
ten :: Int
ten = fromIntegral (c_add_one 9)

View file

@ -0,0 +1,8 @@
module Main (main) where
import Control.Monad (unless)
import Lib (ten)
main :: IO ()
main = unless (ten == 10)
$ error $ "Incorrect lib value. Got " <> show ten

View file

@ -0,0 +1 @@
int add_five(int x) { return x + 5; }

View file

@ -0,0 +1,36 @@
load("@io_tweag_rules_haskell//haskell:c2hs.bzl", "c2hs_library")
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
)
package(default_testonly = 1)
c2hs_library(
name = "foo",
srcs = ["src/Foo/Foo.chs"],
src_strip_prefix = "src",
tags = [
"requires_c2hs",
"requires_zlib",
],
deps = ["@zlib.dev//:zlib"],
)
c2hs_library(
name = "bar",
srcs = ["Bar.chs"],
tags = ["requires_c2hs"],
deps = [":foo"],
)
haskell_library(
name = "c2hs",
srcs = [
":bar",
":foo",
"@c2hs_repo//:baz",
],
tags = ["requires_c2hs"],
deps = ["//tests/hackage:base"],
)

View file

@ -0,0 +1,6 @@
module Bar (bar) where
{#import Foo.Foo#}
bar :: Int
bar = 6

View file

@ -0,0 +1,10 @@
load("@io_tweag_rules_haskell//haskell:c2hs.bzl", "c2hs_library")
package(default_testonly = 1)
c2hs_library(
name = "baz",
srcs = ["Baz.chs"],
visibility = ["//visibility:public"],
deps = ["@zlib.dev//:zlib"],
)

View file

@ -0,0 +1,6 @@
module Baz (baz) where
#include <zlib.h>
baz :: Int
baz = {# sizeof gz_header_s #}

View file

@ -0,0 +1 @@
workspace(name = "c2hs_repo")

View file

@ -0,0 +1,6 @@
module Foo.Foo (foo) where
#include <zlib.h>
foo :: Int
foo = {# sizeof gz_header_s #}

View file

@ -0,0 +1,70 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
)
package(default_testonly = 1)
haskell_library(
name = "hs-lib-a",
srcs = ["LibA.hs"],
deps = [
"//tests/data:ourclibrary",
"//tests/hackage:base",
],
)
haskell_library(
name = "hs-lib-b",
srcs = ["LibB.hs"],
deps = [
":hs-lib-a",
"//tests/hackage:base",
],
)
cc_binary(
name = "cc-bin",
srcs = [
"main.c",
],
# TODO support linking with static haskell libraries.
linkstatic = False,
tags = ["requires_threaded_rts"],
visibility = ["//tests:__subpackages__"],
deps = [
":hs-lib-b",
"@ghc//:threaded-rts",
],
)
# We go one step further and use the Haskell library from above
# to build a static .so which is then loaded with a Python script
# and calls the Haskell function constructed from GHC C FFI.
# shared library which python will dlopen
cc_binary(
name = "hs-lib-b-wrapped.so",
linkshared = 1,
linkstatic = 0,
tags = ["requires_threaded_rts"],
visibility = ["//tests:__subpackages__"],
deps = [
":hs-lib-b",
"@ghc//:threaded-rts",
],
)
# just dlopens hb-lib-b-wrapped.so and prints it
py_binary(
name = "python_add_one",
srcs = ["python_add_one.py"],
data = [
":hs-lib-b-wrapped.so",
],
default_python_version = "PY3",
srcs_version = "PY3ONLY",
tags = ["requires_threaded_rts"],
visibility = ["//tests:__subpackages__"],
deps = ["@bazel_tools//tools/python/runfiles"],
)

View file

@ -0,0 +1,8 @@
module LibA (add_one) where
import Data.Int (Int32)
foreign import ccall "c_add_one" c_add_one' :: Int32 -> Int32
add_one :: Int32 -> Int32
add_one x = c_add_one' x

View file

@ -0,0 +1,9 @@
module LibB (add_one_hs) where
import LibA (add_one)
import Data.Int (Int32)
foreign export ccall add_one_hs :: Int32 -> IO Int32
add_one_hs :: Int32 -> IO Int32
add_one_hs x = pure $! add_one x + 0

View file

@ -0,0 +1,5 @@
#include <stdint.h>
int32_t c_add_one(int32_t x) {
return 1 + x;
}

View file

@ -0,0 +1,11 @@
#include <stdio.h>
#include "HsFFI.h"
extern HsInt32 add_one_hs(HsInt32 a0);
int main(int argc, char *argv[]) {
hs_init(&argc, &argv);
printf("Adding one to 5 through Haskell is %d\n", add_one_hs(5));
hs_exit();
return 0;
}

View file

@ -0,0 +1,18 @@
import os
import ctypes
from bazel_tools.tools.python.runfiles import runfiles
import subprocess
r = runfiles.Create()
path = r.Rlocation('io_tweag_rules_haskell/tests/cc_haskell_import/hs-lib-b-wrapped.so')
foreignlib = ctypes.cdll.LoadLibrary(path)
# ATTN: If you remove this print *statement* hs_init will segfault!
# If you use the python3 print *function*, it will segfault as well!
# TODO: wtf?
print foreignlib
foreignlib.hs_init()
assert(str(foreignlib.add_one_hs(1)) == "2")

View file

@ -0,0 +1,36 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
"haskell_test",
)
package(default_testonly = 1)
# empty library with package name "bytestring"
haskell_library(
name = "bytestring",
srcs = ["src/BS.hs"],
deps = ["//tests/hackage:base"],
)
# This depends on two packages "bytestring"
# There should be no CPP macro conflict
haskell_test(
name = "macro_conflict",
srcs = ["Main.hs"],
compiler_flags = [
"-XCPP",
"-Werror",
] + select({
# clang on darwin fails because of unused command line argument, it fails because of -Werror
"@bazel_tools//src/conditions:darwin": [
"-optP-Wno-unused-command-line-argument",
],
"//conditions:default": [],
}),
deps = [
":bytestring",
"//tests/hackage:base",
"//tests/hackage:bytestring",
],
)

View file

@ -0,0 +1,4 @@
import qualified Data.ByteString
import BS
main = putStrLn "hello"

View file

@ -0,0 +1 @@
module BS where

View file

@ -0,0 +1,15 @@
# Generic data files and targets that are used by multiple tests
cc_library(
name = "ourclibrary",
srcs = [":ourclibrary.c"],
linkstatic = False,
visibility = ["//visibility:public"],
)
cc_library(
name = "ourclibrary-static",
srcs = [":ourclibrary.c"],
linkstatic = True,
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,5 @@
#include <stdint.h>
int32_t c_add_one(int32_t x) {
return 1 + x;
}

View file

@ -0,0 +1,21 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
package(default_testonly = 1)
haskell_test(
name = "encoding",
srcs = [
"Main.hs",
"TH.hs",
],
extra_srcs = [
"unicode.txt",
],
deps = [
"//tests/hackage:base",
"//tests/hackage:template-haskell",
],
)

View file

@ -0,0 +1,8 @@
{-# LANGUAGE TemplateHaskell #-}
module Main (main) where
import TH
main :: IO ()
main = putStrLn $foo

View file

@ -0,0 +1,7 @@
module TH (foo) where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax (lift)
foo :: Q Exp
foo = runIO (readFile "tests/encoding/unicode.txt") >>= lift

View file

@ -0,0 +1 @@
Некоторый текст на русском.

View file

@ -0,0 +1,17 @@
# Tests correct linking of haskell packages that were created
# in a different bazel repository, e.g. with hazel.
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
)
haskell_test(
name = "external-haskell-repository",
srcs = ["Main.hs"],
visibility = ["//visibility:public"],
deps = [
"//tests/hackage:base",
"@haskell_package_repository_dummy//:library-with-cbits",
],
)

View file

@ -0,0 +1,6 @@
module Main where
import AddOne
import Control.Exception (assert)
main = assert (addOne 41 == 42) $ return ()

View file

@ -0,0 +1,64 @@
# This file constructs a dummy workspace to test
# haskell binaries that are included from outside repositories
# (because linking external repositories works differently).
# Repo-ception, in the sense that we build a WORKSPACE
# that references the workspaces already set up in the
# `rules_haskell` WORKSPACE.
def _haskell_package_repository_dummy_impl(rep_ctx):
rep_ctx.file(
"WORKSPACE",
executable = False,
content = """
repository(name={name})
register_toolchains(
"@io_tweag_rules_haskell//tests/:ghc"
)
""".format(name = rep_ctx.name),
)
# this mirrors tests/library-with-cbits
rep_ctx.file(
"BUILD",
executable = False,
content = """
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_toolchain",
"haskell_library",
)
load(
"@io_tweag_rules_haskell//:constants.bzl",
"test_ghc_version",
)
haskell_library(
name = "library-with-cbits",
srcs = ["AddOne.hs"],
deps = [
"@io_tweag_rules_haskell//tests/data:ourclibrary",
"@io_tweag_rules_haskell//tests/hackage:base",
],
linkstatic = False,
visibility = ["//visibility:public"],
)
""",
)
rep_ctx.file(
"AddOne.hs",
executable = False,
content = """
module AddOne where
foreign import ccall "c_add_one" addOne :: Int -> Int
""",
)
haskell_package_repository_dummy = repository_rule(
_haskell_package_repository_dummy_impl,
local = True,
)

View file

@ -0,0 +1,44 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
"haskell_test",
)
package(default_testonly = 1)
haskell_library(
name = "extra-source-files",
srcs = [
"Foo.hs",
"FooTH.hs",
],
# Test that the linker can also see the extra_srcs.
compiler_flags = ["-optl-Wl,@tests/extra-source-files/ld-options.txt"],
extra_srcs = [
"file.txt",
"ld-options.txt",
],
deps = [
"//tests/hackage:base",
"//tests/hackage:template-haskell",
],
)
haskell_test(
name = "extra-source-files-bin",
srcs = [
"Foo.hs",
"FooTH.hs",
"Main.hs",
],
# Test that the linker can also see the extra_srcs.
compiler_flags = ["-optl-Wl,@tests/extra-source-files/ld-options.txt"],
extra_srcs = [
"file.txt",
"ld-options.txt",
],
deps = [
"//tests/hackage:base",
"//tests/hackage:template-haskell",
],
)

View file

@ -0,0 +1,8 @@
{-# LANGUAGE TemplateHaskell #-}
module Foo (foo) where
import FooTH (embedFile)
foo :: String
foo = $(embedFile "tests/extra-source-files/file.txt") ++ "!"

View file

@ -0,0 +1,12 @@
{-# LANGUAGE TemplateHaskell #-}
module FooTH (embedFile) where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
embedFile :: FilePath -> Q Exp
embedFile path = do
str <- runIO (readFile path)
addDependentFile path
[| str |]

View file

@ -0,0 +1,4 @@
import Foo (foo)
main :: IO ()
main = putStrLn foo

View file

@ -0,0 +1 @@
And here we go

View file

@ -0,0 +1,66 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
)
package(default_testonly = 1)
haskell_library(
name = "lib-a",
srcs = ["LibA.hs"],
deps = ["//tests/hackage:base"],
)
haskell_library(
name = "lib-b",
srcs = ["LibB.hs"],
visibility = ["//visibility:private"],
deps = [
":lib-a",
"//tests/hackage:base",
],
)
# Targets that must FAIL. These are tagged as manual so that
#
# $ bazel build //...
#
# does not fail.
haskell_library(
# Should fail because it doesn't specify "base" explicitly.
name = "lib-cFailure",
srcs = ["LibC.hs"],
tags = ["manual"],
deps = [":lib-b"],
)
haskell_library(
name = "lib-c",
srcs = ["LibC.hs"],
deps = [
":lib-b",
"//tests/hackage:base",
],
)
haskell_library(
# Should fail because it doesn't specify "lib-a" explicitly.
name = "lib-dFailure",
srcs = ["LibD.hs"],
tags = ["manual"],
deps = [
":lib-b",
"//tests/hackage:base",
],
)
haskell_library(
name = "lib-d",
srcs = ["LibD.hs"],
deps = [
":lib-a",
":lib-b",
"//tests/hackage:base",
],
)

View file

@ -0,0 +1,4 @@
module LibA (thingA) where
thingA :: Int
thingA = 5

View file

@ -0,0 +1,6 @@
module LibB (thingB) where
import LibA (thingA)
thingB :: Int
thingB = thingA + 1

View file

@ -0,0 +1,6 @@
module LibC (thingC) where
import LibB (thingB)
thingC :: Int
thingC = thingB * 2

View file

@ -0,0 +1,7 @@
module LibD (thingD) where
import LibA (thingA)
import LibB (thingB)
thingD :: Int
thingD = thingA + thingB

View file

@ -0,0 +1,56 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
"haskell_test",
)
package(
default_testonly = 1,
default_visibility = ["//visibility:public"],
)
genrule(
name = "generate-genmodule",
outs = ["src/GenModule.hs"],
cmd = "printf 'module GenModule where\na = 1 :: Int' > $@",
)
haskell_library(
name = "GenModule",
srcs = [":generate-genmodule"],
src_strip_prefix = "src",
deps = ["//tests/hackage:base"],
)
genrule(
name = "generate-binmodule",
outs = ["src/BinModule.hs"],
cmd = "printf 'module BinModule where\nb = 2 :: Int' > $@",
output_to_bindir = 1,
)
haskell_library(
name = "BinModule",
srcs = [":generate-binmodule"],
src_strip_prefix = "src",
deps = ["//tests/hackage:base"],
)
genrule(
name = "generate-main",
outs = ["src/Main.hs"],
cmd = "printf 'module Main where\nimport GenModule\nimport BinModule\n" +
"main = print (a+b) :: IO ()' > $@",
)
haskell_test(
name = "generated-modules",
size = "small",
srcs = [":generate-main"],
src_strip_prefix = "src",
deps = [
":BinModule",
":GenModule",
"//tests/hackage:base",
],
)

View file

@ -0,0 +1,41 @@
{ pkgs ? import ../nixpkgs {}
# Whether we want to wrap the packages using <bazel_haskell_wrapper>.
# When this is called from inside bazel, we need to wrap the haskell package
# set using <bazel_haskell_wrapper>. Otherwise we don't need (and don't want)
# to.
, wrapPackages ? (builtins.tryEval <bazel_haskell_wrapper>).success
}:
with pkgs;
let haskellPackages = pkgs.haskell.packages.ghc864.override {
overrides = with pkgs.haskell.lib; self: super: rec {
libc = import ./haddock/libC.nix self pkgs;
};
};
genBazelBuild =
if wrapPackages
then callPackage <bazel_haskell_wrapper> {}
else (x: x);
in
{
ghc = haskellPackages.ghcWithPackages (p: with p; [
# haskell_proto_library inputs
bytestring
containers
data-default-class
lens-family
lens-labels
proto-lens
text
# test inputs
libc
# for test runner
hspec
]);
haskellPackages = genBazelBuild haskellPackages;
}

View file

@ -0,0 +1,3 @@
load("//tests/ghc:ghc.bzl", "ghc_help")
ghc_help(name = "ghc_help")

View file

@ -0,0 +1,19 @@
"""Runs ghc --help"""
hs_toolchain = "@io_tweag_rules_haskell//haskell:toolchain"
def _impl(ctx):
output = ctx.outputs.out
ghc = ctx.toolchains[hs_toolchain].tools.ghc
ctx.actions.run_shell(
inputs = [ghc],
outputs = [output],
progress_message = "Printing ghc help message",
command = "%s --help > %s" % (ghc.path, output.path),
)
ghc_help = rule(
implementation = _impl,
outputs = {"out": "out_file"},
toolchains = [hs_toolchain],
)

View file

@ -0,0 +1,34 @@
"""
Fetches GHC boot packages from GHC directly rather than from Nixpkgs
for better bindist support.
"""
package(default_visibility = [
"//tests:__subpackages__",
"@haskell_package_repository_dummy//:__subpackages__",
])
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_toolchain_library",
)
[
haskell_toolchain_library(name = name)
for name in [
"array",
"base",
"binary",
"bytestring",
"containers",
"deepseq",
"directory",
"filepath",
"mtl",
"template-haskell",
"transformers",
"ghc-prim",
"process",
"text",
]
]

View file

@ -0,0 +1,73 @@
load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_doc",
"haskell_library",
"haskell_toolchain_library",
)
package(
default_testonly = 1,
default_visibility = ["//visibility:public"],
)
haskell_library(
name = "haddock-lib-deep",
srcs = ["Deep.hsc"],
deps = ["//tests/hackage:base"],
)
haskell_library(
name = "haddock-lib-a",
srcs = [
"LibA.hs",
"LibA/A.hs",
"header.h",
],
compiler_flags = ["-I."],
deps = [
":haddock-lib-deep",
"//tests/hackage:base",
"//tests/hackage:template-haskell",
],
)
haskell_toolchain_library(
name = "haddock-lib-c",
package = "libc",
)
haskell_library(
name = "haddock-lib-b",
srcs = [
"LibB.hs",
"TH.hs",
],
extra_srcs = [
"unicode.txt",
],
tags = [
"requires_hackage",
"requires_zlib",
],
deps = [
":haddock-lib-a",
"//tests/hackage:base",
"//tests/hackage:template-haskell",
"@hackage//:libc",
"@zlib",
],
)
haskell_doc(
name = "haddock",
index_transitive_deps = False,
tags = ["requires_hackage"],
deps = [":haddock-lib-b"],
)
haskell_doc(
name = "haddock-transitive",
index_transitive_deps = True,
tags = ["requires_hackage"],
deps = [":haddock-lib-b"],
)

View file

@ -0,0 +1,11 @@
-- | "Deep" doc.
module Deep (deep_lib) where
-- | 'deep_lib' doc.
#if __GLASGOW_HASKELL__ >= 700
#ifndef _INTERNAL_HSC_DO_NOT_DEFINE_ME
deep_lib :: Int
deep_lib = 100
#endif
#endif

View file

@ -0,0 +1,19 @@
-- | "LibA" header
{-# LANGUAGE CPP #-}
{-# LANGUAGE TemplateHaskell #-}
#include "header.h"
module LibA where
import LibA.A (a)
import Deep (deep_lib)
-- | 'A' declaration.
data A =
-- | 'A' constructor.
A
-- | Doc for 'f' using 'a' and 'deep_lib'.
f :: Int
f = const $a deep_lib + MAGIC_NUMBER

View file

@ -0,0 +1,10 @@
-- | "LibA.A" header
{-# LANGUAGE TemplateHaskell #-}
module LibA.A where
import Language.Haskell.TH
-- | 'a' doc
a :: Q Exp
a = [| 5 |]

View file

@ -0,0 +1,21 @@
{-# LANGUAGE TemplateHaskell #-}
-- | "LibB" doc.
module LibB where
import LibA.A (a)
import LibA (f)
import LibC (mytype, LibCType)
import TH (foo)
-- | Doc for 'x' using 'f' and 'a' and 'Int'.
x :: Int
x = const f a
-- | This uses a type from an undocumented package
y :: LibCType
y = mytype
-- | A thing generated with TH.
z :: String
z = $foo

View file

@ -0,0 +1,7 @@
module TH (foo) where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax (lift)
foo :: Q Exp
foo = runIO (readFile "tests/haddock/unicode.txt") >>= lift

View file

@ -0,0 +1 @@
#define MAGIC_NUMBER 100

Some files were not shown because too many files have changed in this diff Show more