summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/.gitignore1
-rw-r--r--scripts/Makefile.am11
-rwxr-xr-xscripts/makepkg-template.pl.in212
-rw-r--r--scripts/makepkg.sh.in95
-rw-r--r--scripts/po/POTFILES.in1
-rw-r--r--scripts/repo-add.sh.in12
6 files changed, 277 insertions, 55 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 9e403bfb..26e088b9 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,4 +1,5 @@
makepkg
+makepkg-template
pacman-db-upgrade
pacman-key
pacman-optimize
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 784b1802..1f3bae24 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -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
diff --git a/scripts/makepkg-template.pl.in b/scripts/makepkg-template.pl.in
new file mode 100755
index 00000000..567514e1
--- /dev/null
+++ b/scripts/makepkg-template.pl.in
@@ -0,0 +1,212 @@
+#!/usr/bin/perl
+# makepkg-template - template system for makepkg
+# @configure_input@
+#
+# Copyright (c) 2013 Pacman Development Team <pacman-dev@archlinux.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+use warnings;
+use strict;
+use v5.10.1;
+use Cwd qw(abs_path);
+use Getopt::Long;
+use Module::Load;
+use Module::Load::Conditional qw(can_load);
+
+my %opts = (
+ input => '@BUILDSCRIPT@',
+ template_dir => '@TEMPLATE_DIR@',
+);
+
+my $template_name_charset = qr/[[:alnum:]+_.@-]/;
+my $template_marker = qr/# template/;
+
+# 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) {
+ Locale::gettext::bindtextdomain("pacman-scripts", '@localedir@');
+ Locale::gettext::textdomain("pacman-scripts");
+}
+
+sub gettext {
+ my ($string) = @_;
+
+ if ($loaded_gettext) {
+ return Locale::gettext::gettext($string);
+ } else {
+ return $string;
+ }
+}
+
+sub burp {
+ my ($file_name, @lines) = @_;
+ open (my $fh, ">", $file_name) || die sprintf(gettext("can't create '%s': %s"), $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]+)=(.*)$/);
+ unless ($key and $val) {
+ die gettext("invalid key/value pair\n%s:%s: %s"),
+ "$filename:$linenumber: $line";
+ }
+ $values{$key} = $val;
+ }
+
+ # end doesn't take arguments
+ if ($values{command} ne "end") {
+ if (!$values{name}) {
+ die gettext("invalid template line: can't find template name\n"),
+ "$filename:$linenumber: $line";
+ }
+
+ unless ($values{name} =~ /^$template_name_charset+$/) {
+ die sprintf(gettext("invalid chars used in name '%s'. allowed: [:alnum:]+_.\@-\n"), $values{name}),
+ "$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 sprintf(gettext("Couldn't detect version for template '%s'"), $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 sprintf(gettext("failed to open '%s': %s"), $filename, $!);
+ my @lines = <$fh>;
+ close $fh;
+
+ foreach my $line (@lines) {
+ $linenumber++;
+
+ if ($line =~ $template_marker) {
+ my $values = parse_template_line($line, $filename, $linenumber);
+
+ if ($values->{command} eq "start" or $values->{command} eq "input") {
+ if ($nesting_level == 0) {
+ $ret .= load_template($values);
+ }
+ } elsif ($values->{command} eq "end") {
+ # nothing to do here, just for completeness
+ } else {
+ die sprintf(gettext("Unknown template marker '%s'\n"), $values->{command}),
+ "$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;
+}
+
+sub usage {
+ my ($exitstatus) = @_;
+ print gettext("makepkg-template [options]\n");
+ print "\n";
+ print gettext("Options:\n");
+ printf(gettext(" --input, -p <file> Build script to read (default: %s)\n"), '@BUILDSCRIPT@');
+ print gettext(" --output, -o <file> file to output to (default: input file)\n");
+ print gettext(" --newest, -n update templates to newest version\n");
+ print gettext(" (default: use version specified in the template markers)\n");
+ print gettext(" --template-dir <dir> directory to search for templates\n");
+ printf(gettext(" (default: %s)\n"), '@TEMPLATE_DIR@');
+ print gettext(" --help, -h This help message\n");
+ print gettext(" --version Version information\n");
+ print "\n";
+ exit($exitstatus);
+}
+
+sub version {
+ my ($exitstatus) = @_;
+ printf "makepkg-template (pacman) %s\n", '@PACKAGE_VERSION@';
+ print gettext(
+ 'Copyright (c) 2013 Pacman Development Team <pacman-dev@archlinux.org>.'."\n".
+ 'This is free software; see the source for copying conditions.'."\n".
+ 'There is NO WARRANTY, to the extent permitted by law.'."\n");
+ exit($exitstatus);
+}
+
+Getopt::Long::Configure ("bundling");
+GetOptions(
+ "help|h" => sub {usage(0); },
+ "version" => sub {version(0); },
+ "input|p=s" => \$opts{input},
+ "output|o=s" => \$opts{output},
+ "newest|n" => \$opts{newest},
+ "template-dir=s" => \$opts{template_dir},
+) or usage(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}));
+
+# vim: set noet:
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 02f5a02d..2a391575 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -2095,6 +2095,10 @@ install_package() {
fi
}
+have_function() {
+ declare -f "$1" >/dev/null
+}
+
check_sanity() {
# check for no-no's in the build script
local i
@@ -2240,9 +2244,14 @@ check_sanity() {
ret=1
fi
- if (( ${#pkgname[@]} > 1 )); then
+ if (( ${#pkgname[@]} == 1 )); then
+ if have_function build && ! ( have_function package || have_function package_${pkgname}); then
+ error "$(gettext "Missing %s function in %s")" "package()" "$BUILDFILE"
+ ret=1
+ fi
+ else
for i in ${pkgname[@]}; do
- if ! declare -f package_${i} >/dev/null; then
+ if ! have_function package_${i}; then
error "$(gettext "Missing %s function for split package '%s'")" "package_$i()" "$i"
ret=1
fi
@@ -2510,6 +2519,7 @@ usage() {
printf -- "$(gettext " --holdver Do not update VCS sources")\n"
printf -- "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg"
printf -- "$(gettext " --nocheck Do not run the %s function in the %s")\n" "check()" "$BUILDSCRIPT"
+ printf -- "$(gettext " --noprepare Do not run the %s function in the %s")\n" "prepare()" "$BUILDSCRIPT"
printf -- "$(gettext " --nosign Do not create a signature for the package")\n"
printf -- "$(gettext " --pkg <list> Only build listed packages from a split package")\n"
printf -- "$(gettext " --sign Sign the resulting package with %s")\n" "gpg"
@@ -2552,7 +2562,7 @@ ARGLIST=("$@")
OPT_SHORT="AcdefFghiLmop:rRsSV"
OPT_LONG=('allsource' 'asroot' 'check' 'clean' 'config:' 'force' 'geninteg'
'help' 'holdver' 'ignorearch' 'install' 'key:' 'log' 'nobuild' 'nocolor'
- 'nocheck' 'nodeps' 'noextract' 'nosign' 'pkg:' 'repackage' 'rmdeps'
+ 'nocheck' 'nodeps' 'noextract' 'noprepare' 'nosign' 'pkg:' 'repackage' 'rmdeps'
'sign' 'skipchecksums' 'skipinteg' 'skippgpcheck' 'source' 'syncdeps'
'verifysource' 'version')
@@ -2591,6 +2601,7 @@ while true; do
-L|--log) LOGGING=1 ;;
-m|--nocolor) USE_COLOR='n' ;;
--nocheck) RUN_CHECK='n' ;;
+ --noprepare) RUN_PREPARE='n' ;;
--nosign) SIGNPKG='n' ;;
-o|--nobuild) NOBUILD=1 ;;
-p) shift; BUILDFILE=$1 ;;
@@ -2631,6 +2642,7 @@ trap 'trap_exit USR1 "$(gettext "An unknown error has occurred. Exiting...")"' E
[[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT}
[[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY}
[[ -n ${PACKAGER} ]] && _PACKAGER=${PACKAGER}
+[[ -n ${CARCH} ]] && _CARCH=${CARCH}
# default config is makepkg.conf
MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf}
@@ -2667,12 +2679,12 @@ if [[ -t 2 && ! $USE_COLOR = "n" ]] && check_buildenv "color" "y"; then
RED="${BOLD}$(tput setaf 1)"
YELLOW="${BOLD}$(tput setaf 3)"
else
- ALL_OFF="\e[1;0m"
- BOLD="\e[1;1m"
- BLUE="${BOLD}\e[1;34m"
- GREEN="${BOLD}\e[1;32m"
- RED="${BOLD}\e[1;31m"
- YELLOW="${BOLD}\e[1;33m"
+ ALL_OFF="\e[0m"
+ BOLD="\e[1m"
+ BLUE="${BOLD}\e[34m"
+ GREEN="${BOLD}\e[32m"
+ RED="${BOLD}\e[31m"
+ YELLOW="${BOLD}\e[33m"
fi
fi
readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
@@ -2730,6 +2742,7 @@ PKGEXT=${_PKGEXT:-$PKGEXT}
SRCEXT=${_SRCEXT:-$SRCEXT}
GPGKEY=${_GPGKEY:-$GPGKEY}
PACKAGER=${_PACKAGER:-$PACKAGER}
+CARCH=${_CARCH:-$CARCH}
if (( ! INFAKEROOT )); then
if (( EUID == 0 && ! ASROOT )); then
@@ -2762,17 +2775,10 @@ unset makedepends optdepends options noextract
BUILDFILE=${BUILDFILE:-$BUILDSCRIPT}
if [[ ! -f $BUILDFILE ]]; then
- if [[ -t 0 ]]; then
- error "$(gettext "%s does not exist.")" "$BUILDFILE"
- exit 1
- else
- # PKGBUILD passed through a pipe
- BUILDFILE=/dev/stdin
- source_safe "$BUILDFILE"
- fi
+ error "$(gettext "%s does not exist.")" "$BUILDFILE"
+ exit 1
else
- crlftest=$(file "$BUILDFILE" | grep -F 'CRLF' || true)
- if [[ -n $crlftest ]]; then
+ if [[ $(<"$BUILDFILE") = *$'\r'* ]]; then
error "$(gettext "%s contains %s characters and cannot be sourced.")" "$BUILDFILE" "CRLF"
exit 1
fi
@@ -2808,7 +2814,7 @@ if (( GENINTEG )); then
exit 0 # $E_OK
fi
-if declare -f pkgver >/dev/null; then
+if have_function pkgver; then
PKGVERFUNC=1
fi
@@ -2823,21 +2829,24 @@ if (( ${#pkgname[@]} > 1 )); then
fi
# test for available PKGBUILD functions
-if declare -f prepare >/dev/null; then
- PREPAREFUNC=1
+if have_function prepare; then
+ # "Hide" prepare() function if not going to be run
+ if [[ $RUN_PREPARE != "n" ]]; then
+ PREPAREFUNC=1
+ fi
fi
-if declare -f build >/dev/null; then
+if have_function build; then
BUILDFUNC=1
fi
-if declare -f check >/dev/null; then
+if have_function check; then
# "Hide" check() function if not going to be run
if [[ $RUN_CHECK = 'y' ]] || { ! check_buildenv "check" "n" && [[ $RUN_CHECK != "n" ]]; }; then
CHECKFUNC=1
fi
fi
-if declare -f package >/dev/null; then
+if have_function package; then
PKGFUNC=1
-elif [[ $SPLITPKG -eq 0 ]] && declare -f package_${pkgname} >/dev/null; then
+elif [[ $SPLITPKG -eq 0 ]] && have_function package_${pkgname}; then
SPLITPKG=1
fi
@@ -2875,17 +2884,7 @@ if (( INFAKEROOT )); then
if (( ! SPLITPKG )); then
pkgdir="$pkgdirbase/$pkgname"
mkdir "$pkgdir"
- if (( ! PKGFUNC )); then
- if (( ! REPKG )); then
- if (( BUILDFUNC )); then
- run_build
- (( CHECKFUNC )) && run_check
- fi
- else
- warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
- plain "$(gettext "File permissions may not be preserved.")"
- fi
- else
+ if (( PKGFUNC )); then
run_package
fi
tidy_install
@@ -2902,10 +2901,6 @@ fi
fullver=$(get_full_version)
msg "$(gettext "Making package: %s")" "$pkgbase $fullver ($(date))"
-if (( !PKGFUNC && !SPLITPKG )); then
- warning "$(gettext "Using a %s without a %s function is deprecated.")" "$BUILDSCRIPT" "package()"
-fi
-
# if we are creating a source-only package, go no further
if (( SOURCEONLY )); then
if [[ -f $SRCPKGDEST/${pkgbase}-${fullver}${SRCEXT} ]] \
@@ -2983,14 +2978,7 @@ cd_safe "$srcdir"
if (( NOEXTRACT && ! VERIFYSOURCE )); then
warning "$(gettext "Using existing %s tree")" "src/"
-elif (( REPKG )); then
- if (( ! PKGFUNC && ! SPLITPKG )) \
- && { [[ ! -d $pkgdirbase ]] || dir_is_empty "$pkgdirbase"; }; then
- error "$(gettext "The package directory is empty, there is nothing to repackage!")"
- plain "$(gettext "Aborting...")"
- exit 1
- fi
-else
+elif (( !REPKG )); then
download_sources
check_source_integrity
(( VERIFYSOURCE )) && exit 0 # $E_OK
@@ -3004,8 +2992,8 @@ if (( NOBUILD )); then
msg "$(gettext "Sources are ready.")"
exit 0 #E_OK
else
- # check for existing pkg directory; don't remove if we are repackaging
- if [[ -d $pkgdirbase ]] && (( ! REPKG || PKGFUNC || SPLITPKG )); then
+ # clean existing pkg directory
+ if [[ -d $pkgdirbase ]]; then
msg "$(gettext "Removing existing %s directory...")" "pkg/"
rm -rf "$pkgdirbase"
fi
@@ -3029,9 +3017,6 @@ else
mkdir -p "$pkgdir"
if (( PKGFUNC )); then
run_package
- elif (( REPKG )); then
- warning "$(gettext "Repackaging without the use of a %s function is deprecated.")" "package()"
- plain "$(gettext "File permissions may not be preserved.")"
fi
tidy_install
create_package
@@ -3040,7 +3025,7 @@ else
run_split_packaging
fi
else
- if (( ! REPKG && ( PKGFUNC || SPLITPKG ) )); then
+ if (( ! REPKG )); then
(( BUILDFUNC )) && run_build
(( CHECKFUNC )) && run_check
cd_safe "$startdir"
diff --git a/scripts/po/POTFILES.in b/scripts/po/POTFILES.in
index 162731b9..f9e8a481 100644
--- a/scripts/po/POTFILES.in
+++ b/scripts/po/POTFILES.in
@@ -2,6 +2,7 @@
# scripts with gettext translations
scripts/makepkg.sh.in
+scripts/makepkg-template.pl.in
scripts/pacman-db-upgrade.sh.in
scripts/pacman-key.sh.in
scripts/pacman-optimize.sh.in
diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in
index 4470dd0a..a9a4499b 100644
--- a/scripts/repo-add.sh.in
+++ b/scripts/repo-add.sh.in
@@ -31,6 +31,7 @@ declare -r confdir='@sysconfdir@'
QUIET=0
DELTA=0
ONLYADDNEW=0
+RMEXISTING=0
WITHFILES=0
SIGN=0
VERIFY=0
@@ -58,6 +59,7 @@ Multiple packages to add can be specified on the command line.\n")"
printf -- "$(gettext "Options:\n")"
printf -- "$(gettext " -d, --delta generate and add delta for package update\n")"
printf -- "$(gettext " -n, --new only add packages that are not already in the database\n")"
+ printf -- "$(gettext " -R, --remove remove package file from disk when updating database entry\n")"
printf -- "$(gettext " -f, --files update database's file list\n")"
elif [[ $cmd == "repo-remove" ]] ; then
printf -- "$(gettext "Usage: repo-remove [options] <path-to-db> <packagename|delta> ...\n")"
@@ -304,6 +306,15 @@ db_write_entry() {
local oldfilename=$(grep -A1 FILENAME "$pkgentry/desc" | tail -n1)
local oldfile="$(dirname "$1")/$oldfilename"
fi
+ elif (( RMEXISTING )); then
+ # only remove existing package if we're not doing deltas
+ pkgentry=$(find_pkgentry "$pkgname")
+ if [[ -n $pkgentry ]]; then
+ local oldfilename="$(sed -n '/^%FILENAME%$/ {n;p;q;}' "$pkgentry/desc")"
+ local oldfile="$(dirname "$1")/$oldfilename"
+ msg2 "$(gettext "Removing existing package '%s'")" "$oldfilename"
+ rm -f ${oldfile} ${oldfile}.sig
+ fi
fi
fi
@@ -611,6 +622,7 @@ while (( $# )); do
-q|--quiet) QUIET=1;;
-d|--delta) DELTA=1;;
-n|--new) ONLYADDNEW=1;;
+ -R|--remove) RMEXISTING=1;;
-f|--files) WITHFILES=1;;
--nocolor) USE_COLOR='n';;
-s|--sign)