-
Notifications
You must be signed in to change notification settings - Fork 3
/
gp_release
executable file
·346 lines (295 loc) · 11.4 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
345
346
#!/bin/bash
# gp_release
# This is part of the Mer git-packaging suite
. ${GP_LIB:=/usr/share/gitpkg}/gp_common
git_tag_exists() { git show-ref --tags --quiet --verify -- "refs/tags/$1"; }
update_changes(){ # release oldpatchtag patchtag
release=$1
tag1=$2
tag2=$3
changes=${name}.changes
newchanges=$(mktemp changes_XXXXX)
date +"* %a %b %d %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
#### Begin gitlog summary. This line and lines up to the next changelog entry will be removed.
# The following lines contain a [summary] entry.
EOF
git log $tag1..$tag2 -- | egrep "^[[:space:]]*\[.*\]" | sed 's/\s*\(.*\)/- \1/' >> $newchanges
echo >> $newchanges
echo "#### Begin gitlog raw. This line and lines up to the next changelog entry will be removed.." >> $newchanges
echo >> $newchanges
git log $tag1..$tag2 -- >> $newchanges
echo "#### this line will be removed" >> $newchanges
cat $changes 2>/dev/null >> $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
rm -f $newchanges.pre-edit $newchanges~ $newchanges
fatal "No changes entered, aborting"
fi
sed -i '/^#### Begin gitlog/,/^#### this line will/d' $newchanges
mv $newchanges $changes || fatal "Can't update changes file"
# Tidy up emacs backup and old files
rm -f $newchanges.pre-edit $newchanges~
}
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 modifies 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 (ie 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. If the provided value does not exist the tag
is made at HEAD.
--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 :)
src 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.
If $PKG_DIR is set it is used instead of rpm/
If $PKG_FILE is set it is used instead of the first matching yaml/spec file
EOF
}
do_release() {
verrel_regex="^[^-]+-[^-]+$"
# or "^[a-zA-Z0-9.~_]+-[a-zA-Z0-9.~_]+$" ?
while [[ $1 ]]; do
case $1 in
--ver=*)
newver=${1#*=}
# 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 ;;
-V)
_V=1
_MKPKG_OPTS="-V"
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."
# 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
# Make a tag if none exists
if [[ $newver ]] && ! git_tag_exists $newver; then
git_tag_cleanly $newver
fi
get_pkgfile
name=$(get_field_from_packaging Name)
# Get ver-rel and increment it if we need to
case $get_verrel in
packaging )
ver=$(get_field_from_packaging Version)
rel=$(get_field_from_packaging Release)
oldrel=$rel
rel=$(perl -e"\$r='$rel';print ++\$r;")
log "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 speciyf 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 < $pkg_dir/_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
# Find the yaml or spec (or abort)
get_pkgfile
if [[ ! $pkgfile ]]; then
fatal "No spec or yaml files found"
fi
# if basetag and patchtag have the same sha1 then there are no
# patches to package.
if [[ $type == git ]]; then
tarball=$name-$ver.tar.gz
fi
if [[ $(git rev-parse $basetag 2>/dev/null) == $(git rev-parse $patchtag 2>/dev/null) ]]; then
srcfile="${type}:${tarball}:${basetag}"
else
srcfile="${type}:${tarball}:${basetag}:${patchtag}"
if ! git_branch_exists $DISTRO-master; then
# There are patches so we make mer-master branch and point
# it here
log "Reset $DISTRO-master branch to start at $patchtag"
git branch -f $DISTRO-master $patchtag
fi
fi
# Update the version/release, the .changes and the list of patches
# in the packaging
if [[ $verrel ]]; then
cd $pkg_dir
# 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
# Now update spec/yaml and _src
echo $srcfile > _src
sed -i -e"s/Version:.*/Version: $ver/" $pkgfile
sed -i -e"s/Release:.*/Release: $rel/" $pkgfile
# All done, use gp_mkpkg to update patch lists in yaml/spec etc
gp_mkpkg --no-tarball --no-checkout $_MKPKG_OPTS
# and commit
if [[ $manual_edit ]]; then
git add -u .
cat <<EOF
GUIDE: The packaging has been prepared. You may now manually edit the packaging.
When you are done, commit and tag the changes:
cd $pkg_dir
git commit -am"Release $patchtag"
git tag pkg-$patchtag
EOF
else
git commit -am"Release $patchtag"
git_tag_cleanly pkg-$patchtag
fi
else
echo $srcfile > $pkg_dir/_src
sha1=$(git rev-parse --short $patchtag_sha1)
gitcount=$(count_commits ${basetag} ${patchtag})
cd $pkg_dir
sed -i -re"s/Release:\s*(\S*)/Release: \1.$gitcount.$sha1/" $pkgfile
# Get version from packaging and then build dummy release with it.
get_info_from_packaging
release="$ver-1.$gitcount.$sha1"
# Now add a dummy changelog entry
changes=${name}.changes
newchanges=$(mktemp changes_XXXXX)
date +"* %a %b %d %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 $_MKPKG_OPTS
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