Skip to content

Commit

Permalink
Add Pkl codegen related macros (#30)
Browse files Browse the repository at this point in the history
This commit contains the code required for `pkl_codegen_java_toolchain`,
`pkl_config_java_library`, and `pkl_config_src`.

---------

Co-authored-by: Kushal Pisavadia <[email protected]>
  • Loading branch information
shs96c and KushalP authored Dec 5, 2024
1 parent 701c8d8 commit 167889c
Show file tree
Hide file tree
Showing 12 changed files with 534 additions and 10 deletions.
14 changes: 8 additions & 6 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ module(
compatibility_level = 1,
)

bazel_dep(name = "aspect_bazel_lib", version = "2.5.3")
bazel_dep(name = "aspect_bazel_lib", version = "2.9.4")
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "rules_java", version = "8.3.2")
bazel_dep(name = "rules_jvm_external", version = "6.2")
bazel_dep(name = "rules_java", version = "8.6.1")
bazel_dep(name = "rules_jvm_external", version = "6.6")

pkl = use_extension("//pkl:extensions.bzl", "pkl")
use_repo(
Expand All @@ -35,10 +35,11 @@ use_repo(
)

register_toolchains(
"@rules_pkl//pkl:pkl_toolchain_macos_aarch64",
"@rules_pkl//pkl:pkl_toolchain_macos_amd64",
"@rules_pkl//pkl:pkl_toolchain_codegen_java",
"@rules_pkl//pkl:pkl_toolchain_linux_aarch64",
"@rules_pkl//pkl:pkl_toolchain_linux_amd64",
"@rules_pkl//pkl:pkl_toolchain_macos_aarch64",
"@rules_pkl//pkl:pkl_toolchain_macos_amd64",
)

maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
Expand All @@ -48,6 +49,7 @@ maven.install(
"org.pkl-lang:pkl-tools:0.27.0",
"org.jetbrains.kotlin:kotlin-stdlib:1.7.10",
"com.google.code.gson:gson:2.10.1",
"org.junit.vintage:junit-vintage-engine:5.7.0",
],
lock_file = "//pkl/private:pkl_deps_install.json",
repositories = [
Expand All @@ -63,7 +65,7 @@ use_repo(
bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "1.4.1", dev_dependency = True)
bazel_dep(name = "buildifier_prebuilt", version = "6.1.0", dev_dependency = True)
bazel_dep(name = "gazelle", version = "0.35.0", dev_dependency = True, repo_name = "bazel_gazelle")
bazel_dep(name = "stardoc", version = "0.7.0", dev_dependency = True)
bazel_dep(name = "stardoc", version = "0.7.2", dev_dependency = True)
bazel_dep(name = "rules_python", version = "0.34.0", dev_dependency = True)

python = use_extension(
Expand Down
70 changes: 70 additions & 0 deletions docs/rules_pkl_docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,27 @@

Public API re-exports

<a id="pkl_codegen_java_toolchain"></a>

## pkl_codegen_java_toolchain

<pre>
load("@rules_pkl//pkl:defs.bzl", "pkl_codegen_java_toolchain")

pkl_codegen_java_toolchain(<a href="#pkl_codegen_java_toolchain-name">name</a>, <a href="#pkl_codegen_java_toolchain-cli">cli</a>)
</pre>



**ATTRIBUTES**


| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="pkl_codegen_java_toolchain-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
| <a id="pkl_codegen_java_toolchain-cli"></a>cli | - | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `"@rules_pkl//pkl:pkl_codegen_java_cli"` |


<a id="pkl_doc_toolchain"></a>

## pkl_doc_toolchain
Expand Down Expand Up @@ -152,6 +173,55 @@ pkl_toolchain(<a href="#pkl_toolchain-name">name</a>, <a href="#pkl_toolchain-cl
| <a id="pkl_toolchain-cli"></a>cli | - | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |


<a id="pkl_config_java_library"></a>

## pkl_config_java_library

<pre>
load("@rules_pkl//pkl:defs.bzl", "pkl_config_java_library")

pkl_config_java_library(<a href="#pkl_config_java_library-name">name</a>, <a href="#pkl_config_java_library-files">files</a>, <a href="#pkl_config_java_library-module_path">module_path</a>, <a href="#pkl_config_java_library-generate_getters">generate_getters</a>, <a href="#pkl_config_java_library-deps">deps</a>, <a href="#pkl_config_java_library-tags">tags</a>, <a href="#pkl_config_java_library-kwargs">kwargs</a>)
</pre>

Create a compiled JAR of Java source files generated from Pkl source files.

**PARAMETERS**


| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="pkl_config_java_library-name"></a>name | A unique name for this target. | none |
| <a id="pkl_config_java_library-files"></a>files | The Pkl files that are used to generate the Java source files. | none |
| <a id="pkl_config_java_library-module_path"></a>module_path | List of Java module targets. Must export provide the JavaInfo provider. | `[]` |
| <a id="pkl_config_java_library-generate_getters"></a>generate_getters | Generate private final fields and public getter methods instead of public final fields. Defaults to True. | `None` |
| <a id="pkl_config_java_library-deps"></a>deps | Other targets to include in the Pkl module path when building this Java library. Must be pkl_* targets. | `[]` |
| <a id="pkl_config_java_library-tags"></a>tags | Bazel tags to add to this target. | `[]` |
| <a id="pkl_config_java_library-kwargs"></a>kwargs | Further keyword arguments. E.g. visibility | none |


<a id="pkl_config_src"></a>

## pkl_config_src

<pre>
load("@rules_pkl//pkl:defs.bzl", "pkl_config_src")

pkl_config_src(<a href="#pkl_config_src-name">name</a>, <a href="#pkl_config_src-files">files</a>, <a href="#pkl_config_src-module_path">module_path</a>, <a href="#pkl_config_src-kwargs">kwargs</a>)
</pre>

Create a JAR containing the generated Java source files from Pkl files.

**PARAMETERS**


| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="pkl_config_src-name"></a>name | A unique name for this target. | none |
| <a id="pkl_config_src-files"></a>files | The Pkl source files used to generate the Java source files. | none |
| <a id="pkl_config_src-module_path"></a>module_path | List of Java module targets. Must export provide the JavaInfo provider. | `None` |
| <a id="pkl_config_src-kwargs"></a>kwargs | Further keyword arguments. E.g. visibility | none |


<a id="pkl_doc"></a>

## pkl_doc
Expand Down
32 changes: 31 additions & 1 deletion pkl/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@rules_java//java:defs.bzl", "java_binary")
load("@rules_jvm_external//:defs.bzl", "artifact")
load("//pkl:repositories.bzl", "DEFAULT_PKL_VERSION")
load(":defs.bzl", "pkl_doc_toolchain", "pkl_toolchain")
load(":defs.bzl", "pkl_codegen_java_toolchain", "pkl_doc_toolchain", "pkl_toolchain")

filegroup(
name = "all_files",
Expand Down Expand Up @@ -120,6 +120,21 @@ toolchain(
toolchain_type = ":toolchain_type",
)

toolchain_type(
name = "codegen_toolchain_type",
)

pkl_codegen_java_toolchain(
name = "pkl_codegen_java",
visibility = ["//visibility:public"],
)

toolchain(
name = "pkl_toolchain_codegen_java",
toolchain = ":pkl_codegen_java",
toolchain_type = ":codegen_toolchain_type",
)

toolchain_type(
name = "doc_toolchain_type",
)
Expand All @@ -143,6 +158,21 @@ bzl_library(
"//pkl/private:docs",
"@bazel_tools//tools/build_defs/repo:http.bzl",
"@bazel_tools//tools/build_defs/repo:utils.bzl",
"@rules_java//java/private:proto_support",
],
)

java_binary(
name = "pkl_codegen_java_cli",
main_class = "org.pkl.codegen.java.Main",
visibility = [
"//visibility:public",
],
runtime_deps = [
artifact(
"org.pkl-lang:pkl-tools",
repository_name = "rules_pkl_deps",
),
],
)

Expand Down
9 changes: 9 additions & 0 deletions pkl/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ load(
_pkl_eval = "pkl_eval",
_pkl_test = "pkl_test",
)
load(
"//pkl/private:pkl_codegen.bzl",
_pkl_config_java_library = "pkl_config_java_library",
_pkl_config_src = "pkl_config_src",
)
load(
"//pkl/private:pkl_doc.bzl",
_pkl_doc = "pkl_doc",
Expand All @@ -38,10 +43,14 @@ load(
)
load(
"//pkl/private:toolchain.bzl",
_pkl_codegen_java_toolchain = "pkl_codegen_java_toolchain",
_pkl_doc_toolchain = "pkl_doc_toolchain",
_pkl_toolchain = "pkl_toolchain",
)

pkl_codegen_java_toolchain = _pkl_codegen_java_toolchain
pkl_config_java_library = _pkl_config_java_library
pkl_config_src = _pkl_config_src
pkl_doc = _pkl_doc
pkl_doc_toolchain = _pkl_doc_toolchain
pkl_library = _pkl_library
Expand Down
5 changes: 4 additions & 1 deletion pkl/private/constants.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ Constants.

PKL_DEPS = {
"0.26.1": [
"com.google.code.gson:gson:2.10.1",
"org.junit.vintage:junit-vintage-engine:5.7.0",
"org.pkl-lang:pkl-codegen-java:0.26.1",
"org.pkl-lang:pkl-config-java:0.26.1",
"org.pkl-lang:pkl-doc:0.26.1",
"org.pkl-lang:pkl-tools:0.26.1",
"com.google.code.gson:gson:2.10.1",
],
"0.26.3": [
"org.pkl-lang:pkl-doc:0.26.3",
Expand Down
147 changes: 147 additions & 0 deletions pkl/private/pkl_codegen.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
"""
Implementation for 'pkl_config_src' and 'pkl_config_java_library' macros.
"""

load("@rules_jvm_external//:defs.bzl", "artifact")

def _to_short_path(f, _expander):
return f.tree_relative_path + "=" + f.path

def _zipit(ctx, outfile, files):
zip_args = ctx.actions.args()
zip_args.add_all("cC", [outfile.path])
zip_args.add_all(files, map_each = _to_short_path)
ctx.actions.run(
inputs = files,
outputs = [outfile],
executable = ctx.executable._zip,
arguments = [zip_args],
progress_message = "Writing via zip: %s" % outfile.basename,
)

def _pkl_codegen_impl(ctx):
modules = depset(transitive = [depset(dep[JavaInfo].runtime_output_jars) for dep in ctx.attr.module_path]).to_list()
java_codegen_toolchain = ctx.toolchains["//pkl:codegen_toolchain_type"]

# Generate Java from PKL
outdir = ctx.actions.declare_directory(ctx.attr.name, sibling = None)
gen_args = ctx.actions.args()

gen_args.add("--no-cache")
if len(modules):
gen_args.add_all(["--module-path", ctx.configuration.host_path_separator.join([module.path for module in modules])])
if ctx.attr.generate_getters:
gen_args.add_all(["--generate-getters"])
gen_args.add_all("-o", [outdir.path])
gen_args.add_all(ctx.files.files)

ctx.actions.run(
inputs = ctx.files.files + modules,
outputs = [outdir],
executable = java_codegen_toolchain.codegen_cli,
arguments = [gen_args],
tools = [
java_codegen_toolchain.cli_files_to_run,
],
progress_message = "Generating Java sources from Pkl %s" % (ctx.label),
)

# Create JAR
outjar = ctx.outputs.out
_zipit(
ctx = ctx,
outfile = ctx.outputs.out,
files = [outdir],
)

# Return JAR
return OutputGroupInfo(out = [outjar])

_pkl_codegen = rule(
_pkl_codegen_impl,
attrs = {
"files": attr.label_list(
mandatory = True,
allow_files = [".pkl"],
doc = "The Pkl source files.",
),
"generate_getters": attr.bool(
doc = "Whether to generate getters in the AppConfig. Defaults to True",
default = True,
),
"module_path": attr.label_list(
providers = [
[JavaInfo],
],
doc = "List of Java module targets. Must export provide the JavaInfo provider.",
),
"out": attr.output(
doc = "The output JAR generated by this action.",
),
"_zip": attr.label(
allow_single_file = True,
cfg = "exec",
default = "@bazel_tools//tools/zip:zipper",
executable = True,
),
},
toolchains = [
"//pkl:codegen_toolchain_type",
],
)

def pkl_config_src(name, files, module_path = None, **kwargs):
"""Create a JAR containing the generated Java source files from Pkl files.
Args:
name: A unique name for this target.
files: The Pkl source files used to generate the Java source files.
module_path: List of Java module targets. Must export provide the JavaInfo provider.
**kwargs: Further keyword arguments. E.g. visibility
"""
_pkl_codegen(
name = name,
files = files,
module_path = module_path,
out = name + "_codegen.srcjar",
**kwargs
)

def pkl_config_java_library(name, files, module_path = [], generate_getters = None, deps = [], tags = [], **kwargs):
"""Create a compiled JAR of Java source files generated from Pkl source files.
Args:
name: A unique name for this target.
files: The Pkl files that are used to generate the Java source files.
module_path: List of Java module targets. Must export provide the JavaInfo provider.
generate_getters: Generate private final fields and public getter methods instead of public final fields. Defaults to True.
deps: Other targets to include in the Pkl module path when building this Java library. Must be pkl_* targets.
tags: Bazel tags to add to this target.
**kwargs: Further keyword arguments. E.g. visibility
"""
name_generated_code = name + "_pkl"

pkl_config_src(
name = name_generated_code,
files = files,
generate_getters = generate_getters,
module_path = module_path,
tags = tags,
)

pkl_deps = [artifact("org.pkl-lang:pkl-tools", repository_name = "rules_pkl_deps")]

# Ensure that there are no duplicate entries in the deps
all_deps = depset(
pkl_deps + module_path,
transitive = [depset([dep]) for dep in deps],
)

native.java_library(
name = name,
srcs = [name_generated_code],
deps = all_deps.to_list(),
resources = files,
tags = tags + [] if "no-lint" in tags else ["no-lint"],
**kwargs
)
Loading

0 comments on commit 167889c

Please sign in to comment.