commit 03d53fcb0444fe9d752719bfbb62e3658d15d26d Author: Nicolas Vigier boklm@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 }); }