openbsd-ports/x11/kde4/kde-release-helper
2014-12-23 14:10:36 +00:00

700 lines
16 KiB
Bash

#!/bin/ksh
set -e
MY_NAME=$(basename "$0")
MY_NAME="${MY_NAME:-kde-release-helper}"
usage() {
cat >&2 <<EOF
usage: $MY_NAME prepare new-KDE-version
$MY_NAME check-lists
$MY_NAME deps
$MY_NAME merge
$MY_NAME next
$MY_NAME new port-name [commentary ...]
$MY_NAME run
$MY_NAME show {built|packaged|status|unpackaged} [all|l10n|sc]
$MY_NAME update status
typical usecases:
$MY_NAME prepare 4.9.3
cd ../kde493
# start hacking
$MY_NAME check-lists
$MY_NAME new kdepkg some cool KDE stuff
$MY_NAME deps
$MY_NAME run
# after some progress but before committing
$MY_NAME update status
# when new KDE release is ready
$MY_NAME merge
EOF
exit 1
}
# echo-and-run
ear() {
echo "$*" >&2
"$@"
}
CLEANUP_ITEMS=
cleanup() {
test -n "$CLEANUP_ITEMS" && ear rm -Rf $CLEANUP_ITEMS
}
trap cleanup EXIT
# Files to ignore during prepare and merge stages in addition to VCS ones
IGNORE_FILES="*.port.mk $MY_NAME STATUS kde4.pkgpath"
# File containing list of KDE packages in order they should be built
DEPS_LIST=kde.deps.list
# List of options for diff(1) to make it ignore files above
diff_ignore_opts() {
for F in ${IGNORE_FILES}; do
echo -n " -x $F"
done
}
# Arg: KDE version in X.Y.Z format
# Output: kdeXYZ
kde_port_dir() {
if ! echo "$1" | egrep -q '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "$1 is not a valid KDE version (X.Y.Z)" >&2
exit 1
fi
echo "kde$1" | tr -d '.'
}
# List all ports (subdirectories) in current directory.
# Assume we're in KDE ports root directory.
# Output does not include l10n, see list_l10n_ports() below.
list_local_ports() {
ls | while read P; do
# Test for being directory for safety in case of symlinks
test X"$P" != Xl10n -a \
X"$P" != Xtemplate -a \
-d "$P" \
-a -e "$P"/Makefile || continue
echo "$P"
done
}
# Assume we're in KDE ports root directory.
# Input: list of subdirectories.
# Output: list of distribution names.
port_dir_to_distname() {
while read D; do
(cd $D && make show=DISTNAME)
done | sed -Ee 's@-([0-9]|\$).*@@' | sort
}
# Assume we're in KDE ports root directory.
list_l10n_ports() {
test -d l10n || return 0
for L in $(cd l10n/ru && make show=ALL_LANGS); do
echo "kde-l10n-${L}"
done | sort
}
# Assume we're in KDE ports root directory.
list_l10n_ports_dirs() {
test -d l10n || return 0
for L in $(cd l10n/ru && make show=ALL_LANGS); do
echo "l10n/$L"
done | sort
}
# Assume we're in the apporiate port's directory
list_remote_source() {
local LIST URL
local V=`make show=MODKDE4_VERSION`
for URL in $(make MASTER_SITE_BACKUP= show=MASTER_SITES); do
echo "$URL" | grep -q '^ftp://' || continue
LIST="$(ear curl -sl $URL |
sed -e s@-${V}.*@@ |
grep -v '^\.' |
sort)" || continue
test `echo -n "$LIST" | wc -l` -gt 1 || continue
echo "$LIST"
return 0
done
echo "Could not retrieve source files list." >&2
echo "Probably more FTP servers with NLIST command supported" >&2
echo "are needed in MASTER_SITES." >&2
return 1
}
# Assume the same as list_remote_source().
# Input: sorted local list of ports.
# Output: list of new ports prefixed with "+"
compare_sources_lists() {
T="`mktemp -t srccomp.XXXXXXXX`"
OCLEANUP_ITEMS="$CLEANUP_ITEMS"
CLEANUP_ITEMS="$CLEANUP_ITEMS $T"
list_remote_source >"$T"
test -s "$T" && diff -u - "$T" || true
rm "$T"
CLEANUP_ITEMS="$OCLEANUP_ITEMS"
}
# Assume we're in KDE ports root directory.
kde_version() {
(cd libs && make show=MODKDE4_VERSION)
}
# Arguments: port, status
print_status_line() {
printf '%-32s%s\n' "$1" "$2"
}
is_started() {
test -d "`cd $1 && make show=WRKSRC`"
}
is_configured() {
test -e "`cd $1 && make show=_CONFIGURE_COOKIE`"
}
is_built() {
test -e "`cd $1 && make show=_BUILD_COOKIE`"
}
is_tested() {
test -e "`cd $1 && make show=_TEST_COOKIE`"
}
is_packaged() {
local P F FOUND FLAVORS=`cd $1 && make show=FLAVORS`
for P in `cd $1 && make show=BUILD_PACKAGES`; do
FOUND=
for F in "" ${FLAVORS}; do
if [ -e "`cd $1 && SUBPACKAGE=$P FLAVOR=$F make show=PKGFILE`" ]; then
FOUND=Y
break
fi
done
test -n "$FOUND" || return 1
done
return 0
}
is_locked() {
# LOCKDIR could be empty, see ports(7)
LOCKDIR="${LOCKDIR:-X`cd $1 && make show=LOCKDIR`}"
if [ "$LOCKDIR" != X ]; then
test -e "${LOCKDIR#X}/`cd $1 && make show=FULLPKGNAME`.lock"
else
# XXX Better detection mechanizm?
false
fi
}
# Argument: KDE version in X.Y.Z format.
is_stable_ver() {
# KDE alpha/beta/etc. versions start from 80
test 80 -gt `echo $1 | sed -E 's/^.*\.([0-9]+)$/\1/'`
}
expand_port_list() {
case ${1:-all} in
all)
list_local_ports
list_l10n_ports_dirs
;;
sc)
list_local_ports
;;
l10n)
list_l10n_ports_dirs
;;
*)
usage
;;
esac
}
### Main actions go here
prepare() {
test $# -eq 1 || usage
if ! [ -f ../kde4/kde4.port.mk -a X"`cd .. && basename $(pwd)`" = Xx11 ]; then
echo "Please run $MY_NAME from KDE 4 directory in ports tree" >&2
exit 2
fi
local NEW_KDE_PORT_VER=$1; shift
local CUR_KDE_PORT_VER=`kde_version`
cd ..
local NEW_KDE_PORT_DIR=`kde_port_dir "$NEW_KDE_PORT_VER"`
if [ -e $NEW_KDE_PORT_DIR ]; then
echo "x11/$NEW_KDE_PORT_DIR already exists" >&2
exit 2
fi
echo '==> copying ports directory' >&2
CLEANUP_ITEMS="$CLEANUP_ITEMS $NEW_KDE_PORT_DIR"
cp -R "$OLDPWD" $NEW_KDE_PORT_DIR
local LOCAL_PORTS=`cd $NEW_KDE_PORT_DIR && list_local_ports`
echo '==> removing extra files' >&2
for F in $IGNORE_FILES; do ear rm -f $NEW_KDE_PORT_DIR/$F; done
find $NEW_KDE_PORT_DIR -name 'PLIST*.orig' -print0 | xargs -0rt rm
if is_stable_ver $NEW_KDE_PORT_VER; then
if is_stable_ver $CUR_KDE_PORT_VER; then
# just mark distinfo missing
ear rm -f $NEW_KDE_PORT_DIR/l10n/distinfo
else
# need to copy l10n back from some stable directory
ear mkdir -p $NEW_KDE_PORT_DIR/l10n
ear cp -R kde4/l10n/* $NEW_KDE_PORT_DIR/l10n
fi
else
# Unstable KDE versions usually lacks l10n.
# And if not, we don't care either, they will not
# hit the CVS anyway.
ear rm -Rf $NEW_KDE_PORT_DIR/l10n
fi
for P in $LOCAL_PORTS; do
ear rm -f $NEW_KDE_PORT_DIR/$P/distinfo
done
echo '==> removing REVISION marks' >&2
for P in $LOCAL_PORTS; do
local OCLEANUP_ITEMS="$CLEANUP_ITEMS"
CLEANUP_ITEMS="$CLEANUP_ITEMS $NEW_KDE_PORT_DIR/$P/Makefile.orig"
perl -ni.orig -e '/^REVISION/ or print' $NEW_KDE_PORT_DIR/$P/Makefile
cmp -s $NEW_KDE_PORT_DIR/$P/Makefile{.orig,} || echo $P
rm $NEW_KDE_PORT_DIR/$P/Makefile.orig
CLEANUP_ITEMS="$OCLEANUP_ITEMS"
done
echo '==> patching Makefile.inc' >&2
local MI=$NEW_KDE_PORT_DIR/Makefile.inc
local T=`mktemp -u "$MI".XXXXXXXXXXX`
OCLEANUP_ITEMS="$CLEANUP_ITEMS"
CLEANUP_ITEMS="$CLEANUP_ITEMS $T"
local MSPATCH OSTABLE=stable NSTABLE=stable
is_stable_ver $CUR_KDE_PORT_VER || OSTABLE=unstable
is_stable_ver $NEW_KDE_PORT_VER || NSTABLE=unstable
if [[ $OSTABLE = $NSTABLE ]]; then
MSPATCH=cat
else
MSPATCH="sed /MASTER_SITES/s@${OSTABLE}/@${NSTABLE}/@"
fi
awk "
/^MODKDE4_FLAVOR[[:space:]]*:?=/ {
print \"MODKDE4_FLAVOR = ${NEW_KDE_PORT_DIR}\";
VL = 1;
}
{
if (VL) {
VL = 0;
} else {
print;
}
}
" <"$MI" | $MSPATCH >"$T"
if ! grep -q ^MODKDE4_FLAVOR "$T"; then
# MODKDE4_FLAVOR could be missing
echo "MODKDE4_FLAVOR = $NEW_KDE_PORT_DIR" >>"$T"
fi
mv "$T" "$MI"
if ! is_stable_ver $NEW_KDE_PORT_VER; then
echo '==> patching Makefile' >&2
sed -Ee '/^SUBDIR[[:space:]]*\+=[[:space:]]*l10n/d' \
<$NEW_KDE_PORT_DIR/Makefile >"$T"
mv "$T" $NEW_KDE_PORT_DIR/Makefile
fi
CLEANUP_ITEMS="$OCLEANUP_ITEMS"
set -x
echo '==> adjusting the kde-shared-data port' >&2
perl -ni.pre-$NEW_KDE_PORT_DIR -e "print; if (/^\\s*MASTER_SITES0/) {
print \"DISTFILES += kde-runtime-${NEW_KDE_PORT_VER}.tar.xz:1\\n\";
print \"MASTER_SITES1 = \\\${MASTER_SITE_KDE:=${NSTABLE}/${NEW_KDE_PORT_VER}/src/}\\n\";
}" kde-shared-data/Makefile
set +x
echo "==> creating STATUS" >&2
for P in $LOCAL_PORTS `list_l10n_ports_dirs`; do
print_status_line $P WAITING \
>>${NEW_KDE_PORT_DIR}/STATUS
done
# Avoid removing newly created directory
CLEANUP_ITEMS=
}
check_lists() {
test $# -eq 0 || usage
echo '==> checking for new source packages' >&2
list_local_ports |
port_dir_to_distname |
(cd libs && compare_sources_lists) |
egrep '^[\+-][^\+-]' |
grep -v '^+kde-l10n' || true
test -d l10n || return 0
echo '==> checking for l10n package list changes' >&2
list_l10n_ports |
(cd l10n/ru && compare_sources_lists) |
egrep '^[\+-][^\+-]' || true
}
build_deps_list() {
test $# -eq 0 || usage
local KDEDIR=$(kde_port_dir `kde_version`)
local P BDEPS DEP DEP2 T
T=$(mktemp ${DEPS_LIST}.XXXXXXXX)
OCLEANUP_ITEMS="$CLEANUP_ITEMS"
CLEANUP_ITEMS="$CLEANUP_ITEMS $T"
echo "===> Gathering lists of KDE ports packaged or being built" >&2
for P in `list_local_ports; list_l10n_ports_dirs`; do
# normalize build dependencies list by removing all but pkgpath
BDEPS=$(cd $P && make show="BUILD_DEPENDS LIB_DEPENDS" |
sed -E -e 's@[^[:space:]]+:@@g' -e 's@[<>=].*@@')
# take care of KDE SC dependencies only
for DEP2 in $BDEPS; do
echo "$DEP2"
done |
fgrep "x11/${KDEDIR}/" |
sed -e "s%x11/${KDEDIR}/%%" -e 's%,.*%%' -e "s%\$% ${P}%"
done | sort -u >"$T"
mv -- "$T" "$DEPS_LIST"
CLEANUP_ITEMS="$OCLEANUP_ITEMS"
}
choose_next() {
test $# -eq 0 || usage
local P
tsort <"$DEPS_LIST" | while read P; do
is_packaged $P && continue
is_locked $P && continue
if is_built $P; then
echo "# $P was built"
echo "(cd $P && make update-plist) && \\"
echo "(cd $P && make port-lib-depends-check) && \\"
echo "(cd $P && make package)"
elif is_configured $P; then
echo "# $P was configured"
echo "(cd $P && make build)"
elif is_started $P; then
echo "# $P was started"
echo "(cd $P && make configure)"
else
echo "# $P was not started"
echo "(cd $P && make patch)"
fi
break
done
}
new_port() {
test $# -ge 1 || usage
NEW_P=$1; shift
mkdir "$NEW_P" "$NEW_P"/pkg
sed -e "s@XYZ@${NEW_P}@g" \
-e "s@^COMMENT.*@COMMENT = $*@" \
<template/Makefile \
>"$NEW_P"/Makefile
echo "Now run:" >&2
exec ${VISUAL:-${EDITOR:-vi}} $NEW_P/Makefile
}
merge_back() {
test $# -eq 0 || usage
# Avoid erroring out here, we'll print a nicer message below.
local SKDEV=`cd libs && make show=_MODKDE4_STABLE || true`
local KDEV=`cd libs && make show=MODKDE4_VERSION || true`
if [ -e STATUS ] && egrep -v 'PACKAGED$' STATUS; then
echo "Not all KDE SC $KDEV stuff looks like packaged" >&2
exit 2
fi
if [ -f kde4.port.mk -o X"`cd .. && basename $(pwd)`" != Xx11 -o \
X"$KDEV" = X ]; then
echo "Please run $MY_NAME from directory with KDE4 ports being tested" >&2
exit 2
fi
local SKDED=$(kde_port_dir $SKDEV)
local KDED=$(kde_port_dir $KDEV)
if [ -e ../$SKDED ]; then
echo "The x11/$SKDED directory already exists" >&2
exit 2
fi
cd ..
echo '==> patching Makefile.inc' >&2
perl -ni -e 'm@^ *MODKDE4_FLAVOR@ or print' ${KDED}/Makefile.inc
echo '==> moving directories' >&2
mv kde4 $SKDED
mv $KDED kde4
echo '==> adjusting the kde-shared-data port' >&2
perl -ni -e "
m@^ *DISTFILES\\s*\\+=\\s*kde-runtime-${KDED}\.@ or
m@^ *MASTER_SITES[1-9]\\s*=.*/${KDEV}/@ or
m@^ REVISION\\s*=@ or
print" kde-shared-data/Makefile
(cd kde-shared-data && make makesum)
echo '==> removing REVISIONs from meta/kde4' >&2
local METAKDE=../meta/kde4
test -d "$METAKDE" || METAKDE="../$METAKDE"
test -d "$METAKDE" || METAKDE="../$METAKDE"
test -d "$METAKDE" || {
echo "===> meta/kde4 directory wasn't found" >&2
return
}
perl -ni -e "/^ *REVISION/ or print" "$METAKDE/Makefile"
}
run_job() {
test $# -eq 0 || usage
for P in `list_local_ports`; do
if is_packaged $P || is_locked $P; then
continue
fi
echo "==> Working on port $P" >&2
if is_built $P; then
local TARGETS=
if ! ls $P/pkg/PLIST*.orig >/dev/null 2>&1; then
TARGETS=update-plist
fi
TARGETS="$TARGETS port-lib-depends-check package"
TARGETS="$TARGETS lib-depends-check install clean"
(cd $P && make $TARGETS)
elif is_configured $P; then
(cd $P && make build)
elif is_started $P; then
(cd $P && make configure)
else
(cd $P && make makesum prepare)
fi
done
}
# Assume to be running in KDE4 ports directory
show_status() {
local P T V PORTLIST=$(expand_port_list "$1")
V="`kde_version`"
for P in $PORTLIST; do
if is_packaged $P; then
print_status_line $P PACKAGED
elif is_built $P; then
print_status_line $P BUILT
elif is_configured $P; then
print_status_line $P CONFIGURED
elif is_started $P; then
print_status_line $P STARTED
else
print_status_line $P WAITING
fi
done
}
show() {
test $# -ge 1 -a $# -le 2 || usage
if ! [ -f ../kde4/kde4.port.mk -a \
X"`cd .. && basename $(pwd)`" = Xx11 ]; then
echo "Please run $MY_NAME from a KDE 4 directory in ports tree" >&2
exit 2
fi
local P WHAT PORTLIST=$(expand_port_list "$2")
WHAT=$1; shift
case $WHAT in
c|co|con|conf|confi|config|configu|configur|configure|configured)
for P in $PORTLIST; do
is_configured $P && echo $P
done
;;
b|bu|bui|buil|built)
for P in $PORTLIST; do
is_built $P && echo $P
done
;;
p|pa|pac|pack|packa|packag|package|packaged)
for P in $PORTLIST; do
is_packaged $P && echo $P
done
;;
s|st|sta|stat|statu|status)
show_status "$@"
;;
u|un|unp|unpa|unpac|unpack|unpacka|unpackag|unpackage|unpackaged)
for P in $PORTLIST; do
is_packaged $P || echo $P
done
;;
*)
usage
esac
true
}
update_status() {
test $# -eq 0 || usage
local V=`kde_version`
local T="`mktemp -u STATUS.XXXXXXXX`"
local OCLEANUP_ITEMS="$CLEANUP_ITEMS"
CLEANUP_ITEMS="$T $CLEANUP_ITEMS"
if [ -e "STATUS" ]; then
echo "===> Updating status of KDE $V porting"
local P S
show_status all | awk "
BEGIN {
while (getline L <\"STATUS\") {
split(L, PARTS);
STATUS[PARTS[1]] = PARTS[2];
}
# From most to least useful, the latest one isn't actually needed now.
STATUSES[1] = \"PACKAGED\";
STATUSES[2] = \"BUILT\";
STATUSES[3] = \"CONFIGURED\";
STATUSES[4] = \"STARTED\";
#STATUSES[5] = \"WAITING\";
# We cannot use 'for(... in STATUSES)' because it doesn't restart
# on every loop, but starts cycling items from the position where
# previous loop was interrupted.
NSTATUSES = 4
}
/^([[:space:]]*#.*)?\$/ {
next;
}
{
for (I = 1; I < NSTATUSES; I++) {
S = STATUSES[I];
if (STATUS[\$1] == S || \$2 == S) {
printf(\"%-32s%s\\n\", \$1, S);
next;
}
}
printf(\"%-32s%s\\n\", \$1, \"WAITING\");
}
" | tee "$T"
else
echo "===> Old status file missing, recreating"
show_status "$WHAT" | tee "$T"
fi
mv "$T" "STATUS"
CLEANUP_ITEMS="$OCLEANUP_ITEMS"
}
update_l10n() {
local d dirs l parargs
if [[ $# -gt 0 && $1 == @([0-9]) ]]; then
parargs="-j $1"
fi
if [ $# -eq 0 ]; then
dirs=$(list_l10n_ports_dirs)
else
dirs=
for l; do
dirs="$dirs l10n/$l"
done
fi
for d in $dirs; do
echo SUBDIR=$d
done | parallel $parargs make DANGEROUS=Yes update-plist
}
update() {
test $# -ge 1 || usage
if ! [ -f ../kde4/kde4.port.mk -a \
X"`cd .. && basename $(pwd)`" = Xx11 ]; then
echo "Please run $MY_NAME from a KDE 4 directory in ports tree" >&2
exit 2
fi
local CMD=$1; shift
case $CMD in
l|l1|l10|l10n)
update_l10n "$@"
;;
s|st|sta|stat|statu|status)
update_status "$@"
;;
*)
usage
;;
esac
}
# All actions take (at least) one argument
test $# -ge 1 || usage
ACTION=$1; shift
case $ACTION in
p|pr|pre|prep|prepa|prepar|prepare)
prepare "$@"
;;
check-l|check-li|check-lis|check-list|check-lists)
check_lists "$@"
;;
d|de|dep|deps)
build_deps_list "$@"
;;
m|me|mer|merg|merge)
merge_back "$@"
;;
nex|next)
choose_next "$@"
;;
new)
new_port "$@"
;;
r|ru|run)
run_job "$@"
;;
s|sh|sho|show)
show "$@"
;;
u|up|upd|upda|updat|update)
update "$@"
;;
esac