mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 09:17:43 +03:00
4fd1cf7c28
Haven’t tracked down when they broke. They used to work at some point but atm they are very broken and don’t test anything. This PR fixes the bash mess to parse the files correctly and fixes two minor issues that creeped in by virtue of the doctests being broken. changelog_begin changelog_end
416 lines
12 KiB
Python
416 lines
12 KiB
Python
# Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
load("@build_environment//:configuration.bzl", "ghc_version", "sdk_version")
|
|
load("//bazel_tools/sh:sh.bzl", "sh_inline_test")
|
|
|
|
_damlc = attr.label(
|
|
allow_single_file = True,
|
|
default = Label("//compiler/damlc:damlc-compile-only"),
|
|
executable = True,
|
|
cfg = "host",
|
|
doc = "The DAML compiler.",
|
|
)
|
|
|
|
_zipper = attr.label(
|
|
allow_single_file = True,
|
|
default = Label("@bazel_tools//tools/zip:zipper"),
|
|
executable = True,
|
|
cfg = "host",
|
|
)
|
|
|
|
ghc_opts = ["--ghc-option=-Werror"]
|
|
|
|
def _daml_configure_impl(ctx):
|
|
project_name = ctx.attr.project_name
|
|
project_version = ctx.attr.project_version
|
|
daml_yaml = ctx.outputs.daml_yaml
|
|
target = ctx.attr.target
|
|
opts = ghc_opts + ["--target={}".format(target)] if target else ghc_opts
|
|
ctx.actions.write(
|
|
output = daml_yaml,
|
|
content = """
|
|
sdk-version: {sdk}
|
|
name: {name}
|
|
version: {version}
|
|
source: .
|
|
dependencies: []
|
|
build-options: [{opts} ]
|
|
""".format(
|
|
sdk = sdk_version,
|
|
name = project_name,
|
|
version = project_version,
|
|
opts = ", ".join(opts),
|
|
),
|
|
)
|
|
|
|
_daml_configure = rule(
|
|
implementation = _daml_configure_impl,
|
|
attrs = {
|
|
"project_name": attr.string(
|
|
mandatory = True,
|
|
doc = "Name of the DAML project.",
|
|
),
|
|
"project_version": attr.string(
|
|
mandatory = True,
|
|
doc = "Version of the DAML project.",
|
|
),
|
|
"daml_yaml": attr.output(
|
|
mandatory = True,
|
|
doc = "The generated daml.yaml config file.",
|
|
),
|
|
"target": attr.string(
|
|
doc = "DAML-LF version to output.",
|
|
),
|
|
},
|
|
)
|
|
|
|
def file_of_target(k):
|
|
[file] = k.files.to_list()
|
|
return file
|
|
|
|
def make_cp_command(src, dest):
|
|
return "mkdir -p $(dirname {dest}); cp -f {src} {dest}".format(
|
|
src = src,
|
|
dest = dest,
|
|
)
|
|
|
|
def _daml_build_impl(ctx):
|
|
name = ctx.label.name
|
|
daml_yaml = ctx.file.daml_yaml
|
|
srcs = ctx.files.srcs
|
|
dar_dict = ctx.attr.dar_dict
|
|
damlc = ctx.file._damlc
|
|
input_dars = [file_of_target(k) for k in dar_dict.keys()]
|
|
output_dar = ctx.outputs.dar
|
|
posix = ctx.toolchains["@rules_sh//sh/posix:toolchain_type"]
|
|
ctx.actions.run_shell(
|
|
tools = [damlc],
|
|
inputs = [daml_yaml] + srcs + input_dars,
|
|
outputs = [output_dar],
|
|
progress_message = "Building DAML project %s" % name,
|
|
command = """
|
|
set -eou pipefail
|
|
tmpdir=$(mktemp -d)
|
|
trap "rm -rf $tmpdir" EXIT
|
|
cp -f {config} $tmpdir/daml.yaml
|
|
# Having to produce all the daml.yaml files via a genrule is annoying
|
|
# so we allow hardcoded version numbers and patch them here.
|
|
{sed} -i 's/^sdk-version:.*$/sdk-version: {sdk_version}/' $tmpdir/daml.yaml
|
|
{cp_srcs}
|
|
{cp_dars}
|
|
{damlc} build --project-root $tmpdir {ghc_opts} -o $PWD/{output_dar}
|
|
""".format(
|
|
config = daml_yaml.path,
|
|
cp_srcs = "\n".join([
|
|
make_cp_command(
|
|
src = src.path,
|
|
dest = "$tmpdir/" + src.path,
|
|
)
|
|
for src in srcs
|
|
]),
|
|
cp_dars = "\n".join([
|
|
make_cp_command(
|
|
src = file_of_target(k).path,
|
|
dest = "$tmpdir/" + v,
|
|
)
|
|
for k, v in dar_dict.items()
|
|
]),
|
|
sed = posix.commands["sed"],
|
|
damlc = damlc.path,
|
|
output_dar = output_dar.path,
|
|
sdk_version = sdk_version,
|
|
ghc_opts = " ".join(ghc_opts),
|
|
),
|
|
)
|
|
|
|
_daml_build = rule(
|
|
implementation = _daml_build_impl,
|
|
attrs = {
|
|
"daml_yaml": attr.label(
|
|
allow_single_file = True,
|
|
mandatory = True,
|
|
doc = "The daml.yaml config file.",
|
|
),
|
|
"srcs": attr.label_list(
|
|
allow_files = [".daml"],
|
|
mandatory = True,
|
|
doc = "DAML files in this DAML project.",
|
|
),
|
|
"dar_dict": attr.label_keyed_string_dict(
|
|
mandatory = True,
|
|
allow_files = True,
|
|
doc = "Other DAML projects referenced by this DAML project.",
|
|
),
|
|
"dar": attr.output(
|
|
mandatory = True,
|
|
doc = "The generated DAR file.",
|
|
),
|
|
"_damlc": _damlc,
|
|
},
|
|
toolchains = ["@rules_sh//sh/posix:toolchain_type"],
|
|
)
|
|
|
|
def _extract_main_dalf_impl(ctx):
|
|
project_name = ctx.attr.project_name
|
|
project_version = ctx.attr.project_version
|
|
input_dar = ctx.file.dar
|
|
output_dalf = ctx.outputs.dalf
|
|
zipper = ctx.file._zipper
|
|
posix = ctx.toolchains["@rules_sh//sh/posix:toolchain_type"]
|
|
ctx.actions.run_shell(
|
|
tools = [zipper],
|
|
inputs = [input_dar],
|
|
outputs = [output_dalf],
|
|
progress_message = "Extract DALF from DAR (%s)" % project_name,
|
|
command = """
|
|
set -eoux pipefail
|
|
TMPDIR=$(mktemp -d)
|
|
trap "rm -rf $TMPDIR" EXIT
|
|
# While zipper has a -d option, it insists on it
|
|
# being a relative path so we don't use it.
|
|
ZIPPER=$PWD/{zipper}
|
|
DAR=$PWD/{input_dar}
|
|
(cd $TMPDIR && $ZIPPER x $DAR)
|
|
main_dalf=$({find} $TMPDIR/ -name '{project_name}-{project_version}-[a-z0-9]*.dalf')
|
|
cp $main_dalf {output_dalf}
|
|
""".format(
|
|
zipper = zipper.path,
|
|
find = posix.commands["find"],
|
|
project_name = project_name,
|
|
project_version = project_version,
|
|
input_dar = input_dar.path,
|
|
output_dalf = output_dalf.path,
|
|
),
|
|
)
|
|
|
|
_extract_main_dalf = rule(
|
|
implementation = _extract_main_dalf_impl,
|
|
attrs = {
|
|
"project_name": attr.string(
|
|
mandatory = True,
|
|
doc = "Name of the DAML project.",
|
|
),
|
|
"project_version": attr.string(
|
|
mandatory = True,
|
|
doc = "Version of the DAML project.",
|
|
),
|
|
"dar": attr.label(
|
|
allow_single_file = [".dar"],
|
|
mandatory = True,
|
|
doc = "The DAR from which the DALF will be extracted.",
|
|
),
|
|
"dalf": attr.output(
|
|
mandatory = True,
|
|
doc = "The extracted DALF.",
|
|
),
|
|
"_zipper": _zipper,
|
|
},
|
|
toolchains = ["@rules_sh//sh/posix:toolchain_type"],
|
|
)
|
|
|
|
def _daml_validate_test(
|
|
name,
|
|
dar,
|
|
**kwargs):
|
|
damlc = "//compiler/damlc:damlc-compile-only"
|
|
sh_inline_test(
|
|
name = name,
|
|
data = [damlc, dar],
|
|
cmd = """\
|
|
DAMLC=$$(canonicalize_rlocation $(rootpath {damlc}))
|
|
|
|
$$DAMLC validate-dar $$(canonicalize_rlocation $(rootpath {dar}))
|
|
""".format(
|
|
damlc = damlc,
|
|
dar = dar,
|
|
),
|
|
**kwargs
|
|
)
|
|
|
|
def _inspect_dar(base):
|
|
name = base + "-inspect"
|
|
dar = base + ".dar"
|
|
pp = base + ".dar.pp"
|
|
native.genrule(
|
|
name = name,
|
|
srcs = [
|
|
dar,
|
|
"//compiler/damlc:damlc-compile-only",
|
|
],
|
|
outs = [pp],
|
|
cmd = "$(location //compiler/damlc:damlc-compile-only) inspect $(location :" + dar + ") > $@",
|
|
)
|
|
|
|
_default_project_version = "1.0.0"
|
|
|
|
def daml_compile(
|
|
name,
|
|
srcs,
|
|
version = _default_project_version,
|
|
target = None,
|
|
project_name = None,
|
|
**kwargs):
|
|
"Build a DAML project, with a generated daml.yaml."
|
|
if len(srcs) == 0:
|
|
fail("daml_compile: Expected `srcs' to be non-empty.")
|
|
daml_yaml = name + ".yaml"
|
|
_daml_configure(
|
|
name = name + ".configure",
|
|
project_name = project_name or name,
|
|
project_version = version,
|
|
daml_yaml = daml_yaml,
|
|
target = target,
|
|
**kwargs
|
|
)
|
|
_daml_build(
|
|
name = name + ".build",
|
|
daml_yaml = daml_yaml,
|
|
srcs = srcs,
|
|
dar_dict = {},
|
|
dar = name + ".dar",
|
|
**kwargs
|
|
)
|
|
_inspect_dar(
|
|
base = name,
|
|
)
|
|
|
|
def daml_compile_with_dalf(
|
|
name,
|
|
version = _default_project_version,
|
|
**kwargs):
|
|
"Build a DAML project, with a generated daml.yaml, and extract the main DALF."
|
|
daml_compile(
|
|
name = name,
|
|
version = version,
|
|
**kwargs
|
|
)
|
|
_extract_main_dalf(
|
|
name = name + ".extract",
|
|
project_name = name,
|
|
project_version = version,
|
|
dar = name + ".dar",
|
|
dalf = name + ".dalf",
|
|
)
|
|
|
|
def daml_build_test(
|
|
name,
|
|
project_dir,
|
|
daml_config_basename = "daml.yaml",
|
|
daml_subdir_basename = "daml",
|
|
daml_yaml = None,
|
|
dar_dict = {},
|
|
**kwargs):
|
|
"Build a DAML project and validate the resulting .dar file."
|
|
if not daml_yaml:
|
|
daml_yaml = project_dir + "/" + daml_config_basename
|
|
srcs = native.glob([project_dir + "/" + daml_subdir_basename + "/**/*.daml"])
|
|
_daml_build(
|
|
name = name,
|
|
daml_yaml = daml_yaml,
|
|
srcs = srcs,
|
|
dar_dict = dar_dict,
|
|
dar = name + ".dar",
|
|
**kwargs
|
|
)
|
|
_daml_validate_test(
|
|
name = name + ".test",
|
|
dar = name + ".dar",
|
|
)
|
|
|
|
def daml_test(
|
|
name,
|
|
srcs = [],
|
|
deps = [],
|
|
data_deps = [],
|
|
damlc = "//compiler/damlc:damlc",
|
|
target = None,
|
|
**kwargs):
|
|
sh_inline_test(
|
|
name = name,
|
|
data = [damlc] + srcs + deps + data_deps,
|
|
cmd = """\
|
|
set -eoux pipefail
|
|
tmpdir=$$(mktemp -d)
|
|
trap "rm -rf $$tmpdir" EXIT
|
|
DAMLC=$$(canonicalize_rlocation $(rootpath {damlc}))
|
|
rlocations () {{ for i in $$@; do echo $$(canonicalize_rlocation $$i); done; }}
|
|
DEPS=($$(rlocations {deps}))
|
|
DATA_DEPS=($$(rlocations {data_deps}))
|
|
JOINED_DATA_DEPS="$$(printf ',"%s"' $${{DATA_DEPS[@]}})"
|
|
echo "$$JOINED_DATA_DEPS"
|
|
cat << EOF > $$tmpdir/daml.yaml
|
|
build-options: [{target}]
|
|
sdk-version: {sdk_version}
|
|
name: test
|
|
version: 0.0.1
|
|
source: .
|
|
dependencies: [daml-stdlib, daml-prim $$([ $${{#DEPS[@]}} -gt 0 ] && printf ',"%s"' $${{DEPS[@]}})]
|
|
data-dependencies: [$$([ $${{#DATA_DEPS[@]}} -gt 0 ] && printf '%s' $${{JOINED_DATA_DEPS:1}})]
|
|
EOF
|
|
cat $$tmpdir/daml.yaml
|
|
{cp_srcs}
|
|
cd $$tmpdir
|
|
$$DAMLC test --files {files}
|
|
""".format(
|
|
damlc = damlc,
|
|
files = " ".join(["$(rootpaths %s)" % src for src in srcs]),
|
|
sdk_version = sdk_version,
|
|
deps = " ".join(["$(rootpaths %s)" % dep for dep in deps]),
|
|
data_deps = " ".join(["$(rootpaths %s)" % dep for dep in data_deps]),
|
|
cp_srcs = "\n".join([
|
|
"mkdir -p $$(dirname {dest}); cp -f {src} {dest}".format(
|
|
src = "$$(canonicalize_rlocation $(rootpath {}))".format(src),
|
|
dest = "$$tmpdir/$(rootpath {})".format(src),
|
|
)
|
|
for src in srcs
|
|
]),
|
|
target = "--target=" + target if (target) else "",
|
|
),
|
|
**kwargs
|
|
)
|
|
|
|
def daml_doc_test(
|
|
name,
|
|
package_name,
|
|
srcs = [],
|
|
ignored_srcs = [],
|
|
flags = [],
|
|
cpp = "@stackage-exe//hpp",
|
|
damlc = "//compiler/damlc:damlc",
|
|
**kwargs):
|
|
sh_inline_test(
|
|
name = name,
|
|
data = [cpp, damlc] + srcs,
|
|
cmd = """\
|
|
set -eou pipefail
|
|
CPP=$$(canonicalize_rlocation $(rootpath {cpp}))
|
|
DAMLC=$$(canonicalize_rlocation $(rootpath {damlc}))
|
|
FILES=($$(
|
|
for file in {files}; do
|
|
IGNORED=false
|
|
for pattern in {ignored}; do
|
|
if [[ $$file = *$$pattern ]]; then
|
|
IGNORED=true
|
|
continue
|
|
fi
|
|
done
|
|
if [[ $$IGNORED == "false" ]]; then
|
|
echo $$(canonicalize_rlocation $$file)
|
|
fi
|
|
done
|
|
))
|
|
|
|
$$DAMLC doctest {flags} --cpp $$CPP --package-name {package_name}-{version} "$${{FILES[@]}}"
|
|
""".format(
|
|
cpp = cpp,
|
|
damlc = damlc,
|
|
package_name = package_name,
|
|
flags = " ".join(flags),
|
|
version = ghc_version,
|
|
files = " ".join(["$(rootpaths %s)" % src for src in srcs]),
|
|
ignored = " ".join(ignored_srcs),
|
|
),
|
|
**kwargs
|
|
)
|