mirror of
https://github.com/moparisthebest/pacman
synced 2024-12-21 23:38:49 -05:00
Add makepkg-template
This allows for somewhat easy templating for PKGBUILDs. Signed-off-by: Florian Pritz <bluewind@xinu.at> Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
parent
7ea58d09f6
commit
ce3125196d
19
configure.ac
19
configure.ac
@ -97,6 +97,11 @@ AC_ARG_WITH(buildscript,
|
||||
AS_HELP_STRING([--with-buildscript=name], [set the build script name used by makepkg]),
|
||||
[BUILDSCRIPT=$withval], [BUILDSCRIPT=PKGBUILD])
|
||||
|
||||
# Help line for buildscript filename
|
||||
AC_ARG_WITH(makepkg-template-dir,
|
||||
AS_HELP_STRING([--with-makepkg-template-dir=name], [set the template dir used by makepkg-template]),
|
||||
[TEMPLATE_DIR=$withval], [TEMPLATE_DIR=/usr/share/makepkg-template])
|
||||
|
||||
# Help line for debug package suffix
|
||||
AC_ARG_WITH(debug-suffix,
|
||||
AS_HELP_STRING([--with-debug-suffix=name], [set the suffix for split debugging symbol packages used by makepkg]),
|
||||
@ -166,6 +171,16 @@ AC_PROG_INSTALL
|
||||
AC_CHECK_PROGS([PYTHON], [python2.7 python2.6 python2.5 python2 python], [false])
|
||||
AC_PATH_PROGS([BASH_SHELL], [bash bash4], [false])
|
||||
|
||||
# check for perl 5.10.1 (needed by makepkg-template)
|
||||
AC_PATH_PROG([PERL],[perl])
|
||||
AC_DEFUN([AX_PROG_PERL_VERSION],
|
||||
[AC_CACHE_CHECK([for Perl version $1 or later], [ax_cv_prog_perl_version],
|
||||
[AS_IF(["$PERL" -e 'require v$1;' >/dev/null 2>&1],
|
||||
[ax_cv_prog_perl_version=yes],
|
||||
[ax_cv_prog_perl_version=no])])
|
||||
AS_IF([test x"$ax_cv_prog_perl_version" = xyes], [$2], [$3])])
|
||||
AX_PROG_PERL_VERSION([5.10.1], [], [AC_MSG_ERROR([perl is too old])])
|
||||
|
||||
AS_IF([test "x$BASH_SHELL" = "xfalse"],
|
||||
AC_MSG_WARN([*** bash >= 4.1.0 is required for pacman scripts]),
|
||||
[bash_version_major=`$BASH_SHELL -c 'echo "${BASH_VERSINFO[[0]]}"'`
|
||||
@ -457,6 +472,9 @@ AC_DEFINE_UNQUOTED([SRCEXT], "$SRCEXT", [The file extension used by pacman sourc
|
||||
# Set makepkg build script name
|
||||
AC_SUBST(BUILDSCRIPT)
|
||||
AC_DEFINE_UNQUOTED([BUILDSCRIPT], "$BUILDSCRIPT", [The build script name used by makepkg])
|
||||
# Set makepkg-template template directory
|
||||
AC_SUBST(TEMPLATE_DIR)
|
||||
AC_DEFINE_UNQUOTED([TEMPLATE_DIR], "$TEMPLATE_DIR", [The template directory used by makepkg-teplate])
|
||||
# Set makepkg split debugging symbol package suffix
|
||||
AC_SUBST(DEBUGSUFFIX)
|
||||
AC_DEFINE_UNQUOTED([DEBUGSUFFIX], "$DEBUGSUFFIX", [The suffix for debugging symbol packages used by makepkg])
|
||||
@ -524,6 +542,7 @@ ${PACKAGE_NAME}:
|
||||
package extension : ${PKGEXT}
|
||||
source pkg extension : ${SRCEXT}
|
||||
build script name : ${BUILDSCRIPT}
|
||||
template directory : ${TEMPLATE_DIR}
|
||||
|
||||
Compilation options:
|
||||
Use libcurl : ${have_libcurl}
|
||||
|
1
doc/.gitignore
vendored
1
doc/.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
PKGBUILD.5
|
||||
libalpm.3
|
||||
makepkg.8
|
||||
makepkg-template.1
|
||||
makepkg.conf.5
|
||||
pacman.8
|
||||
pacman-key.8
|
||||
|
@ -6,6 +6,7 @@
|
||||
ASCIIDOC_MANS = \
|
||||
pacman.8 \
|
||||
makepkg.8 \
|
||||
makepkg-template.1 \
|
||||
repo-add.8 \
|
||||
vercmp.8 \
|
||||
pkgdelta.8 \
|
||||
@ -21,6 +22,7 @@ DOXYGEN_MANS = $(wildcard man3/*.3)
|
||||
HTML_MANPAGES = \
|
||||
pacman.8.html \
|
||||
makepkg.8.html \
|
||||
makepkg-template.1.html \
|
||||
repo-add.8.html \
|
||||
vercmp.8.html \
|
||||
pkgdelta.8.html \
|
||||
@ -46,6 +48,7 @@ EXTRA_DIST = \
|
||||
asciidoc-override.css \
|
||||
pacman.8.txt \
|
||||
makepkg.8.txt \
|
||||
makepkg-template.1.txt \
|
||||
repo-add.8.txt \
|
||||
vercmp.8.txt \
|
||||
pkgdelta.8.txt \
|
||||
@ -147,6 +150,7 @@ $(HTML_OTHER): asciidoc.conf Makefile.am
|
||||
# Dependency rules
|
||||
pacman.8 pacman.8.html: pacman.8.txt
|
||||
makepkg.8 makepkg.8.html: makepkg.8.txt
|
||||
makepkg-template.1 makepkg-template.1.html: makepkg-template.1.txt
|
||||
repo-add.8 repo-add.8.html: repo-add.8.txt
|
||||
vercmp.8 vercmp.8.html: vercmp.8.txt
|
||||
pkgdelta.8 pkgdelta.8.html: pkgdelta.8.txt
|
||||
|
120
doc/makepkg-template.1.txt
Normal file
120
doc/makepkg-template.1.txt
Normal file
@ -0,0 +1,120 @@
|
||||
/////
|
||||
vim:set ts=4 sw=4 syntax=asciidoc noet spell spelllang=en_us:
|
||||
/////
|
||||
makepkg-template(1)
|
||||
===================
|
||||
|
||||
Name
|
||||
----
|
||||
makepkg-template - package build templating utility
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
'makepkg-template' [options]
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
'makepkg-template' is a script to ease the work of maintaining multiple similar
|
||||
PKGBUILDs. It allows you to move most of the code from the PKGBUILD into a
|
||||
template file and uses markers to allow in-place updating of existing PKGBUILDs
|
||||
if the template has been changed.
|
||||
|
||||
Template files can contain any code allowed in a PKGBUILD. You can think of
|
||||
them like external files included with "." or "source", but they will be
|
||||
inlined into the PKGBUILD by 'makepkg-template' so you do not depend on the
|
||||
template file when building the package.
|
||||
|
||||
Markers are bash comments in the form of:
|
||||
|
||||
# template start; key=value; key2=value2; ...
|
||||
|
||||
and
|
||||
|
||||
# template end;
|
||||
|
||||
Currently used keys are: name (mandatory) and version. Template names are limited to
|
||||
alphanumerics, "@", "+", ".", "-" and "_". Versions are limited to numbers and ".".
|
||||
|
||||
For initial creation there is a one line short cut which does not need an end marker:
|
||||
|
||||
# template input; key=value;
|
||||
|
||||
Using this short-cut will result in 'makepkg-template' replacing it with start
|
||||
and end markers and the template code on the first run.
|
||||
|
||||
Template files should be stored in one directory and filenames should be
|
||||
"$template_name-$version.template" with a symlink "$template_name.template"
|
||||
pointing to the most recent template. If the version is not set in the marker,
|
||||
'makepkg-template' will automatically use the most recent version of the
|
||||
template, otherwise the specified version will be used. This allows for easier
|
||||
verification of untrusted PKGBUILDs if the template is trusted. You verify the
|
||||
non-template code and then use a command similar to this:
|
||||
|
||||
diff -u <(makepkg-template -o -) PKGBUILD
|
||||
|
||||
Template files may also contain markers leading to nested templates in the
|
||||
resulting PKGBUILD. If you use markers in a template, please set the version
|
||||
you used/tested with in the start/input marker so other people can properly
|
||||
recreate from templates.
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
*-p, \--input* <build script>::
|
||||
Read the package script `build script` instead of the default.
|
||||
|
||||
*-o, \--output* <build script>::
|
||||
Write the updated file to `build script` instead of overwriting the input file.
|
||||
|
||||
*-n, \--newest*::
|
||||
Always use the newest available template file.
|
||||
|
||||
*\--template-dir* <dir>::
|
||||
Change the dir where we are looking for template files.
|
||||
|
||||
Example PKGBUILD
|
||||
----------------
|
||||
|
||||
pkgname=perl-config-simple
|
||||
pkgver=4.58
|
||||
pkgrel=1
|
||||
pkgdesc="simple configuration file class"
|
||||
arch=('any')
|
||||
license=('PerlArtistic' 'GPL')
|
||||
depends=('perl')
|
||||
source=("http://search.cpan.org/CPAN/authors/id/S/SH/SHERZODR/Config-Simple-${pkgver}.tar.gz")
|
||||
md5sums=('f014aec54f0a1e2e880d317180fce502')
|
||||
_distname="Config-Simple"
|
||||
|
||||
# template start; name=perl-module; version=1.0;
|
||||
_distdir="${_distname}-${pkgver}"
|
||||
url="https://metacpan.org/release/${_distname}"
|
||||
options+=('!emptydirs')
|
||||
|
||||
build() {
|
||||
cd "$srcdir/$_distdir"
|
||||
perl Makefile.PL INSTALLDIRS=vendor
|
||||
make
|
||||
}
|
||||
|
||||
check() {
|
||||
cd "$srcdir/$_distdir"
|
||||
make test
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/$_distdir"
|
||||
make DESTDIR="$pkgdir" install
|
||||
}
|
||||
# template end;
|
||||
|
||||
|
||||
|
||||
See Also
|
||||
--------
|
||||
linkman:makepkg[8], linkman:PKGBUILD[5]
|
||||
|
||||
include::footer.txt[]
|
1
scripts/.gitignore
vendored
1
scripts/.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
makepkg
|
||||
makepkg-template
|
||||
pacman-db-upgrade
|
||||
pacman-key
|
||||
pacman-optimize
|
||||
|
@ -5,6 +5,7 @@ SUBDIRS = po
|
||||
|
||||
bin_SCRIPTS = \
|
||||
$(OURSCRIPTS) \
|
||||
makepkg-template \
|
||||
repo-remove \
|
||||
repo-elephant
|
||||
|
||||
@ -18,6 +19,7 @@ OURSCRIPTS = \
|
||||
|
||||
EXTRA_DIST = \
|
||||
makepkg.sh.in \
|
||||
makepkg-template.pl.in \
|
||||
pacman-db-upgrade.sh.in \
|
||||
pacman-key.sh.in \
|
||||
pacman-optimize.sh.in \
|
||||
@ -54,6 +56,7 @@ edit = sed \
|
||||
-e 's|@PACKAGE_BUGREPORT[@]|$(PACKAGE_BUGREPORT)|g' \
|
||||
-e 's|@PACKAGE_NAME[@]|$(PACKAGE_NAME)|g' \
|
||||
-e 's|@BUILDSCRIPT[@]|$(BUILDSCRIPT)|g' \
|
||||
-e 's|@TEMPLATE_DIR[@]|$(TEMPLATE_DIR)|g' \
|
||||
-e 's|@DEBUGSUFFIX[@]|$(DEBUGSUFFIX)|g' \
|
||||
-e "s|@INODECMD[@]|$(INODECMD)|g" \
|
||||
-e 's|@SIZECMD[@]|$(SIZECMD)|g' \
|
||||
@ -76,6 +79,14 @@ makepkg: \
|
||||
$(srcdir)/makepkg.sh.in \
|
||||
$(srcdir)/library/parseopts.sh
|
||||
|
||||
makepkg-template: \
|
||||
$(srcdir)/makepkg-template.pl.in \
|
||||
Makefile
|
||||
|
||||
$(AM_V_at)$(RM) -f makepkg-template
|
||||
$(AM_V_GEN)$(edit) $< > $@
|
||||
$(AM_V_at)chmod +x,a-w $@
|
||||
|
||||
pacman-db-upgrade: \
|
||||
$(srcdir)/pacman-db-upgrade.sh.in \
|
||||
$(srcdir)/library/output_format.sh
|
||||
|
168
scripts/makepkg-template.pl.in
Executable file
168
scripts/makepkg-template.pl.in
Executable file
@ -0,0 +1,168 @@
|
||||
#!/usr/bin/perl
|
||||
use warnings;
|
||||
use strict;
|
||||
use v5.10.1;
|
||||
use Cwd qw(abs_path);
|
||||
use File::Spec;
|
||||
use Getopt::Long;
|
||||
use Pod::Usage;
|
||||
|
||||
my %opts = (
|
||||
input => '@BUILDSCRIPT@',
|
||||
template_dir => '@TEMPLATE_DIR@',
|
||||
);
|
||||
|
||||
my $template_name_charset = qr/[[:alnum:]+_.@-]/;
|
||||
my $template_marker = qr/# template/;
|
||||
|
||||
sub burp {
|
||||
my ($file_name, @lines) = @_;
|
||||
open (my $fh, ">", $file_name) || die "can't create $file_name $!" ;
|
||||
print $fh @lines;
|
||||
close $fh;
|
||||
}
|
||||
|
||||
# read a template marker line and parse values into a hash
|
||||
# format is "# template (start|input); key=value; key2=value2; ..."
|
||||
sub parse_template_line {
|
||||
my ($line, $filename, $linenumber) = @_;
|
||||
my %values;
|
||||
|
||||
my ($marker, @elements) = split(/;\s?/, $line);
|
||||
|
||||
($values{command}) = ($marker =~ /$template_marker (.*)/);
|
||||
|
||||
foreach my $element (@elements) {
|
||||
my ($key, $val) = ($element =~ /^([a-z0-9]+)=(.*)$/);
|
||||
die "invalid key/value pair $filename:$linenumber: $line"
|
||||
unless $key and $val;
|
||||
$values{$key} = $val;
|
||||
}
|
||||
|
||||
# end doesn't take arguments
|
||||
if ($values{command} ne "end") {
|
||||
if (!$values{name}) {
|
||||
die "invalid template line: can't find template name\n",
|
||||
"$filename:$linenumber: $line";
|
||||
}
|
||||
|
||||
unless ($values{name} =~ /^$template_name_charset+$/) {
|
||||
die "invalid chars used in name '$values{name}'. allowed: [:alnum:]+_.@-\n",
|
||||
"$filename:$linenumber: $line";
|
||||
}
|
||||
}
|
||||
|
||||
return \%values;
|
||||
}
|
||||
|
||||
# load a template, process possibly existing markers (nested templates)
|
||||
sub load_template {
|
||||
my ($values) = @_;
|
||||
|
||||
my $ret = "";
|
||||
|
||||
my $path;
|
||||
if (!$opts{newest} and $values->{version}) {
|
||||
$path = "$opts{template_dir}/$values->{name}-$values->{version}.template";
|
||||
} else {
|
||||
$path = "$opts{template_dir}/$values->{name}.template";
|
||||
}
|
||||
|
||||
# resolve symlink(s) and use the real file's name for version detection
|
||||
my ($version) = (abs_path($path) =~ /-([0-9.]+)[.]template$/);
|
||||
|
||||
if (!$version) {
|
||||
die "Couldn't detect version for template '$values->{name}'";
|
||||
}
|
||||
|
||||
my $parsed = process_file($path);
|
||||
|
||||
$ret .= "# template start; name=$values->{name}; version=$version;\n";
|
||||
$ret .= $parsed;
|
||||
$ret .= "# template end;\n";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
# process input file and load templates for all markers found
|
||||
sub process_file {
|
||||
my ($filename) = @_;
|
||||
|
||||
my $ret = "";
|
||||
my $nesting_level = 0;
|
||||
my $linenumber = 0;
|
||||
|
||||
open (my $fh, "<", $filename) or die "failed to open '$filename': $!";
|
||||
my @lines = <$fh>;
|
||||
close $fh;
|
||||
|
||||
foreach my $line (@lines) {
|
||||
$linenumber++;
|
||||
|
||||
if ($line =~ $template_marker) {
|
||||
my $values = parse_template_line($line, $filename, $linenumber);
|
||||
|
||||
given ($values->{command}) {
|
||||
when (['start', 'input']) {
|
||||
if ($nesting_level == 0) {
|
||||
$ret .= load_template($values);
|
||||
}
|
||||
}
|
||||
|
||||
when ('end') {
|
||||
# nothing to do here, just for completeness
|
||||
}
|
||||
|
||||
default {
|
||||
die "Unknown template marker '$values->{command}'\n",
|
||||
"$filename:$linenumber: $line";
|
||||
}
|
||||
}
|
||||
|
||||
$nesting_level++ if $values->{command} eq "start";
|
||||
$nesting_level-- if $values->{command} eq "end";
|
||||
|
||||
# marker lines should never be added
|
||||
next;
|
||||
}
|
||||
|
||||
# we replace code inside blocks with the template
|
||||
# so we ignore the content of the block
|
||||
next if $nesting_level > 0;
|
||||
|
||||
$ret .= $line;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
Getopt::Long::Configure ("bundling");
|
||||
GetOptions(
|
||||
"help" => sub {pod2usage(-exitval => 0, -verbose => 1); },
|
||||
"h" => sub {pod2usage(-exitval => 0, -verbose => 0); },
|
||||
"input|p=s" => \$opts{input},
|
||||
"output|o=s" => \$opts{output},
|
||||
"newest|n" => \$opts{newest},
|
||||
"template-dir=s" => \$opts{template_dir},
|
||||
) or pod2usage(1);
|
||||
|
||||
$opts{output} = $opts{input} unless $opts{output};
|
||||
|
||||
$opts{input} = "/dev/stdin" if $opts{input} eq "-";
|
||||
$opts{output} = "/dev/stdout" if $opts{output} eq "-";
|
||||
|
||||
burp($opts{output}, process_file($opts{input}));
|
||||
|
||||
__END__
|
||||
=head1 SYNOPSIS
|
||||
|
||||
makepkg-template [options]
|
||||
|
||||
Options:
|
||||
--input, -p <file> Build script to read (default: @BUILDSCRIPT@)
|
||||
--output, -o <file> file to output to (default: input file)
|
||||
--newest, -n update templates to newest version
|
||||
(default: use specified version in the template markers)
|
||||
--template-dir <dir> directory to search for templates
|
||||
(default: @TEMPLATE_DIR@)
|
||||
|
||||
=cut
|
||||
# vim: set noet:
|
Loading…
Reference in New Issue
Block a user