Bug#797045: [uupdate] offer alternative command addressing all the bugs

Osamu Aoki osamu at debian.org
Thu Aug 27 10:02:05 UTC 2015


Package: devscripts
Version: 2.15.3
Severity: wishlist
File: /usr/bin/uupdate

This is still applicable to 2.15.8.

The current uupdate does not use elaborate packaging tricks dpkg-source
implemented.  As I mentioned in https://bugs.debian.org/752364
alternative approach may be good idea.

Here is a proof of concept code I wrote to support multiple upstream
tarball.

Please note calling convention and its name are intentionally changed.
So when testing this, please be careful.

Please see "./uupdate2 --help" how this command works.

This command should solve all the reported issues on uupdate in
principle.
 #278797 add option to remove any upstream debian directory before patching
 (I know this is not exactly as requested but should offer trouble free
  workflow.)
 #544638 Support ~ in package versions
 #570221 not possible to create source package with lower version number
 #752364 Should support multiple source archives

Update of uscan is desirable to have smooth transition.  That should be
matched to watch version=4 which explicitly support multiple upstream
tarballs.

Osamu

-- Package-specific info:

--- /etc/devscripts.conf ---

--- ~/.devscripts ---
DEBUILD_DPKG_BUILDPACKAGE_OPTS="-i -us -uc"
DEBUILD_LINTIAN_OPTS="-i -I --show-overrides"
DEBSIGN_KEYID="1DD8D791"

