When templates recursively include other templates, a diamond problem, similar to multiple inheritance, may occur. It is illustrated in the test case. As templates may consist of arbitrary code, it may be unwanted to execute a template twice. This patch provides a solution to some simple cases of this problem by completely ignoring every template occurrence but the first for each template name. Signed-off-by: Dominik Fischer <d.f.fischer@web.de> --- doc/makepkg-template.1.txt | 6 ++++++ scripts/makepkg-template.pl.in | 12 ++++++++++++ .../makepkg-template-tests/diamond-input/PKGBUILD | 5 +++++ .../diamond-input/PKGBUILD.expanded | 13 +++++++++++++ .../diamond-input/templates/base-1.template | 1 + .../diamond-input/templates/first-include-1.template | 1 + .../diamond-input/templates/second-include-1.template | 1 + .../diamond-input/testcase-config | 18 ++++++++++++++++++ 8 files changed, 57 insertions(+) create mode 100644 test/scripts/makepkg-template-tests/diamond-input/PKGBUILD create mode 100644 test/scripts/makepkg-template-tests/diamond-input/PKGBUILD.expanded create mode 100644 test/scripts/makepkg-template-tests/diamond-input/templates/base-1.template create mode 100644 test/scripts/makepkg-template-tests/diamond-input/templates/first-include-1.template create mode 100644 test/scripts/makepkg-template-tests/diamond-input/templates/second-include-1.template create mode 100644 test/scripts/makepkg-template-tests/diamond-input/testcase-config diff --git a/doc/makepkg-template.1.txt b/doc/makepkg-template.1.txt index 03b2a38..bd2355c 100644 --- a/doc/makepkg-template.1.txt +++ b/doc/makepkg-template.1.txt @@ -76,6 +76,12 @@ Options given multiple times in which case files found in directory given last will take precedence. +*-t, \--no-duplicates*:: + Do not include any template twice, even when templates recursively include + other templates. Only the first occurrence of each template will be + expanded, all further references to the same name, also with different + version numbers, will be ignored. + Example PKGBUILD ---------------- diff --git a/scripts/makepkg-template.pl.in b/scripts/makepkg-template.pl.in index 9877796..e9f6e08 100755 --- a/scripts/makepkg-template.pl.in +++ b/scripts/makepkg-template.pl.in @@ -33,6 +33,8 @@ my %opts = ( my $template_name_charset = qr/[[:alnum:]+_.@-]/; my $template_marker = qr/# template/; +my %seen = (); + # runtime loading to avoid dependency on cpan since this is the only non-core module my $loaded_gettext = can_load(modules => {'Locale::gettext' => undef}); if ($loaded_gettext) { @@ -96,6 +98,15 @@ sub parse_template_line { sub load_template { my ($values) = @_; + if ($opts{dups}) { + # omit already included templates. + if (exists $seen{$values->{name}}) { + return ""; + } else { + $seen{$values->{name}} = (); + } + } + my $ret = ""; my $template_name = "$values->{name}"; @@ -205,6 +216,7 @@ GetOptions( "output|o=s" => \$opts{output}, "newest|n" => \$opts{newest}, "template-dir=s@" => \$opts{template_dir}, + "no-duplicates|t" => \$opts{dups}, ) or usage(1); $opts{output} = $opts{input} unless $opts{output}; diff --git a/test/scripts/makepkg-template-tests/diamond-input/PKGBUILD b/test/scripts/makepkg-template-tests/diamond-input/PKGBUILD new file mode 100644 index 0000000..6bb4fa5 --- /dev/null +++ b/test/scripts/makepkg-template-tests/diamond-input/PKGBUILD @@ -0,0 +1,5 @@ +pkgname=foo +pkgver=1 + +# template input; name=first-include; version=1; +# template input; name=second-include; version=1; diff --git a/test/scripts/makepkg-template-tests/diamond-input/PKGBUILD.expanded b/test/scripts/makepkg-template-tests/diamond-input/PKGBUILD.expanded new file mode 100644 index 0000000..8077581 --- /dev/null +++ b/test/scripts/makepkg-template-tests/diamond-input/PKGBUILD.expanded @@ -0,0 +1,13 @@ +pkgname=foo +pkgver=1 + +# template start; name=first-include; version=1; +# template start; name=base; version=1; +package() {} +# template end; +# template end; +# template start; name=second-include; version=1; +# template start; name=base; version=1; +package() {} +# template end; +# template end; diff --git a/test/scripts/makepkg-template-tests/diamond-input/templates/base-1.template b/test/scripts/makepkg-template-tests/diamond-input/templates/base-1.template new file mode 100644 index 0000000..056096f --- /dev/null +++ b/test/scripts/makepkg-template-tests/diamond-input/templates/base-1.template @@ -0,0 +1 @@ +package() {} diff --git a/test/scripts/makepkg-template-tests/diamond-input/templates/first-include-1.template b/test/scripts/makepkg-template-tests/diamond-input/templates/first-include-1.template new file mode 100644 index 0000000..9916370 --- /dev/null +++ b/test/scripts/makepkg-template-tests/diamond-input/templates/first-include-1.template @@ -0,0 +1 @@ +# template input; name=base; version=1; diff --git a/test/scripts/makepkg-template-tests/diamond-input/templates/second-include-1.template b/test/scripts/makepkg-template-tests/diamond-input/templates/second-include-1.template new file mode 100644 index 0000000..9916370 --- /dev/null +++ b/test/scripts/makepkg-template-tests/diamond-input/templates/second-include-1.template @@ -0,0 +1 @@ +# template input; name=base; version=1; diff --git a/test/scripts/makepkg-template-tests/diamond-input/testcase-config b/test/scripts/makepkg-template-tests/diamond-input/testcase-config new file mode 100644 index 0000000..65bb8d0 --- /dev/null +++ b/test/scripts/makepkg-template-tests/diamond-input/testcase-config @@ -0,0 +1,18 @@ +arguments+=(-t) +expected_exitcode=0 + +IFS="" read -d '' expected_output <<'EOF' +EOF + +IFS="" read -d '' expected_result <<'EOF' +pkgname=foo +pkgver=1 + +# template start; name=first-include; version=1; +# template start; name=base; version=1; +package() {} +# template end; +# template end; +# template start; name=second-include; version=1; +# template end; +EOF -- 2.4.2