#!/bin/ksh set -e MY_NAME=$(basename "$0") MY_NAME="${MY_NAME:-kde-release-helper}" usage() { cat >&2 <&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 = $*@" \