-- System Information:
Debian Release: 8.1
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'proposed-updates'), (500, 'stable'), (99, 'testing'), (98, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages devscripts depends on:
ii  dpkg-dev     1.17.25
ii  libc6        2.19-18
ii  perl         5.20.2-3+deb8u1
ii  python3      3.4.2-2
pn  python3:any  <none>

Versions of packages devscripts recommends:
ii  at                          3.1.16-1
ii  curl                        7.38.0-4+deb8u2
ii  dctrl-tools                 2.23
ii  debian-keyring              2015.04.10
ii  dput                        0.9.6.4
ii  equivs                      2.0.9
ii  fakeroot                    1.20.2-1
ii  file                        1:5.22+15-2
ii  gnupg                       1.4.18-7
ii  libdistro-info-perl         0.14
ii  libencode-locale-perl       1.03-1
ii  libjson-perl                2.61-1
ii  liblwp-protocol-https-perl  6.06-2
ii  libparse-debcontrol-perl    2.005-4
ii  libsoap-lite-perl           1.11-1
ii  liburi-perl                 1.64-1
ii  libwww-perl                 6.08-1
ii  lintian                     2.5.35~bpo8+1
ii  man-db                      2.7.0.2-5
ii  patch                       2.7.5-1
ii  patchutils                  0.3.3-1
ii  python3-debian              0.1.27
ii  python3-magic               1:5.22+15-2
ii  sensible-utils              0.0.9
ii  strace                      4.9-2
ii  unzip                       6.0-16
ii  wdiff                       1.2.2-1
ii  wget                        1.16-1
ii  xz-utils                    5.1.1alpha+20120614-2+b3

Versions of packages devscripts suggests:
ii  bsd-mailx [mailx]            8.1.2-0.20141216cvs-2
ii  build-essential              11.7
pn  cvs-buildpackage             <none>
pn  debbindiff                   <none>
pn  devscripts-el                <none>
pn  gnuplot                      <none>
ii  gpgv                         1.4.18-7
ii  libauthen-sasl-perl          2.1600-1
ii  libfile-desktopentry-perl    0.07-1
ii  libnet-smtp-ssl-perl         1.01-3
pn  libterm-size-perl            <none>
ii  libtimedate-perl             2.3000-2
ii  libyaml-syck-perl            1.27-2+b2
ii  mutt                         1.5.23-3
ii  openssh-client [ssh-client]  1:6.7p1-5
pn  svn-buildpackage             <none>
ii  w3m                          0.5.3-19

-- no debconf information
-------------- next part --------------
#!/bin/bash
# vim:se tw=78 ai ts=2 sts=2 expandtab:

# Copyright 2015 Osamu Aoki <osamu at debian.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 <https://www.gnu.org/licenses/>.

ORIGINALPWD=`pwd`
PROGNAME=`basename $0`

usage () {
echo "NAME
  $PROGNAME - upgrade a source tree using new upstream tarball(s)

SYNOPSIS
~~~~~~~~
  $PROGNAME <version> [<comp1> <comp2> ...]
  $PROGNAME [--help|--version]

DESCRIPTION
~~~~~~~~~~~
$PROGNAME uses the existing Debianized source tree and the new upstream
tarball(s) to create the updated Debianized source tree.

The workflow can be summarized as:
 * Move to the root of the existing Debianized source tree where the debian/
   directory exists.
 * Download the upstream tarball(s) to the ../ directory.
 * Rename them as
   * main: <pkg>_<version>.orig.tar.{gz|bz2|lzma|xz}
   * comp1: <pkg>_<version>.orig-<comp1>.tar.{gz|bz2|lzma|xz} (optional)
   * comp2: <pkg>_<version>.orig-<comp2>.tar.{gz|bz2|lzma|xz} (optional)
   * ... 
 * Execute this command in the root of the existing Debianized source tree.

This command accesses following files in the existing source tree:
 * debian/changelog -- source package name and current package version
 * debian/source/format -- this is desirable to be 3.0 (quilt)

The <pkg> part of the filename need to be matched with the source package name
in the debian/changelog.

For the normal packaging of the single upstream tarball, <version> is the only
argument which indicates the next upstream version.  The source package
version of the updated Debianized source tree is generated from this <version>
by adding epoch if it is previously used and initial Debian revision (-1 for
Debian, -0ubuntu1 for Ubuntu).

For the packaging of the multiple upstream tarballs, the secondary tarballs
need to be renamed to <pkg>_<version>.orig-<compX>.tar.gz etc. in advance .
These are unpacked by this command under the <compX>/ directory within the
source tree.  So these renamed filename may not be similar to the original
secondar upstream tarballs.

$PROGNAME [--help|--version] show this message or give version information.

ENVIRONMENT
~~~~~~~~~~~
Id environmet variable $DEBUG is set to a non-zero string, this commands print
out its internal states and do not remove temporary files.

AUTHOR
~~~~~~
  Copyright 2015, Osamu Aoki <osamu at debian.org>

This is a complete rewite of the uupdate command by 
 * 1996        Christoph Lameter
 * 1999 - 2003 Julian Gilbey <jdg at debian.org>


NOTE
~~~~
This command uses \"dpkg-source -x\" as its backend to do the real work while
coping with many details of the latest Debian source package formats with
accuracy and simplicity.  Features such as renaming and moving upstream
tarballs are skipped since these are mostle covered by other tools these days.
(uscan+mk-origtargz for updating the existing packages and debmake/dh_make the
for new packages.  For multiple upstream arballs, some manual operation is
required still.)

"
}

version () {
  echo "This is $PROGNAME, from the Debian devscripts package, version ###VERSION###

Copyright 2015, Osamu Aoki <osamu at debian.org>

This program comes with ABSOLUTELY NO WARRANTY.
You are free to redistribute this code under the terms of the
GNU General Public License, version 2 or later.
"
}

if which dpkg-vendor >/dev/null 2>&1; then
  VENDER="$(dpkg-vendor --query Vendor 2>/dev/null|tr 'A-Z' 'a-z')"
  case "$VENDER" in
  debian) REV="1" ;;
  *) REV="0${VENDER}1" ;;
  esac
else
  REV="1"
fi

# Process Parameters
case $1 in
--help) usage; exit 0 ;;
--version) version; exit 0 ;;
esac
case $# in
0) usage; exit 0 ;;
*) NEW_VERSION="$1" ;;
esac
shift
COMPONENTS="$@"

if [ -n "$DEBUG" ]; then
  echo "NEW_VERSION=$NEW_VERSION"
  INDEX=1
  for C in $COMPONENTS; do
    echo "COMPONENT$INDEX=$C"
    INDEX=$(($INDEX+1))
  done
