Skip to content

Commit abab696

Browse files
francine-blancsitaktifholzensp
authored
Add pkl_package rule (apple#16)
* feat(pkl project package): Create pkl project package rule (apple#86) * add pkl project package rule * add copyright notice to tortoise.pkl, tidy up defs.bzl * add pkl package to defs.bzl * gitignore formatting * minor formatting of pklproject and deps.json files * update .bazelrc and .bazelignore for integration tests * update repo rule to use pkl executable * update pkl executable failure message in repo rule * update os name and architecture in pkl project repo rule * update os name and architecture in pkl project repo rule * update os name and architecture in pkl project repo rule * partial address of PR comments * continue addressing PR comments - remove run shell, add doc for pkl package * run docs updater * address remaining pr comments * add docstring to pkl_project repo rule make package optional: Co-authored-by: Steve Barrau <[email protected]> remove package from simple/PklProject integration test correct formatting remove refs to workspace in pkl_project add pkl project package rule gitignore formatting partial address of PR comments correct defs.bzl update simple example test pklproject small formatting change * begin addressing PR comments * fix(pkl_project): include src files in packaged pkl project * feat(pkl_project): add strip_prefix attribute * fix(pkl_project): include src files in packaged pkl project * feat(pkl_project): add strip_prefix attribute * add test to pkl package with srcs included * update docs * add another test as per PR comments * fix path ref * Apply suggestions from code review * fix CI failure * update docs --------- Co-authored-by: Romain Chossart <[email protected]> Co-authored-by: Philip K.F. Hölzenspies <[email protected]>
1 parent 863b9be commit abab696

File tree

24 files changed

+732
-98
lines changed

24 files changed

+732
-98
lines changed

.bazelignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,11 @@ tests/integration_tests/example_workspaces/simple/bazel-bin
66
tests/integration_tests/example_workspaces/simple/bazel-out
77
tests/integration_tests/example_workspaces/simple/bazel-simple
88
tests/integration_tests/example_workspaces/simple/bazel-testlogs
9+
tests/integration_tests/example_workspaces/pkl_cache/bazel-bin
10+
tests/integration_tests/example_workspaces/pkl_cache/bazel-out
911
tests/integration_tests/example_workspaces/pkl_cache/bazel-pkl_cache
12+
tests/integration_tests/example_workspaces/pkl_cache/bazel-testlogs
13+
tests/integration_tests/example_workspaces/pkl_package/bazel-bin
14+
tests/integration_tests/example_workspaces/pkl_package/bazel-out
15+
tests/integration_tests/example_workspaces/pkl_package/bazel-pkl_package
16+
tests/integration_tests/example_workspaces/pkl_package/bazel-testlogs

.bazelrc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ build --tool_java_runtime_version=17
1010
test --test_output=all
1111

1212
# To update these lines, execute
13-
# `bazel run @rules_bazel_integration_test//tools:update_deleted_packages`
14-
build --deleted_packages=examples/pets,examples/pkl_project,examples/pkl_project/pkl,examples/simple,tests/integration_tests/example_workspaces/pkl_cache,tests/integration_tests/example_workspaces/simple
15-
query --deleted_packages=examples/pets,examples/pkl_project,examples/pkl_project/pkl,examples/simple,tests/integration_tests/example_workspaces/pkl_cache,tests/integration_tests/example_workspaces/simple
13+
# `bazel run @rules_bazel_integration_test//tools:update_deleted_packages`.
14+
# This command must be run whenever integration test workspaces are added or removed.
15+
build --deleted_packages=examples/pets,examples/pkl_project,examples/pkl_project/pkl,examples/simple,tests/integration_tests/example_workspaces/pkl_cache,tests/integration_tests/example_workspaces/pkl_package,tests/integration_tests/example_workspaces/simple
16+
query --deleted_packages=examples/pets,examples/pkl_project,examples/pkl_project/pkl,examples/simple,tests/integration_tests/example_workspaces/pkl_cache,tests/integration_tests/example_workspaces/pkl_package,tests/integration_tests/example_workspaces/simple

docs/rules_pkl_docs.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,31 @@ Collect Pkl sources together so they can be used by other `rules_pkl` rules.
7676
| <a id="pkl_library-data"></a>data | Files to make available in the filesystem when building this library target. These can be accessed by relative path. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
7777

7878

79+
<a id="pkl_package"></a>
80+
81+
## pkl_package
82+
83+
<pre>
84+
load("@rules_pkl//pkl:defs.bzl", "pkl_package")
85+
86+
pkl_package(<a href="#pkl_package-name">name</a>, <a href="#pkl_package-srcs">srcs</a>, <a href="#pkl_package-extra_flags">extra_flags</a>, <a href="#pkl_package-project">project</a>, <a href="#pkl_package-strip_prefix">strip_prefix</a>)
87+
</pre>
88+
89+
Prepares a Pkl project to be published as a package as per the `pkl project package` command, using Bazel.
90+
You should have at most one `pkl_package` rule per `pkl_project` repo rule.
91+
92+
**ATTRIBUTES**
93+
94+
95+
| Name | Description | Type | Mandatory | Default |
96+
| :------------- | :------------- | :------------- | :------------- | :------------- |
97+
| <a id="pkl_package-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
98+
| <a id="pkl_package-srcs"></a>srcs | - | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
99+
| <a id="pkl_package-extra_flags"></a>extra_flags | - | List of strings | optional | `[]` |
100+
| <a id="pkl_package-project"></a>project | - | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
101+
| <a id="pkl_package-strip_prefix"></a>strip_prefix | Strip a directory prefix from the srcs. | String | optional | `""` |
102+
103+
79104
<a id="pkl_test"></a>
80105

81106
## pkl_test

pkl/defs.bzl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ load(
2828
"//pkl/private:pkl_library.bzl",
2929
_pkl_library = "pkl_library",
3030
)
31+
load(
32+
"//pkl/private:pkl_package.bzl",
33+
_pkl_package = "pkl_package",
34+
)
3135
load(
3236
"//pkl/private:pkl_test_suite.bzl",
3337
_pkl_test_suite = "pkl_test_suite",
@@ -42,6 +46,7 @@ pkl_doc = _pkl_doc
4246
pkl_doc_toolchain = _pkl_doc_toolchain
4347
pkl_library = _pkl_library
4448
pkl_eval = _pkl_eval
49+
pkl_package = _pkl_package
4550
pkl_test = _pkl_test
4651
pkl_test_suite = _pkl_test_suite
4752
pkl_toolchain = _pkl_toolchain

pkl/extensions.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Module extension for using rules_pkl with bzlmod.
1616
"""
1717

1818
load("//pkl:repositories.bzl", "pkl_cli_binaries")
19-
load("//pkl/private:pkl_deps.bzl", "parse_pkl_project_deps_json", "pkl_deps")
19+
load("//pkl/private:pkl_project.bzl", "parse_pkl_project_deps_json", _pkl_project = "pkl_project")
2020
load("//pkl/private:remote_pkl_package.bzl", "remote_pkl_package")
2121

2222
pkl_project = tag_class(
@@ -57,7 +57,7 @@ def _toolchain_extension(module_ctx):
5757
)
5858

5959
# Now set up all the targets that people will rely on in their builds.
60-
pkl_deps(
60+
_pkl_project(
6161
name = proj.name,
6262
pkl_project = proj.pkl_project,
6363
pkl_project_deps = proj.pkl_project_deps,

pkl/private/pkl_deps.bzl

Lines changed: 0 additions & 86 deletions
This file was deleted.

pkl/private/pkl_package.bzl

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
## Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
2+
##
3+
## Licensed under the Apache License, Version 2.0 (the "License");
4+
## you may not use this file except in compliance with the License.
5+
## You may obtain a copy of the License at
6+
##
7+
## https://www.apache.org/licenses/LICENSE-2.0
8+
##
9+
## Unless required by applicable law or agreed to in writing, software
10+
## distributed under the License is distributed on an "AS IS" BASIS,
11+
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
## See the License for the specific language governing permissions and
13+
## limitations under the License.
14+
"""
15+
Implementation of the pkl project package command as a Bazel rule.
16+
"""
17+
18+
load("@rules_pkl//pkl/private:providers.bzl", "PklMetadataInfo", "PklPackageInfo")
19+
20+
def _pkl_package_impl(ctx):
21+
pkl_toolchain = ctx.toolchains["@rules_pkl//pkl:toolchain_type"]
22+
executable = pkl_toolchain.cli[DefaultInfo].files_to_run.executable
23+
24+
project_metadata_info = ctx.attr.project[PklMetadataInfo]
25+
pkl_project_file = project_metadata_info.pkl_project_file
26+
pkl_project_deps = project_metadata_info.pkl_project_deps
27+
pkl_project_name = project_metadata_info.pkl_project_name
28+
pkl_project_version = project_metadata_info.pkl_project_version
29+
30+
artifact_prefix = "{name}@{version}".format(name = pkl_project_name, version = pkl_project_version)
31+
32+
metadata_file = ctx.actions.declare_file("{prefix}".format(prefix = artifact_prefix))
33+
metadata_file_checksum = ctx.actions.declare_file("{prefix}.sha256".format(prefix = artifact_prefix))
34+
package_archive = ctx.actions.declare_file("{prefix}.zip".format(prefix = artifact_prefix))
35+
package_archive_checksum = ctx.actions.declare_file("{prefix}.zip.sha256".format(prefix = artifact_prefix))
36+
37+
outputs = [metadata_file, metadata_file_checksum, package_archive, package_archive_checksum]
38+
39+
parts = [ctx.var["BINDIR"]]
40+
if ctx.label.package:
41+
parts.append(ctx.label.package)
42+
output_dir = "/".join(parts)
43+
44+
working_dir = "%s/work" % ctx.label.name
45+
46+
src_symlinks = []
47+
48+
pkl_project_symlink = ctx.actions.declare_file("{}/{}".format(working_dir, "PklProject"))
49+
ctx.actions.symlink(
50+
target_file = pkl_project_file,
51+
output = pkl_project_symlink,
52+
)
53+
src_symlinks.append(pkl_project_symlink)
54+
55+
pkl_project_deps_symlink = ctx.actions.declare_file("{}/{}".format(working_dir, "PklProject.deps.json"))
56+
ctx.actions.symlink(
57+
target_file = pkl_project_deps,
58+
output = pkl_project_deps_symlink,
59+
)
60+
src_symlinks.append(pkl_project_deps_symlink)
61+
62+
for f in ctx.files.srcs:
63+
f_path = f.short_path
64+
bin_path = ctx.bin_dir.path + "/"
65+
if f_path.startswith(bin_path):
66+
f_path = f_path.removeprefix(bin_path)
67+
if ctx.attr.strip_prefix:
68+
strip_prefix = ctx.attr.strip_prefix + "/"
69+
if not f_path.startswith(strip_prefix):
70+
fail("User asked to strip '{}' prefix from srcs, but source file {} does not start with the prefix".format(
71+
strip_prefix,
72+
f_path,
73+
))
74+
f_path = f_path.removeprefix(strip_prefix)
75+
src_symlink = ctx.actions.declare_file("{}/{}".format(working_dir, f_path))
76+
ctx.actions.symlink(
77+
target_file = f,
78+
output = src_symlink,
79+
)
80+
src_symlinks.append(src_symlink)
81+
82+
args = ctx.actions.args()
83+
args.add_all(["project", "package", pkl_project_symlink.dirname])
84+
args.add_all(["--output-path", "{output_dir}".format(output_dir = output_dir)])
85+
args.add_all(ctx.attr.extra_flags)
86+
87+
ctx.actions.run(
88+
executable = executable,
89+
outputs = outputs,
90+
inputs = [pkl_project_file, pkl_project_deps] + src_symlinks,
91+
arguments = [args],
92+
)
93+
94+
return [
95+
DefaultInfo(files = depset(outputs)),
96+
PklPackageInfo(
97+
metadata_file = metadata_file,
98+
metadata_file_checksum = metadata_file_checksum,
99+
package_archive = package_archive,
100+
package_archive_checksum = package_archive_checksum,
101+
project_metadata_info = project_metadata_info,
102+
),
103+
]
104+
105+
pkl_package = rule(
106+
_pkl_package_impl,
107+
doc = """
108+
Prepares a Pkl project to be published as a package as per the `pkl project package` command, using Bazel.
109+
You should have at most one `pkl_package` rule per `pkl_project` repo rule.
110+
""",
111+
attrs = {
112+
"project": attr.label(
113+
providers = [
114+
PklMetadataInfo,
115+
],
116+
mandatory = True,
117+
),
118+
"srcs": attr.label_list(allow_files = [".pkl"]),
119+
"strip_prefix": attr.string(doc = "Strip a directory prefix from the srcs."),
120+
"extra_flags": attr.string_list(default = []),
121+
},
122+
toolchains = [
123+
"@rules_pkl//pkl:toolchain_type",
124+
],
125+
)

0 commit comments

Comments
 (0)