commit 03d53fcb0444fe9d752719bfbb62e3658d15d26d
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Wed Aug 22 12:34:40 2018 +0200
Bug 27265: fix output_dir value in sub-projects
In the build_pkg call in input_files, we were setting the output_dir
option to the project's directory, causing this directory to be
incorrectly used as the output directory in some cases. But there is no
need to set output_dir at this point, so we can just remove it.
We also introduce a new feature allowing to set options for the current
project but not for the child projects listed in `input_files`. By
default the options are applied recursively to all projects. If some
options are defined under `norec/` then they are only applied on the
current project.
We use this feature in two places where we were setting the output_dir,
which removes the need to reset it in two places.
At the same time, we fix the `urlget()` call in input_files which was
incorrectly ignoring options.
---
doc/rbm_input_files.asc | 45 +++++++++++++++++++++++++++++++++++++++++++++
doc/rbm_templates.asc | 10 ++++++++++
lib/RBM.pm | 29 ++++++++++++++---------------
3 files changed, 69 insertions(+), 15 deletions(-)
diff --git a/doc/rbm_input_files.asc b/doc/rbm_input_files.asc
index d56f125..de47638 100644
--- a/doc/rbm_input_files.asc
+++ b/doc/rbm_input_files.asc
@@ -143,6 +143,51 @@ array can be a string. In that case the string is the name of the option
containing the file descriptor hash. This can be useful when you are
using the same file in multiple projects.
+
+INHERITANCE OF PROJECTS OPTIONS
+-------------------------------
+
+When defining a file of type +project+, the options defined in the
++input_files+ entry are transmitted to the child project. If this
+project is also using other projects in its +input_files+ then the
+options from the first +input_files+ entry are inherited.
+
+In this example, both project B and C are getting the definition of
++option1+:
+----
+projects/A/config:
+ input_files:
+ - project: B
+ option1: value1
+
+projects/B/config:
+ input_files:
+ - project: C
+
+projects/C/config:
+ input_files: []
+----
+
+In some cases you might want to define options that only apply to the
+first level of child projects. To do that you can define the options
+under +norec+. In this example, only project B is getting the definition
+of +option1+:
+----
+projects/A/config:
+ input_files:
+ - project: B
+ norec:
+ option1: value1
+
+projects/B/config:
+ input_files:
+ - project: C
+
+projects/C/config:
+ input_files: []
+----
+
+
EXAMPLES
--------
diff --git a/doc/rbm_templates.asc b/doc/rbm_templates.asc
index d34f3b2..2f72c94 100644
--- a/doc/rbm_templates.asc
+++ b/doc/rbm_templates.asc
@@ -69,6 +69,16 @@ c::
- 'as_array' :
if set to 1, then return all matching results as an
array reference, instead of only the first one.
+ - 'norec' :
+ this option is useful in the cases where the value of
+ an option depends on the input files of the current
+ project, for example to compute a hash based on the
+ input files. In +norec+ you can define options that
+ will apply to the current project, but will not be
+ applied on the child projects defined in the
+ +input_files+ section. For more details, you can read
+ the "Inheritance of projects options" section in
+ link:rbm_input_files.html[rbm_input_files(7)].
pc::
This variable is a function reference. It is the same as +c+,
diff --git a/lib/RBM.pm b/lib/RBM.pm
index 9659f16..4db951a 100644
--- a/lib/RBM.pm
+++ b/lib/RBM.pm
@@ -220,8 +220,8 @@ sub project_config {
goto FINISH unless @$name;
my $opt_save = $config->{opt};
$config->{opt} = { %{$config->{opt}}, %$options } if $options;
- $res = config($project, $name, $options, ['opt'], ['run'],
- ['projects', $project], ['local'], [],
+ $res = config($project, $name, $options, ['opt', 'norec'], ['opt'],
+ ['run'], ['projects', $project], ['local'], [],
['system'], ['default']);
if (!$options->{no_tmpl} && defined($res) && !ref $res
&& !notmpl(confkey_str($name), $project)) {
@@ -747,7 +747,7 @@ sub input_file_id {
return $t->('input_file_id') if $input_file->{input_file_id};
return $input_file->{project} . ':' . $filename if $input_file->{project};
return $filename . ':' . $t->('sha256sum') if $input_file->{sha256sum};
- return $filename . ':' . sha256_hex($t->('exec', { output_dir => '/out' }))
+ return $filename . ':' . sha256_hex($t->('exec', { norec => { output_dir => '/out' } }))
if $input_file->{exec};
return input_file_id_hash($fname, $filename);
}
@@ -774,6 +774,7 @@ sub input_files {
my $getfnames_noname = 0;
my $input_files_id = '';
$options = {$options ? %$options : ()};
+ $options->{norec} = {};
my $input_files = project_config($project, 'input_files', $options);
goto RETURN_RES unless $input_files;
my $proj_dir = rbm_path(project_config($project, 'projects_dir', $options));
@@ -789,8 +790,7 @@ sub input_files {
next unless $input_file;
my $t = sub {
project_config($project, $_[0], {$options ? %$options : (),
- %$input_file, output_dir => $src_dir,
- $_[1] ? %{$_[1]} : ()});
+ %$input_file, $_[1] ? %{$_[1]} : ()});
};
if ($input_file->{enable} && !$t->('enable')) {
next;
@@ -849,11 +849,10 @@ sub input_files {
if ($input_file->{project}) {
$proj_out_dir = rbm_path(project_step_config($t->('project'), 'output_dir',
{ %$options, step => $t->('pkg_type'),
- origin_project => $project,
- output_dir => undef, %$input_file }));
+ origin_project => $project, %$input_file }));
} else {
$proj_out_dir = rbm_path(project_config($project, 'output_dir',
- { %$input_file, output_dir => undef }));
+ { %$options, %$input_file }));
}
create_dir($proj_out_dir);
my $url = $t->('URL');
@@ -871,7 +870,7 @@ sub input_files {
if ($t->('content')) {
path("$proj_out_dir/$name")->spew_utf8($t->('content'));
} elsif ($t->('URL')) {
- urlget($project, {%$input_file, filename => $name}, 1);
+ urlget($project, {%$options, %$input_file, filename => $name}, 1);
} elsif ($t->('exec')) {
my $exec_script = project_config($project, 'exec',
{ $options ? %$options : (), %$input_file });
@@ -885,8 +884,8 @@ sub input_files {
my $run_save = $config->{run};
$config->{run} = { target => $input_file->{target} };
$config->{run}{target} //= $run_save->{target};
- build_pkg($p, {%$options, origin_project => $project, %$input_file,
- output_dir => $proj_out_dir});
+ build_pkg($p, {%$options, origin_project => $project,
+ %$input_file});
$config->{run} = $run_save;
print "Finished build of project $p - $name\n";
} else {
@@ -940,8 +939,8 @@ sub input_files {
}
foreach my $s ($sig_file ? () : @$sig_ext) {
if ($url) {
- my $f = { %$input_file, 'override.URL' => "$url.$s",
- filename => "$name.$s" };
+ my $f = { %$options, %$input_file,
+ 'override.URL' => "$url.$s", filename => "$name.$s" };
if (urlget($project, $f, 0)) {
$sig_file = "$fname.$s";
last;
@@ -1039,7 +1038,7 @@ sub build_run {
}
my $o = {
%$options,
- output_dir => $remote_tmp_dst,
+ norec => { output_dir => $remote_tmp_dst },
};
foreach my $s (@scripts) {
$build_script{$s} = project_config($project, $s, $o);
@@ -1163,7 +1162,7 @@ sub publish {
if (!$publish_src_dir) {
$publish_src_dir = File::Temp->newdir(get_tmp_dir($project)
. '/rbm-XXXXXX');
- build_pkg($project, {output_dir => $publish_src_dir});
+ build_pkg($project, { norec => { output_dir => $publish_src_dir } });
}
build_run($project, 'publish', { build_srcdir => $publish_src_dir });
}