forked from lbt/git-pkg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gp_release
344 lines (291 loc) · 11.2 KB
/
gp_release
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
#!/bin/bash
# gp_release
# This is part of the Mer git-packaging suite
. ${GP_LIB:=/usr/share/gitpkg}/gp_common
assert_not_on_pkg_branch() {
if [[ $initial_branch == "pkg-$DISTRO" ]]; then
fatal <<EOF
$ME must not be run from the pkg-$DISTRO branch. Maybe
git checkout -f master
EOF
fi
}
git_tag_exists() { git show-ref --tags --quiet --verify -- "refs/tags/$1"; }
git_branch_exists() { git show-ref --quiet --verify -- "refs/heads/$1"; }
switch_to_pkg(){
git checkout -f pkg-$DISTRO || { fatal "Can't checkout pkg-$DISTRO, aborting"; }
}
cleanup(){
# switch back to initial branch
echo "Attempting to switch back to $initial_branch in git"
git checkout $initial_branch
}
update_changes(){ # release oldpatchtag patchtag
release=$1
tag1=$2
tag2=$3
changes=$(find . -maxdepth 1 -name '*changes' -print -quit)
newchanges=$(mktemp changes_XXXXX)
date +"* %a %b %Y ${GIT_AUTHOR_NAME:-Your Name (Set \$GIT_AUTHOR_NAME)} <${GIT_AUTHOR_EMAIL:-Your Email Set \$GIT_AUTHOR_EMAIL}> - $release" > $newchanges
cat <<EOF >> $newchanges
- Please enter a changelog message
#### Relevant gitlog. This line and lines up to the next changelog entry will be removed.
EOF
git log $tag1..$tag2 >> $newchanges
echo "#### this line will be removed" >> $newchanges
cat *.changes >> $newchanges
cp $newchanges $newchanges.pre-edit
${EDITOR:-vi} $newchanges || fatal "EDITOR not set and vi not available"
if diff --report-identical-files $newchanges $newchanges.pre-edit > /dev/null; then
fatal "No changes entered, aborting"
fi
sed -i '/^#### Relevant gitlog/,/^#### this line will/d' $newchanges
mv $newchanges $changes || fatal "Can't update changes file"
}
usage() {
cat <<EOF
$ME [--rel[=<version-release>]] [--ver=<tag>] [--edit] [--git-dir=<path>]
Used to create a new release or prepare for an intermediate
build. It is used to update the packaging by modifying the
_src, .changes, .yaml and .spec files.
Version: and Release: values and patch lines will be updated in
the yaml/spec. A changelog entry is prompted for (using git log
as a base) and the git repo will be tagged.
Normal usage is to update git; possibly to a new upstream or
local release point, apply or rebase any patches and run as
$ME --ver/--rel
An alternative use is to *not* specify --ver or --rel but to
use --git-dir; this will create a ready-to-build set of
patches/tarballs (FIXME: it has the unwanted side-effect of
changing the checkout state of <path>)
--rel is used to create a new incremental release of a package
when all that is changed is a patch to upstream code or
packaging. It does not change the 'version' of a package or the
main tag the package is built from.
--ver is used to create a new version of a package. Usually
this means that the <release> value is '1'. Usually this means
there is a new upstream code/tag. If the upstream tag is not a
simple version (eg it has text or underscores: 'vX_Y_Z') then
the extended form of the --rel arg can be used to override the
<version> and <release> values.
--rel[=<version-release>]
If --rel is used then a new package release will be created.
If <version-release> is not specified then it is guessed from
the packaging and uses perls string increment on
<release>. This often works :)
HEAD when the command is run will be tagged as
$DISTRO-<version-release> and packaging as
pkg-$DISTRO-<version-release>. (Usually git checkout -f
master would be run before running $ME --rel)
--ver=<basetag>
If --ver is provided then it identifies the new base tag from
which patches are based and from where the tarball is
built. If --rel=<version>-<release> is not given then
<version> is assumed to be <basetag> and <release> is assumed to
be "1". A $DISTRO-master branch will be made if not present.
This is used for a new upstream release.
--edit
If --edit is provided then the final commit/tag step on the
packaging branch is not made so that the spec/yaml can be
edited manually. The commit/tag commands are printed for
reference.
If --rel is not given then the packaging branch pkg-$DISTRO is
checked out, the spec/yaml is updated by appending
.gitcount.sha1 to the Release: value (this tries to ensure rpm
release values increment in a manner that allow rpm upgrades to
work).
ADDITIONALLY: a normal gp_mkpkg is used to prepare the tarball
and patches when --rel is not given.
--git-dir=<dir>
The --git-dir option is ideal for working with a local OBS
checkout and doing local OBS builds. It makes most sense when
--rel is not specified
Internally it sets GIT_DIR to <dir> and GIT_WORK_TREE to cwd
$DISTRO is set either in ~/.gitpkg, the GITPKG_DISTRO
environment variable or using --distro=<DISTRO>. If not
specified 'mer' is used.
EOF
}
do_release() {
verrel_regex="^[^-]+-[^-]+$"
# or "^[a-zA-Z0-9.~_]+-[a-zA-Z0-9.~_]+$" ?
while [[ $1 ]]; do
case $1 in
--ver=*)
newver=${1#*=}
if ! git_tag_exists $newver; then
fatal "--ver must provide a valid tag. '$newver' is not a valid tag."
fi
# if a plain --rel is given aswell (ie without
# =ver-rel) that's ambiguous since --ver implies a
# new version
# so override to 'basetag' and we'll set ver=$newver and rel=1
get_verrel=newver
shift;;
--rel )
# Now if --ver was given, don't override from packaging
get_verrel=${get_verrel:-packaging}
shift;;
--rel=* )
verrel=${1#*=}
if [[ $verrel =~ $verrel_regex ]]; then
ver=${verrel%-*}
rel=${verrel##*-}
else
fatal "The --rel= option must provide <ver>-<rel>"
fi
# if $verrel is "" then we guess it later when the packaging is present
shift ;;
--edit )
manual_edit=true
shift ;;
--git-dir=*)
gitdir=${1#*=}
if ! git --git-dir $gitdir rev-parse --git-dir > /dev/null 2>&1; then
# not a git dir - try appending .git
if git --git-dir $gitdir/.git rev-parse --git-dir > /dev/null 2>&1; then
gitdir=$gitdir/.git
else
fatal "The --git-dir option must point to a git repo. \n" \
"$gitdir nor $gitdir/.git are a git directory"
fi
fi
export GIT_WORK_TREE=$(pwd)
export GIT_DIR=$gitdir
export GIT_INDEX_FILE=$(mktemp /tmp/gp.index_XXXXX)
git read-tree --empty
shift ;;
*-h*) usage;
exit 0;;
* )
echo "Error $1 not recognised"
usage
exit 1;;
esac
done
git rev-parse --git-dir > /dev/null 2>&1 ||
fatal "This is not a git repository; use $ME in a gitpkg git repo or use --git-dir."
# We need a clean tree unless we're in another directory using --git-dir
if ! [[ $GIT_INDEX_FILE ]]; then require_clean_work_tree "run $ME"; fi
save_initial_branch
assert_not_on_pkg_branch
# store current git postion as we'll make patches to here from the
# basetag. If they turn out to be the same ... no patches
patchtag_sha1=$(git rev-parse HEAD)
trap cleanup EXIT
switch_to_pkg
# Get ver-rel and increment it if we need to
case $get_verrel in
packaging )
get_info_from_packaging .
oldrel=$rel
rel=$(perl -e"\$r='$rel';print ++\$r;")
echo "Automagically guessed $ver-$oldrel -> $ver-$rel"
verrel=$ver-$rel
if ! [[ $rel ]] || [[ $rel == "1" ]]; then
fatal "The value guessed for Release: is '$rel' and this is probably wrong.\n" \
"Please specify an exact value for --rel=\n" \
"Currently Version: $ver and Release: $oldrel"
fi
;;
newver )
# if we have a newver and no ver/rel then set them:
if ! [[ $verrel ]]; then
ver=$newver
rel=1
verrel=$ver-$rel
fi
;;
esac
# Update from _src
IFS=: read type tarball basetag oldpatchtag rest < _src
# TODO: verify tarball basetag oldpatchtag are sane
# basetag should be ${DISTRO}-$ver
# patchtag should be ${DISTRO}-$ver-$rel
# If we're not given a --ver or a --rel then this is a trial
# build and we just use a sha1. Otherwise make a tag
if [[ $verrel ]]; then
patchtag=${DISTRO}-$verrel
if ! git_tag_exists $patchtag; then
git_tag_cleanly $patchtag $patchtag_sha1
fi
else
patchtag=$patchtag_sha1
fi
# If --ver was used to set a new <basetag> then do so
if [[ $newver ]]; then
oldbase=$basetag
basetag=$newver
fi
# if basetag and patchtag have the same sha1 then there are no
# patches to package.
if [[ $(git rev-parse $basetag 2>/dev/null) == $(git rev-parse $patchtag 2>/dev/null) ]]; then
echo ${type}:${tarball}:${basetag} > _src
else
echo ${type}:${tarball}:${basetag}:${patchtag} > _src
# There are patches so we make mer-master branch and point it
# here
echo "Reset $DISTRO-master branch to start at $patchtag"
git branch -f $DISTRO-master $patchtag
fi
# Find the yaml or spec (or abort)
pkgfile=$(find . -maxdepth 1 -name '*yaml' -print -quit)
if [[ ! $pkgfile ]]; then
pkgfile=$(find . -maxdepth 1 -name '*spec' -print -quit)
fi
if [[ ! $pkgfile ]]; then
fatal "No spec or yaml files found"
fi
# Update the version/release, the .changes and the list of patches
# in the packaging
if [[ $verrel ]]; then
sed -i -e"s/Version:.*/Version: $ver/" $pkgfile
sed -i -e"s/Release:.*/Release: $rel/" $pkgfile
# If this is a newver then it's a new upstream release: give a
# set of changes from one ver to the next
if [[ $newver ]]; then
update_changes $verrel $oldbase $newver
else
update_changes $verrel $oldpatchtag $patchtag_sha1
fi
# All done, use gp_mkpkg to update patch lists in yaml/spec etc
gp_mkpkg --no-tarball --no-checkout
# and commit
if [[ $manual_edit ]]; then
git add -u .
cat <<EOF
The packaging has been prepared. You may now manally edit the
packaging.
When you are done, commit and tag the changes:
git commit -am"Release $patchtag"
git tag pkg-$patchtag
git checkout $initial_branch
EOF
else
git commit -am"Release $patchtag"
git_tag_cleanly pkg-$patchtag
git checkout $initial_branch
fi
else
sha1=$(git rev-parse --short $patchtag_sha1)
gitcount=$(count_commits ${basetag} ${patchtag})
sed -i -re"s/Release:\s*(\S*)/Release: \1.$gitcount.$sha1/" $pkgfile
# Now add a dummy changelog entry
changes=$(find . -maxdepth 1 -name '*changes' -print -quit)
newchanges=$(mktemp changes_XXXXX)
date +"* %a %b %Y ${GIT_AUTHOR_NAME:-Your Name (Set \$GIT_AUTHOR_NAME)} <${GIT_AUTHOR_EMAIL:-Your Email Set \$GIT_AUTHOR_EMAIL}> - $release" > $newchanges
echo -e "- git commits from $oldpatchtag to $sha1" >> $newchanges
git log ${oldpatchtag}..$patchtag_sha1 --oneline | sed -e 's/^/ /' >> $newchanges
echo >> $newchanges
cat *.changes >> $newchanges
mv $newchanges $changes || fatal "Can't update changes file"
# All done, use gp_mkpkg to update patch lists in yaml/spec etc
gp_mkpkg --no-checkout
cat <<EOF
The tarball and patches have been prepared for building.
EOF
fi
}
do_release $*
# Don't try to undo all tags/changes
trap - EXIT