From f223b49bf2e0663f8c55456925534fc41217f997 Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Thu, 10 Apr 2025 12:09:33 +0100 Subject: [PATCH 1/4] fix(config_toolchain): Move defaults to `labgrid_config` This is the recommended way to implement macros, and makes `labgrid_config` easier to use in isolation. --- labgrid/config/rule.bzl | 6 ++++++ labgrid/config/toolchain/macro.bzl | 12 +++--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/labgrid/config/rule.bzl b/labgrid/config/rule.bzl index 3205d9f3..4b26f7ff 100644 --- a/labgrid/config/rule.bzl +++ b/labgrid/config/rule.bzl @@ -61,30 +61,36 @@ ATTRS = { doc = "The labgrid configuration Python dependencies.", providers = [[DefaultInfo, PyInfo]], cfg = "exec", + default = [], ), "env": attr.string_dict( doc = "The environment variables to set for the configuration. Subject to `$(location)` and \"Make\" variable substitution.", + default = {}, ), "state": attr.label( doc = "The states to transition the configuration strategy to.", providers = [LabgridStateInfo], + default = "//labgrid/state", ), "data": attr.label_list( allow_files = True, doc = "The data files to use in the configuration.", providers = [DefaultInfo], cfg = "target", + default = [], ), "tools": attr.label_list( allow_files = True, doc = "The tools to use in the configuration.", providers = [DefaultInfo], cfg = "exec", + default = [], ), "managers": attr.label_list( doc = "A list of Python context managers to customize the setup of the labgrid environment.", providers = [[DefaultInfo, PyInfo]], cfg = "exec", + default = [], ), } diff --git a/labgrid/config/toolchain/macro.bzl b/labgrid/config/toolchain/macro.bzl index ed2cb810..a8ffb122 100644 --- a/labgrid/config/toolchain/macro.bzl +++ b/labgrid/config/toolchain/macro.bzl @@ -2,7 +2,7 @@ load("@rules_labgrid//labgrid/config:defs.bzl", "labgrid_config") visibility("//...") -def labgrid_config_toolchain(*, name, src, target_compatible_with, exec_compatible_with = [], state = "@rules_labgrid//labgrid/state", managers = [], deps = [], env = {}, data = [], tools = [], toolchains = []): +def labgrid_config_toolchain(*, name, src, target_compatible_with, exec_compatible_with = [], managers = [], deps = [], env = {}, **kwargs): """Registers a labgrid configuration as a toolchain of type `@rules_labgrid//labgrid/toolchain/config:type`. Args: @@ -10,13 +10,10 @@ def labgrid_config_toolchain(*, name, src, target_compatible_with, exec_compatib src: The labgrid configuration YAML. target_compatible_with: The constraints to set for the target. exec_compatible_with: The constraints to set for the exec. - state: The states to transition the configuration strategy to managers: A list of Python context managers to customize the setup of the labgrid environment. deps: The labgrid configuration Python dependencies. env: The environment variables to set for the configuration. `LG_ENV` is always set to the path of `src`. Subject to `$(location)` and \"Make\" variable substitution. - data: The data files to use in the configuration. - tools: The tools to use in the configuration. - toolchains: The toolchains to use in the configuration. + **kwargs: Extra attributes to pass to `labgrid_config` """ src = native.package_relative_label(src) labgrid_config( @@ -26,11 +23,8 @@ def labgrid_config_toolchain(*, name, src, target_compatible_with, exec_compatib env = env | { "LG_ENV": "$(location {})".format(src), }, - state = state, - data = data, - tools = tools, - toolchains = toolchains, managers = [native.package_relative_label(m) for m in managers], + **kwargs ) target_constraints = [native.package_relative_label(c) for c in target_compatible_with] -- GitLab From 5154c2204984f4f04942b9ee5d27e9c538284bc6 Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Thu, 10 Apr 2025 12:16:14 +0100 Subject: [PATCH 2/4] test(config): cover state env vars --- labgrid/config/BUILD.bazel | 6 ++++ labgrid/config/tests.bzl | 60 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 labgrid/config/tests.bzl diff --git a/labgrid/config/BUILD.bazel b/labgrid/config/BUILD.bazel index 52f77d0e..f4c3b1f9 100644 --- a/labgrid/config/BUILD.bazel +++ b/labgrid/config/BUILD.bazel @@ -3,6 +3,7 @@ load(":data.bzl", "data") load(":deps.bzl", "deps") load(":env.bzl", "env") load(":managers.bzl", "managers") +load(":tests.bzl", "suite") load(":tools.bzl", "tools") env( @@ -60,3 +61,8 @@ bzl_library( visibility = ["//visibility:public"], deps = ["//labgrid/cfg:unstore"], ) + +suite( + name = "suite", + visibility = ["//visibility:private"], +) diff --git a/labgrid/config/tests.bzl b/labgrid/config/tests.bzl new file mode 100644 index 00000000..b3ddc963 --- /dev/null +++ b/labgrid/config/tests.bzl @@ -0,0 +1,60 @@ +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load("@bazel_skylib//rules:write_file.bzl", "write_file") +load("//labgrid/state:defs.bzl", "labgrid_state") +load(":rule.bzl", "labgrid_config") + +def _test_state_env(name): + state = "{}.state".format(name) + + write_file( + name = "{}.file".format(name), + out = "{}.yml".format(name), + ) + + labgrid_state( + name = state, + initial = "one", + desired = "two", + final = "three", + ) + + labgrid_config( + name = "{}.config".format(name), + src = "{}.yml".format(name), + state = state, + ) + + env_contains_test( + name = name, + target_under_test = "{}.config".format(name), + subset = { + "LG_INITIAL_STATE": "one", + "LG_STATE": "two", + "BZL_LG_FINAL_STATE": "three", + }, + ) + +def suite(name, **kwargs): + _test_state_env("state-env-test") + + native.test_suite( + name = name, + tests = [ + ":state-env-test", + ], + **kwargs + ) + +def _env_contains_impl(ctx): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + for k, v in ctx.attr.subset.items(): + asserts.equals(env, v, target[platform_common.ToolchainInfo].env.get(k, None)) + return analysistest.end(env) + +env_contains_test = analysistest.make( + impl = _env_contains_impl, + attrs = { + "subset": attr.string_dict(), + }, +) -- GitLab From 9842407f29e6060337abb6ad54672b2d3dc14d73 Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Thu, 10 Apr 2025 12:47:04 +0100 Subject: [PATCH 3/4] fix(config_toolchain): set `LG_ENV` in `labgrid_config` This delegates most responsibilities to the rule the macro is wrapping, which is what we want. --- labgrid/config/rule.bzl | 11 +++++++++-- labgrid/config/tests.bzl | 28 +++++++++++++++++++++++++++- labgrid/config/toolchain/macro.bzl | 6 +----- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/labgrid/config/rule.bzl b/labgrid/config/rule.bzl index 4b26f7ff..d7f0694b 100644 --- a/labgrid/config/rule.bzl +++ b/labgrid/config/rule.bzl @@ -141,7 +141,14 @@ def _forward_runfiles(ctx, targets): runfiles = runfiles.merge_all([d.default_runfiles for d in targets]) return DefaultInfo(files = files, runfiles = runfiles) -def _state_env(state): +def _src_env(ctx): + src = ctx.attr.src.label + return { + "LG_ENV": "$(location {})".format(src), + } + +def _state_env(ctx): + state = ctx.attr.state[LabgridStateInfo] tuples = [ ("LG_INITIAL_STATE", state.initial), ("LG_STATE", state.desired), @@ -152,7 +159,7 @@ def _state_env(state): def implementation(ctx): data = ctx.attr.data + [ctx.attr.src] tools = ctx.attr.tools + ctx.attr.toolchains - env = {k: _expand(ctx, data, v) for k, v in ctx.attr.env.items()} | _state_env(ctx.attr.state[LabgridStateInfo]) + env = {k: _expand(ctx, data, v) for k, v in (ctx.attr.env | _src_env(ctx) | _state_env(ctx)).items()} default = DefaultInfo(files = depset([ctx.file.src])) toolchain = platform_common.ToolchainInfo( src = ctx.file.src, diff --git a/labgrid/config/tests.bzl b/labgrid/config/tests.bzl index b3ddc963..877da37e 100644 --- a/labgrid/config/tests.bzl +++ b/labgrid/config/tests.bzl @@ -3,6 +3,28 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file") load("//labgrid/state:defs.bzl", "labgrid_state") load(":rule.bzl", "labgrid_config") +def _test_src_env(name): + src = "{}.yml".format(name) + + write_file( + name = "{}.file".format(name), + out = src, + ) + + labgrid_config( + name = "{}.config".format(name), + src = src, + ) + + env_contains_test( + name = name, + target_under_test = "{}.config".format(name), + subset = { + "LG_ENV": "$(rlocationpath {})".format(src), + }, + data = [src], + ) + def _test_state_env(name): state = "{}.state".format(name) @@ -35,11 +57,13 @@ def _test_state_env(name): ) def suite(name, **kwargs): + _test_src_env("src-env-test") _test_state_env("state-env-test") native.test_suite( name = name, tests = [ + ":src-env-test", ":state-env-test", ], **kwargs @@ -48,7 +72,8 @@ def suite(name, **kwargs): def _env_contains_impl(ctx): env = analysistest.begin(ctx) target = analysistest.target_under_test(env) - for k, v in ctx.attr.subset.items(): + subset = {k: ctx.expand_location(v, ctx.attr.data) for k, v in ctx.attr.subset.items()} + for k, v in subset.items(): asserts.equals(env, v, target[platform_common.ToolchainInfo].env.get(k, None)) return analysistest.end(env) @@ -56,5 +81,6 @@ env_contains_test = analysistest.make( impl = _env_contains_impl, attrs = { "subset": attr.string_dict(), + "data": attr.label_list(allow_files = True), }, ) diff --git a/labgrid/config/toolchain/macro.bzl b/labgrid/config/toolchain/macro.bzl index a8ffb122..69179127 100644 --- a/labgrid/config/toolchain/macro.bzl +++ b/labgrid/config/toolchain/macro.bzl @@ -2,7 +2,7 @@ load("@rules_labgrid//labgrid/config:defs.bzl", "labgrid_config") visibility("//...") -def labgrid_config_toolchain(*, name, src, target_compatible_with, exec_compatible_with = [], managers = [], deps = [], env = {}, **kwargs): +def labgrid_config_toolchain(*, name, src, target_compatible_with, exec_compatible_with = [], managers = [], deps = [], **kwargs): """Registers a labgrid configuration as a toolchain of type `@rules_labgrid//labgrid/toolchain/config:type`. Args: @@ -12,7 +12,6 @@ def labgrid_config_toolchain(*, name, src, target_compatible_with, exec_compatib exec_compatible_with: The constraints to set for the exec. managers: A list of Python context managers to customize the setup of the labgrid environment. deps: The labgrid configuration Python dependencies. - env: The environment variables to set for the configuration. `LG_ENV` is always set to the path of `src`. Subject to `$(location)` and \"Make\" variable substitution. **kwargs: Extra attributes to pass to `labgrid_config` """ src = native.package_relative_label(src) @@ -20,9 +19,6 @@ def labgrid_config_toolchain(*, name, src, target_compatible_with, exec_compatib name = "{}-config".format(name), src = src, deps = [native.package_relative_label(d) for d in deps], - env = env | { - "LG_ENV": "$(location {})".format(src), - }, managers = [native.package_relative_label(m) for m in managers], **kwargs ) -- GitLab From a4a158c4404454faaac68f86d539053dd26cb009 Mon Sep 17 00:00:00 2001 From: Alex Tercete Date: Thu, 10 Apr 2025 14:16:59 +0100 Subject: [PATCH 4/4] feat(config): add `place_tags` attribute --- labgrid/config/rule.bzl | 12 +++++++++++- labgrid/config/tests.bzl | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/labgrid/config/rule.bzl b/labgrid/config/rule.bzl index d7f0694b..50b3fb30 100644 --- a/labgrid/config/rule.bzl +++ b/labgrid/config/rule.bzl @@ -67,6 +67,10 @@ ATTRS = { doc = "The environment variables to set for the configuration. Subject to `$(location)` and \"Make\" variable substitution.", default = {}, ), + "place_tags": attr.string_dict( + doc = "The tags to use when reserving a place.", + default = {}, + ), "state": attr.label( doc = "The states to transition the configuration strategy to.", providers = [LabgridStateInfo], @@ -156,10 +160,16 @@ def _state_env(ctx): ] return {k: v for k, v in tuples if v} +def _place_tags_env(ctx): + place_tags = ctx.attr.place_tags + if place_tags: + return {"BZL_LG_TAGS": " ".join(["{}={}".format(k, v) for k, v in place_tags.items()])} + return {} + def implementation(ctx): data = ctx.attr.data + [ctx.attr.src] tools = ctx.attr.tools + ctx.attr.toolchains - env = {k: _expand(ctx, data, v) for k, v in (ctx.attr.env | _src_env(ctx) | _state_env(ctx)).items()} + env = {k: _expand(ctx, data, v) for k, v in (ctx.attr.env | _src_env(ctx) | _state_env(ctx) | _place_tags_env(ctx)).items()} default = DefaultInfo(files = depset([ctx.file.src])) toolchain = platform_common.ToolchainInfo( src = ctx.file.src, diff --git a/labgrid/config/tests.bzl b/labgrid/config/tests.bzl index 877da37e..95a6a408 100644 --- a/labgrid/config/tests.bzl +++ b/labgrid/config/tests.bzl @@ -56,15 +56,40 @@ def _test_state_env(name): }, ) +def _test_place_tags_env(name): + write_file( + name = "{}.file".format(name), + out = "{}.yml".format(name), + ) + + labgrid_config( + name = "{}.config".format(name), + src = "{}.yml".format(name), + place_tags = { + "ONE": "1", + "TWO": "2", + }, + ) + + env_contains_test( + name = name, + target_under_test = "{}.config".format(name), + subset = { + "BZL_LG_TAGS": "ONE=1 TWO=2", + }, + ) + def suite(name, **kwargs): _test_src_env("src-env-test") _test_state_env("state-env-test") + _test_place_tags_env("place-tags-env-test") native.test_suite( name = name, tests = [ ":src-env-test", ":state-env-test", + ":place-tags-env-test", ], **kwargs ) -- GitLab