fi

# Sanity checks

if [ ! -d debian ]; then
  echo "$PROGNAME: cannot find debian/ directory." >&2
  echo "Are you in the debianized source tree?" >&2
  echo "You may wish to run debmake or dh_make first." >&2
  exit 1
fi

if [ ! -x debian/rules ]; then
  echo "$PROGNAME: cannot find debian/rules." >&2
  echo "Are you in the top directory of the old source tree?" >&2
  exit 1
fi

if [ ! -f debian/changelog ]; then
  echo "$PROGNAME: cannot find debian/changelog." >&2
  echo "Are you in the top directory of the old source tree?" >&2
  exit 1
fi

# Get Parameters from the old source tree

if [ -e debian/source -a -e debian/source/format ]; then
  FORMAT=`cat debian/source/format`
else
  FORMAT='1.0'
fi

PACKAGE="`dpkg-parsechangelog -SSource`"
if [ -z "$PACKAGE" ]; then
  echo "$PROGNAME: cannot find the source package name in debian/changelog." >&2
  exit 1
fi
  
# Variable names follow the convention of old uupdate

VERSION="`dpkg-parsechangelog -SVersion`"
if [ -z "$VERSION" ]; then
  echo "$PROGNAME: cannot find the source version name in debian/changelog." >&2
  exit 1
fi

EPOCH="${VERSION%:*}"
if [ "$EPOCH" = "$VERSION" ]; then
  EPOCH=""
else
  EPOCH="$EPOCH:"
fi
SVERSION="${VERSION#*:}"
UVERSION="${SVERSION%-*}"
if [ "$UVERSION" = "$SVERSION" ]; then
  echo "$PROGNAME: a native Debian package cannot take upstream updates" >&2
  exit 1
fi

if [ -n "$DEBUG" ]; then
  echo "Old: <epoch:><version>-<revision> = $VERSION"
  echo "Old: <epoch:>                     = $EPOCH"
  echo "Old:         <version>-<revision> = $SVERSION"
  echo "Old:         <version>            = $UVERSION"
  echo "New:         <version>            = $NEW_VERSION"
fi

if [ "`readlink -f ../${PACKAGE}-$NEW_VERSION`" = "$ORIGINALPWD" ]; then
  echo "$PROGNAME: You can not execute this from ../${PACKAGE}-${NEW_VERSION}/." >&2
  exit 1
fi

if [ -e "../${PACKAGE}-$NEW_VERSION" ];then
  echo "$PROGNAME: ../${PACKAGE}-$NEW_VERSION directory exists." >&2
  echo "           remove ../${PACKAGE}-$NEW_VERSION directory." >&2
  rm -rf ../${PACKAGE}-$NEW_VERSION
fi

# Move to the archive directory
cd ..
if [ -e "${PACKAGE}_$EPOCH$NEW_VERSION.orig.tar.xz" ]; then
  ARCHIVE="${PACKAGE}_$EPOCH$NEW_VERSION.orig.tar.xz"
  SUFFIX="xz"
elif [ -e "${PACKAGE}_$EPOCH$NEW_VERSION.orig.tar.gz" ]; then
  ARCHIVE="${PACKAGE}_$EPOCH$NEW_VERSION.orig.tar.gz"
  SUFFIX="gz"
elif [ -e "${PACKAGE}_$EPOCH$NEW_VERSION.orig.tar.bz2" ]; then
  ARCHIVE="${PACKAGE}_$EPOCH$NEW_VERSION.orig.tar.bz2"
  SUFFIX="bz2"
elif [ -e "${PACKAGE}_$EPOCH$NEW_VERSION.orig.tar.lzma" ]; then
  ARCHIVE="${PACKAGE}_$EPOCH$NEW_VERSION.orig.tar.lzma"
  SUFFIX="lzma"
else
  echo "$PROGNAME: Missing archive at ../${PACKAGE}_$EPOCH$NEW_VERSION.orig.tar.*" >&2
  exit 1
