[pacman-dev] [PATCH 1/2] makepkg-template: ignore duplicates per option

Dominik Fischer d.f.fischer at web.de
Mon Jun 8 09:28:14 UTC 2015


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 at 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:]+_. at -]/;
 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


More information about the pacman-dev mailing list