From 712d82d2e588b28fd28583ce12f86f5b3f79e928 Mon Sep 17 00:00:00 2001 From: Michael Kelly Date: Mon, 2 Oct 2023 08:37:08 -0700 Subject: [PATCH 1/2] Allow substitution of user-defined variables in RPM preamble It's desirable to be able to parameterize some variables in the preamble such as architecture when RPM packages. This change enables variable substitution in the preamble section so that the values may be injected in this fashion in lieu of only using statically defined values. --- pkg/rpm_pfg.bzl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/rpm_pfg.bzl b/pkg/rpm_pfg.bzl index 97ffcfa2..782ea215 100644 --- a/pkg/rpm_pfg.bzl +++ b/pkg/rpm_pfg.bzl @@ -33,7 +33,7 @@ load( "PackageSymlinkInfo", "PackageVariablesInfo", ) -load("//pkg/private:util.bzl", "setup_output_files") +load("//pkg/private:util.bzl", "setup_output_files", "substitute_package_variables") rpm_filetype = [".rpm"] @@ -349,7 +349,7 @@ def _pkg_rpm_impl(ctx): ) ctx.actions.write( output = preamble_file, - content = "\n".join(preamble_pieces), + content = substitute_package_variables(ctx, "\n".join(preamble_pieces)), ) files.append(preamble_file) args.append("--preamble=" + preamble_file.path) From d8c35ba96dacbaeccf969bfcd276bf1c2ae05544 Mon Sep 17 00:00:00 2001 From: Michael Kelly Date: Wed, 22 Nov 2023 11:29:37 -0800 Subject: [PATCH 2/2] Deal with mismatched variable definitions Currently we don't handle things like $(foo or (bar) correctly. Lacking regex matching, we can compensate for this somewhat by attempting to find matching pairs of $( and ) and failing if we see the start of a variable declaration but not its termination. --- pkg/private/util.bzl | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/private/util.bzl b/pkg/private/util.bzl index 7d36cf8e..7225456b 100644 --- a/pkg/private/util.bzl +++ b/pkg/private/util.bzl @@ -82,5 +82,14 @@ def substitute_package_variables(ctx, attribute_value): # Map $(var) to {x} and then use format for substitution. # This is brittle and I hate it. We should have template substitution - # in the Starlark runtime. - return attribute_value.replace("$(", "{").replace(")", "}").format(**vars) + # in the Starlark runtime. This loop compensates for mismatched counts + # of $(foo) so that we don't try replace things like (bar) because we + # have no regex matching + for _ in range(attribute_value.count("$(")): + if attribute_value.find(")") == -1: + fail("mismatched variable declaration") + + attribute_value = attribute_value.replace("$(", "{", 1) + attribute_value = attribute_value.replace(")", "}", 1) + + return attribute_value.format(**vars) \ No newline at end of file