summaryrefslogtreecommitdiff
path: root/pbs-convert-absgit
diff options
context:
space:
mode:
Diffstat (limited to 'pbs-convert-absgit')
-rwxr-xr-xpbs-convert-absgit237
1 files changed, 237 insertions, 0 deletions
diff --git a/pbs-convert-absgit b/pbs-convert-absgit
new file mode 100755
index 0000000..30070c3
--- /dev/null
+++ b/pbs-convert-absgit
@@ -0,0 +1,237 @@
+#!/bin/bash -euE
+
+cmd="${0##*/}"
+export TMPDIR="`mktemp -d --tmpdir ${cmd}.XXXXXXXXXX`"
+cleanup() {
+ msg "$(gettext "Removing temporary files...")"
+ echo rm -rf "$TMPDIR"
+}
+trap cleanup EXIT
+
+. /usr/bin/libremessages
+
+abort() {
+ echo # force a fresh line
+ error "$(gettext "Aborting...")"
+ cleanup
+}
+
+##
+# Usage: trailing-newline FILE
+#
+# Adds a trailing newline to ${FILE} if there isn't one.
+#
+# Useful because different versions of git are inconsistent about
+# when there is one on output.
+###
+trailing-newline() {
+ local file=$1
+ if [[ "`sed -n '$p' "$file"|wc -l`" = 0 ]]; then
+ echo >> "$file"
+ fi
+}
+
+##
+# Usage: collect-data
+#
+# Assumptions:
+# - currently in the working repo
+# Effected by:
+# - file ../missing-packages
+# Effects:
+# - creates file "../find"
+# - creates file "../packages"
+# - creates file "../architectures"
+# Side effects:
+# - creates file "${TMPDIR}/commits"
+##
+collect-data() {
+ local mode=fast # 'correct' or 'fast
+ # 'fast' may omit some packages that have been deleted.
+
+ msg "$(gettext "Collecting package data...")"
+
+ case "$mode" in
+ correct) git log --pretty=format:'%H' master > "${TMPDIR}/commits";;
+ fast) git log -n1 --pretty=format:'%H' master > "${TMPDIR}/commits";;
+ *) usage; return 1;;
+ esac
+ trailing-newline "${TMPDIR}/commits"
+
+ # actual data collection ###############################################
+ local count="$(wc -l < "${TMPDIR}/commits")"
+ cat -n "${TMPDIR}/commits" | while read n commit; do
+ printf "\\r$(gettext "Scanning commit %s (%d/%d)")" "$commit" "$n" "$count" >> /dev/tty
+ git ls-tree -rd --name-only "$commit"
+ done | fgrep /repos/ | sort -u > ../find
+ echo # newline
+
+ # extract some things ##################################################
+ # packages
+ {
+ if [[ $mode = fast ]]; then
+ cat ../{packages,missing-packages} 2>/dev/null || true
+ fi
+ < ../find sed -e 's|^\.||' -e 's|/.*||'
+ } | sort -u > ../packages.tmp
+ mv ../packages{.tmp,}
+ # architectures
+ {
+ echo master
+ < ../find sed -e 's/.*-//' -e '/^any$/d'
+ } | sort -u > ../architectures
+}
+
+##
+# Usage: convert-package PACKAGE
+#
+# Assumptions:
+# - currently in the working repo
+# Effects:
+# - creates git branch "pkgs/${PACKAGE}"
+# - creates file "../pkg-${PACKAGE}.commits"
+# Side effects:
+# - changes git working tree
+# - prints output of git commands
+##
+convert-package() {
+ local package=$1
+
+ local obranch="pkgs/${package}"
+ local ibranch
+ local dir
+ if git checkout "packages/${package}" &>/dev/null; then
+ # special case (common; optimization)
+ ibranch="packages/${package}"
+ dir=trunk
+ else
+ # general case (uncommon)
+ ibranch=master
+ dir="${package}/trunk"
+ fi
+
+ git rewrite-branch --svn "$ibranch" "$obranch" \
+ --prune-empty --subdirectory-filter "$dir"
+
+ if [[ $ibranch != master ]]; then
+ git branch -D "$ibranch"
+ fi
+
+ git log "$obranch" --pretty=format:'%T %H' \
+ > "../pkg-${package}.commits"
+}
+
+##
+# Usage: convert-packages
+# Assumptions:
+# - currently in the working repo
+# - file "../packages" contains a newline-separated list of packages
+# Effects:
+# - runs `convert-package` for every package listed in "../packages"
+# - prints status updates about what it is doing
+##
+convert-packages() {
+ msg "$(gettext "Converting packages...")"
+ local count="$(wc -l < ../packages)"
+ cat -n ../packages | while read n package; do
+ msg2 "$(gettext "(%d/%d) %s")" "$n" "$count" "$package"
+ convert-package "$package"
+ done
+}
+
+##
+# Usage: convert-arch ARCH
+# Assumptions:
+# - currently in the working repo
+# - file "../packages-${PACKAGE}.commits" exists for every package
+# Effects:
+# - creates git branch "${ARCH}"
+# - creates file "${TMPDIR}/missing-packages/${ARCH}"
+# Side effects:
+# - changes git working tree
+# - prints output of git commands
+##
+convert-arch() {
+ local arch=$1
+
+ mkdir -p "${TMPDIR}/missing-packages"
+ touch "${TMPDIR}/missing-packages/${arch}.tmp"
+
+ git rewrite-branch master "$arch" \
+ --tree-filter "${cmd}--filterarch $arch"
+
+ sort -u \
+ < "${TMPDIR}/missing-packages/${arch}.tmp" \
+ > "${TMPDIR}/missing-packages/${arch}"
+ rm -f "${TMPDIR}/missing-packages/${arch}.tmp"
+}
+
+##
+# Usage: convert-arches
+# Assumptions:
+# - currently in the working repo
+# - file "../architectures" contains a newline-separated list of arches
+# Effects:
+# - runs `convert-arch` for every arch listed in "${TMPDIR}/architectures"
+# - prints status updates about what it is doing
+##
+convert-arches() {
+ msg "$(gettext "Converting architectures...")"
+ local count="$(wc -l < "../architectures")"
+ cat -n "../architectures" | while read n arch; do
+ msg2 "$(gettext "(%d/%d) %s")" "$n" "$count" "$arch"
+ convert-arch "$arch"
+ done
+}
+
+usage() {
+ echo "Usage: ${0##*/} SOURCE"
+ echo "Convert the absgit format SOURCE to pbs format"
+ echo
+ echo "SOURCE must be configured in /etc/libretools.d/pbs-convert.conf"
+}
+
+main() {
+ trap abort EXIT
+ [[ $# = 1 ]] || { usage; return 1; }
+ local source=$1
+
+ local cache="$(pbs-plumb-config get core.cachedir)/${source}.git"
+ local workdir="$(pbs-plumb-config get core.rewritedir)/${source}"
+ local sourcedir="$(pbs-plumb-config get core.sourcedir)"
+
+ # init ###################################d##############################
+ if [[ ! -d "${workdir}" ]]; then
+ msg "$(gettext "Creating working copy...")"
+ git clone "$cache" "${workdir}/repo"
+ fi
+ cd "${workdir}/repo"
+
+ # main #################################################################
+
+ collect-data fast
+ convert-packages
+ convert-arches
+
+ # save results #########################################################
+ msg "$(gettext "Copying into source directory...")"
+ [[ -d "$sourcedir" ]] || mkdir -p "$sourcedir"
+
+ # copy git repo
+ git clone --mirror "${TMPDIR}/repo" "${sourcedir}/${source}.new.git"
+ if [[ -d "${sourcedir}/${source}.git" ]]; then
+ mv "${sourcedir}/${source}"{,.old}.git
+ fi
+ mv "${sourcedir}/${source}"{.new,}.git
+ if [[ ! -d "${sourcedir}/${source}.old.git" ]]; then
+ rm -rf "${sourcedir}/${source}".old.git
+ fi
+
+ # copy other data
+ cp -f "../packages" "${sourceir}/${source}.packages"
+ cat "${TMPDIR}"/missing-packages/* > "${sourceir}/${source}.missing-packages"
+
+ trap cleanup EXIT
+}
+
+main "$@"