summaryrefslogtreecommitdiffstats
path: root/src/deb.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/deb.sh')
-rwxr-xr-xsrc/deb.sh333
1 files changed, 333 insertions, 0 deletions
diff --git a/src/deb.sh b/src/deb.sh
new file mode 100755
index 0000000..1535bf2
--- /dev/null
+++ b/src/deb.sh
@@ -0,0 +1,333 @@
+#!@@SHELL@@
+#
+# DEB - Download, Edit, Build!
+# src/deb.sh
+# Main program script.
+#
+# Copyright (C) 2012 Patrick "P. J." McDermott
+#
+# 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 3 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/>.
+
+COMMANDS='init config update download edit builddsc'
+CONFIG_NAMES='mirror distribution component remote buildcmd'
+
+main()
+{
+ SCRIPT_NAME="${0}"
+
+ if [ ${#} -lt 1 ]; then
+ print_usage >&2
+ exit 1
+ fi
+
+ COMMAND_NAME="${1}"
+ shift
+
+ if ! echo " ${COMMANDS} " | grep " ${COMMAND_NAME} " > /dev/null 2>&1; then
+ print_usage >&2
+ exit 1
+ fi
+
+ CWD="${PWD}"
+
+ cmd_run ${@}
+}
+
+print_usage()
+{
+ cat <<EOF
+Usage: ${SCRIPT_NAME} <command> <arguments>
+
+Where <command> is one of:
+ init Initialize a DEB work area
+ config Get or set a configuration value
+ update Update the list of source packages
+ download Download a source package
+ edit Unpack a source package for editing
+ builddsc Build an edited source package and debdiff
+ build Build binary packages
+ push Synchronize changes with a remote tree
+EOF
+}
+
+error()
+{
+ msg="${1}"
+ shift
+ printf "Error: ${msg}\n" ${@}
+ exit 2
+}
+
+find_deb_dir()
+{
+ until [ "${PWD}" = '/' ]; do
+ if [ -d '.deb' ]; then
+ DEB_DIR="${PWD}/.deb"
+ DEB_TREE="${PWD}"
+ return 0
+ fi
+ cd ..
+ done
+ [ ${#} -ge 1 ] && "${1}" && error 'No DEB work area found'
+ return 1
+}
+
+config_load()
+{
+ . "${DEB_DIR}/config"
+}
+
+config_save()
+{
+ for name in ${CONFIG_NAMES}; do
+ printf "CONFIG_%s='%s'\n" "${name}" "$(eval echo \$\{CONFIG_${name}\})"
+ done > "${DEB_DIR}/config"
+}
+
+cmd_run()
+{
+ "cmd_${COMMAND_NAME}" ${@}
+}
+
+cmd_init()
+{
+ find_deb_dir false || {
+ DEB_DIR="${CWD}/.deb"
+ DEB_TREE="${CWD}"
+ }
+
+ CONFIG_mirror='http://ftp.debian.org/debian'
+ CONFIG_distribution='sid'
+ CONFIG_component='main'
+ CONFIG_buildcmd='sbuild --build=%mirror% -d %distribution% %opts% %dsc%'
+
+ cd "${DEB_TREE}"
+ if [ -d .deb ]; then
+ rm -Rf .deb dsc build pkgs work
+ mkdir .deb dsc build pkgs work
+ config_save
+ printf 'Reinitialized DEB work area in %s.\n' "${DEB_TREE}"
+ else
+ mkdir .deb dsc build pkgs work
+ config_save
+ printf 'Initialized DEB work area in %s.\n' "${DEB_TREE}"
+ fi
+}
+
+cmd_config()
+{
+ find_deb_dir
+ config_load
+
+ if [ ${#} -ne 1 -a ${#} -ne 2 ]; then
+ cat >&2 <<EOF
+Usage: ${SCRIPT_NAME} ${COMMAND_NAME} <name> [<value>]
+EOF
+ exit 1
+ fi
+
+ echo " ${CONFIG_NAMES} " | grep " ${1} " > /dev/null 2>&1 || \
+ error 'Invalid configuration name "%s"' "${1}"
+
+ config_name="CONFIG_${1}"
+ if [ ${#} -eq 1 ]; then
+ printf '%s\n' "$(eval echo \$\{${config_name}\})"
+ else
+ eval "${config_name}=${2}"
+ config_save
+ fi
+}
+
+cmd_update()
+{
+ find_deb_dir
+ config_load
+
+ if [ ${#} -ne 0 ]; then
+ cat >&2 <<EOF
+Usage: ${SCRIPT_NAME} ${COMMAND_NAME}
+EOF
+ exit 1
+ fi
+
+ printf 'Downloading Sources file...\n'
+ rm -f "${DEB_DIR}/.Sources.bz2"
+ sources="${CONFIG_mirror}/dists/${CONFIG_distribution}/${CONFIG_component}/source"
+ sources="${sources}/Sources.bz2"
+ curl -o "${DEB_DIR}/.Sources.bz2" "${sources}" || error 'Cannot download Sources file'
+
+ printf '\nDecompressing Sources file...\n'
+ rm -f "${DEB_DIR}/.Sources"
+ bunzip2 "${DEB_DIR}/.Sources.bz2" || error 'Cannot decompress Sources file'
+
+ total=$(grep ^Package: "${DEB_DIR}/.Sources" | wc -l)
+ count=0
+
+ printf '\nReading Sources file...\n'
+ > "${DEB_DIR}/dsc.list~"
+ while read line; do
+ if [ -z "${line}" ]; then
+ printf '%s %s\n' "${pkg}" "${dir}/${dsc}" >> "${DEB_DIR}/.dsc.list~"
+ count=$(($count + 1))
+ printf "\rFound %${#total}d/%d source packages.%s" \
+ "${count}" "${total}" \
+ "$([ ${count} -eq ${total} ] && printf ' ' || printf '..')"
+ continue
+ fi
+ if [ "${line#Package: }" != "${line}" ]; then
+ pkg="${line#Package: }"
+ continue
+ fi
+ if [ "${line#Directory: }" != "${line}" ]; then
+ dir="${line#Directory: }"
+ continue
+ fi
+ if [ "${line#Files:}" != "${line}" ]; then
+ while read sum size file; do
+ if [ "${file%.dsc}" != "${file}" ]; then
+ dsc="${file}"
+ break
+ fi
+ done
+ continue
+ fi
+ done < "${DEB_DIR}/.Sources"
+ printf '\n'
+
+ rm "${DEB_DIR}/.Sources"
+ mv "${DEB_DIR}/.dsc.list~" "${DEB_DIR}/dsc.list"
+
+ printf '\nDone.\n'
+}
+
+cmd_download()
+{
+ find_deb_dir
+ config_load
+
+ if [ ${#} -ne 1 ]; then
+ cat >&2 <<EOF
+Usage: ${SCRIPT_NAME} ${COMMAND_NAME} <pkg>
+EOF
+ exit 1
+ fi
+
+ [ ! -f "${DEB_DIR}/dsc.list" ] && error 'No source package list found'
+
+ pkg="${1}"
+
+ line="$(grep "^${pkg} " "${DEB_DIR}/dsc.list")" || \
+ error 'Package "%s" not found' "${pkg}"
+ dsc="${line#${pkg} }"
+
+ mkdir -p "${DEB_TREE}/dsc/${pkg}"
+ cd "${DEB_TREE}/dsc/${pkg}"
+
+ printf 'Downloading source package "%s"...\n' "${pkg}"
+ dget -d "${CONFIG_mirror}/${dsc}" || error 'Cannot download source package'
+
+ printf '\nDone.\n'
+}
+
+cmd_edit()
+{
+ find_deb_dir
+ config_load
+
+ if [ ${#} -ne 1 ]; then
+ cat >&2 <<EOF
+Usage: ${SCRIPT_NAME} ${COMMAND_NAME} <pkg>
+EOF
+ exit 1
+ fi
+
+ [ ! -f "${DEB_DIR}/dsc.list" ] && error 'No source package list found'
+
+ pkg="${1}"
+
+ line="$(grep "^${pkg} " "${DEB_DIR}/dsc.list")" || \
+ error 'Package "%s" not found' "${pkg}"
+ dsc="${line#${pkg} }"
+ dsc="${dsc##*/}"
+
+ [ ! -f "${DEB_TREE}/dsc/${pkg}/${dsc}" ] && \
+ error 'Source package "%s" not downloaded' "${pkg}"
+
+ ver="${dsc%.dsc}"
+ ver="${ver#${pkg}_}"
+ ver="${ver%-*}"
+
+ mkdir -p "${DEB_TREE}/work/${pkg}"
+ dpkg-source -x "${DEB_TREE}/dsc/${pkg}/${dsc}" \
+ "${DEB_TREE}/work/${pkg}/${pkg}-${ver}"
+}
+
+cmd_builddsc()
+{
+ find_deb_dir
+ config_load
+
+ if [ ${#} -ne 1 ]; then
+ cat >&2 <<EOF
+Usage: ${SCRIPT_NAME} ${COMMAND_NAME} <pkg>
+EOF
+ exit 1
+ fi
+
+ [ ! -f "${DEB_DIR}/dsc.list" ] && error 'No source package list found'
+
+ pkg="${1}"
+
+ line="$(grep "^${pkg} " "${DEB_DIR}/dsc.list")" || \
+ error 'Package "%s" not found' "${pkg}"
+ dsc="${line#${pkg} }"
+ dsc="${dsc##*/}"
+
+ ver="${dsc%.dsc}"
+ ver="${ver#${pkg}_}"
+ ver="${ver%-*}"
+
+ ver="$(dpkg-parsechangelog \
+ -l"${DEB_TREE}/work/${pkg}/${pkg}-${ver}/debian/changelog" | \
+ sed -n 's/^Version: \(.*\)$/\1/p')"
+ base="${pkg}_${ver}"
+ ver="${ver%-*}"
+ rev="${ver#${ver}}"
+ rev="${rev#-}"
+
+ [ ! -d "${DEB_TREE}/work/${pkg}/${pkg}-${ver}" ] && \
+ error 'Source package "%s" not unpacked for editing' "${pkg}"
+
+ cd "${DEB_TREE}/work/${pkg}/${pkg}-${ver}"
+ dpkg-buildpackage -S -us -uc
+
+ cd ..
+ rm -Rf "${DEB_TREE}/pkgs/${pkg}"
+ mkdir -p "${DEB_TREE}/pkgs/${pkg}"
+
+ # XXX: This assumes source format 3.0.
+ mv "${base}.dsc" "${base}_source.changes" "${DEB_TREE}/pkgs/${pkg}"
+ if [ -n "${rev}" ]; then
+ cp -p "${pkg}_${ver}.orig.tar.gz" "${DEB_TREE}/pkgs/${pkg}"
+ mv "${base}.diff.gz" "${DEB_TREE}/pkgs/${pkg}"
+ else
+ mv "${base}.tar.gz" "${DEB_TREE}/pkgs/${pkg}"
+ fi
+
+ debdiff \
+ "${DEB_TREE}/dsc/${pkg}/${dsc}" "${DEB_TREE}/pkgs/${pkg}/${base}.dsc" \
+ > "${DEB_TREE}/pkgs/${pkg}/${pkg}.debdiff"
+}
+
+main ${@}