fi
if [ "$FORMAT" = "1.0" ]; then
  LISTDEBIAN="${PACKAGE}_$VERSION.debian.diff.xz \
    ${PACKAGE}_$VERSION.debian.diff.gz \
    ${PACKAGE}_$VERSION.debian.diff.bz2 \
    ${PACKAGE}_$VERSION.debian.diff.lzma"
else
  LISTDEBIAN="${PACKAGE}_$VERSION.debian.tar.xz \
    ${PACKAGE}_$VERSION.debian.tar.gz \
    ${PACKAGE}_$VERSION.debian.tar.bz2 \
    ${PACKAGE}_$VERSION.debian.tar.lzma"
fi
DEBIANFILE=""
for f in $LISTDEBIAN ; do
  if [ -f $f ] && [ ! -f ${f%.*}.${SUFFIX} ]; then
    DEBIANFILE="$f"
    last
  fi
done

# Move to the original source directory
cd $ORIGINALPWD
if [ -z "$DEBIANFILE" ]; then
  DEBIANFILE="${PACKAGE}_${VERSION}.debian.tar.xz"
  mkdir -p debian/source
  if [ "$FORMAT" != '3.0 (quilt)' ]; then
    echo "$PROGNAME warning: debian/source/format is overwritten as 3.0 (quilt)." >&2
  fi
  FORMAT='3.0 (quilt)'
  echo $FORMAT >debian/source/format
  tar --xz -cf ../$DEBIANFILE debian
fi
FAKEDEBIAN="${PACKAGE}_${EPOCH}${NEW_VERSION}-$REV.debian.tar.xz"
cp --no-clobber ../$DEBIANFILE ../$FAKEDEBIAN

# Move to the archive directory
cd ..
# fake DSC
FAKEDSC="${PACKAGE}_${EPOCH}${NEW_VERSION}-$REV.dsc"
echo "Format: ${FORMAT}" > "$FAKEDSC"
echo "Source: ${PACKAGE}" >> "$FAKEDSC"
echo "Version: $EPOCH${NEW_VERSION}-$REV" >> "$FAKEDSC"
echo "Files:" >> "$FAKEDSC"
echo " 01234567890123456789012345678901 1 ${ARCHIVE}" >> "$FAKEDSC"
for f in ${PACKAGE}_$EPOCH$NEW_VERSION.orig-*.tar.*z* ; do
  if [ -e "$f" ]; then
    if [ "$f" = "${f%.*}.${SUFFIX}" ] || [ ! -e ${f%.*}.${SUFFIX} ]; then
      echo " 01234567890123456789012345678901 1 $f" >> "$FAKEDSC"
    fi
  fi
done
echo " 01234567890123456789012345678901 1 ${FAKEDEBIAN}" >> "$FAKEDSC"

# unpack source tree
if ! dpkg-source --no-copy --no-check -x "$FAKEDSC"; then
  echo "$PROGNAME: Error with \"dpkg-source --no-copy --no-check -x $FAKEDSC\"" >&2
  echo "Remember: Your current directory is changed back to the old source tree!"
  echo "Do a \"cd ..\" to see $FAKEDSC."
  exit 1
fi
# remove bogus DSC and debian.tar files (generate them with dpkg-source -b)
if [ -z "$DEBUG" ]; then
  rm -f $FAKEDSC $FAKEDEBIAN
fi

# Move to the new source directory
if [ ! -d ${PACKAGE}-${NEW_VERSION} ]; then
  echo "$PROGNAME warning: ${PACKAGE}-${NEW_VERSION} directory missing." >&2
  ls -l >&2
  exit 1
fi
cd ${PACKAGE}-${NEW_VERSION}

# Need to set permission for format=1.0
[ -e debian/rules ] && chmod a+x debian/rules
debchange -v "$EPOCH$NEW_VERSION-$REV" "New upstream release"
echo "Remember: Your current directory is changed back to the old source tree!"
echo "Do a \"cd ../$PACKAGE-$NEW_VERSION\" to see the new source tree and
edit it to be nice Debianized source."


More information about the devscripts-devel mailing list