diff options
Diffstat (limited to 'pbs-convert-absgit')
-rwxr-xr-x | pbs-convert-absgit | 237 |
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 "$@" |