summaryrefslogtreecommitdiff
path: root/pbs-absrepo-convert
blob: 16349ad705eaa2a63abb5fcea10da8efc297dcb5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/bin/bash -e

export TMPDIR="`mktemp -d --tmpdir pbs-absrepo-convert.XXXXXXXXXX`"
cleanup() {
	msg "$(gettext "Removing temporary files...")"
	echo rm -rf "$TMPDIR"
}
trap cleanup EXIT

. /usr/bin/libremessages

abort() {
	echo
	error "$(gettext "Aborting...")"
	cleanup
}

_collect-data-gc() {
	local base=$1
	local files=`echo $base.new*`
	cat -- $files 2>>/dev/null | sort -u > $base.tmp
	rm -f -- $files
	mv $base.tmp $base.new
}

collect-data-gc() {(
	cd "$TMPDIR"
	while [[ ! -f collect-data-filter-branch.done ]]; do
		_collect-data-gc packages
		_collect-data-gc repo-arch
		sleep 10
	done
	mv packages.new packages
	mv repo-arch.new repo-arch
)}

##
# Usage: collect-data
# Assumptions:
#   1. Currently in a working copy of the repo
#   2. git branch "master" exists and is untouched
#   3. TMPDIR is set and exists
##
collect-data() {
	msg "$(gettext "Collecting package data...")"
	collect-data-gc &
	git filter-branch --tree-filter pbs-absrepo-convert--list master
	# notify collect-data-gc that filter-branch is done
	touch "${TMPDIR}/collect-data-filter-branch.done"
	# wait for collect-data-gc to finish
	while [[ ! -f "${TMPDIR}/packages" ]]; do
		sleep 10;
	done
	# extract some data from those files
	< "${TMPDIR}/repo-arch" sed -e 's/.*/-/' -e '/^any$/d' | sort -u > "${TMPDIR}/arches"
	{ echo master; cat "${TMPDIR}/arches"; } > "${TMPDIR}/arches.all"
}

##
# Usage: convert-packages SOURCE
# Assumptions:
#   1. Currently in a working copy of the repo
#   2. TMPDIR is set, and collect-data has been run on it
##
convert-packages() {
	msg "$(gettext "Converting packages...")"
	[[ $# != 1 ]] && { usage; return 1; }
	local source=$1

	local ibranch
	local obranch
	local dir

	local count="$(wc -l < "${TMPDIR}/packages")"
	cat -n "${TMPDIR}/packages" | while read n package; do
		msg2 "$(gettext "(%d/%d) %s")" "$n" "$count" "$package"
		if git checkout "packages/${package}" &>/dev/null; then
			# common case (optimization)
			ibranch=orig
			obranch="packages/${package}"
			dir=trunk
		else
			# general (uncommon) case
			ibranch="packages/${package}"
			obranch="packages/${source}/${package}"
			dir="${package}/trunk"
		fi
		git checkout -b "$obranch" "$ibranch"
		if [[ $ibranch != orig ]]; then
			git branch -D "$ibranch"
		fi
		git filter-branch -f --prune-empty --subdirectory-filter "$dir" "$obranch"

		git log --pretty=format:'%T %H' > "${TMPDIR}/packages-${package}.commits"
	done
}

##
# Usage: convert-arches
# Assumptions:
#   1. Currently in a working copy of the repo
#   2. TMPDIR is set, and collect-data has been run on it
#   3. ${TMPDIR}/packages-PACKAGE.commits exists for every package
##
convert-arches() {
	msg "$(gettext "Converting architectures...")"

	local count="$(wc -l < "${TMPDIR}/arches.all")"
	cat -n "${TMPDIR}/arches.all" | while read n arch; do
		msg2 "$(gettext "(%d/%d) %s")" "$n" "$count" "$arch"
		git checkout orig
		git checkout -b "$arch"
		git filter-branch -f --tree-filter \
			"pbs-absrepo-convert--treefilter $arch" "$arch"
	done
}

main() {
	trap abort EXIT
	[[ $# != 1 ]] && { usage; return 1; }
	local source=$1

	local cachedir="$(pbs-plumb-config get core.cachedir)"
	local sourcedir="$(pbs-plumb-config get core.sourcedir)"

	# init #################################################################
	msg "$(gettext "Creating working copy...")"
	git clone "${cachedir}/${source}.git" "${TMPDIR}/repo"
	cd "${TMPDIR}/repo"
	git checkout -b orig
	git checkout master
	collect-data
	git branch -D master

	# main #################################################################

	convert-packages "$source"
	convert-arches "$source"

	# save results #########################################################
	msg "$(gettext "Copying into source directory...")"
	[[ -d "$sourcedir" ]] || mkdir -p "$sourcedir"
	git clone --mirror "${TMPDIR}/repo" "${sourcedir}/${source}.new.git"
	[[ -d "${sourcedir}/${source}.git" ]] && mv "${sourcedir}/${source}"{,.old}.git
	mv "${sourcedir}/${source}"{.new,}.git
	[[ -d "${sourcedir}/${source}.old.git" ]] && rm -rf "${sourcedir}/${source}".old.git
	trap cleanup EXIT
}

main "$@"