Skip to content

Commit 911b5b9

Browse files
committed
Initial introduction of a opam-release tool
This is a tool to generate a branch (and a pull-request manually) from the opam meta data local to the repository. Most of the arguments are inferred automatically if one: - has a unique file named <your-project>.opam - is using a github repository - has their github username configured in their global .gitconfig - has performed git remote update - the dev-repo is set in the opam file - opam is installed Arguments can be supplied to fix any of the default behavior (or their absence thereof). One can witness the inferred arguments by providing option `-s`
1 parent 6d0eada commit 911b5b9

File tree

1 file changed

+266
-0
lines changed

1 file changed

+266
-0
lines changed

opam-release.sh

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
if [ "$DEBUG" = 1 ]; then
5+
set -x
6+
fi
7+
8+
show_help(){
9+
cat <<EOF
10+
Usage : opam-release (arguments)* (opam-files)*
11+
--
12+
Optional arguments:
13+
opam-files: one or many opam files to push to opam-coq-archive
14+
*if no argument is provided, it lists *.opam files in the current directory
15+
-u GITHUBUSER / --user GITHUBUSER:
16+
where GITHUBUSER is your github username,
17+
you must have a fork of coq/opam-coq-archive under
18+
https://github.com/$GITHUBUSER/opam-coq-archive
19+
for this command to work,
20+
* if not provided, tries "git config --get github.user"
21+
-p PROJECT / --project PROJECT:
22+
where PROJECT is a name of the project,
23+
without space, it is used solely for generating
24+
the name of the branch and PR,
25+
* automatically infered from the name of the opam file
26+
if only one was given,
27+
-e DEPTH / --depth DEPTH:
28+
sets the depth of the local clone of opam-coq-archive to $DEPTH
29+
* defaults to full clone,
30+
you may want to fix the DEPTH to save bandwidth and time
31+
-V VERSION / --version VERSION:
32+
where VERSION is the opam version number of
33+
the package to create,
34+
* if no version is provided, tries to find the latest tag,
35+
you may want to perform a "git remote update" to fetch all tags first
36+
-U URL / --url URL:
37+
where URL is the url of the archive associated
38+
with the version to release.
39+
* tries to infer it from the "dev-repo" section if one opam file is provided
40+
-x PREFIX / --version-prefix PREFIX: the tag of a version is equal to $PREFIX$VERSION
41+
* default is ""
42+
** this options is used only if URL is not provided
43+
-d / --dev: pushes an update to extra-dev instead of releases
44+
-C / --no-check-upstream: tells opam lint not to check the sum online
45+
-h / -? / --help: print this usage
46+
-s / --show-defaults: prints the default inferred setting and exists
47+
-v / --verbose: show debug information
48+
-L / --no-lint: do not run opam lint
49+
(not recommended but useful if you do not have opam installed)
50+
-n / --do-nothing: do not push anything
51+
EOF
52+
}
53+
54+
die() {
55+
printf '%s\n' "$1" >&2
56+
exit 1
57+
}
58+
59+
GITHUBUSER=$(git config --get github.user)
60+
TAG=$(git describe --tags --abbrev=0)
61+
VERSION=$(echo $TAG | sed -e "s/[^0-9]*\(\([0-9]+|\.\)\)*/\1/")
62+
PROJECT=
63+
URL=
64+
LINT=1
65+
NOTHING=0
66+
DEPTH=
67+
HDEPTH=
68+
TARGET="released"
69+
OPAM=()
70+
CHECKUPSTREAM="--check-upstream"
71+
PREFIX=
72+
SHOWDEFAULTS=0
73+
74+
while :; do
75+
case $1 in
76+
-h|-\?|--help)
77+
show_help # Display a usage synopsis.
78+
exit 0
79+
;;
80+
-u|--user)
81+
if [ "$2" ]; then GITHUBUSER=$2; shift; shift
82+
else die 'ERROR: "--user" requires a non-empty argument, cf --help'
83+
fi
84+
;;
85+
-p|--project)
86+
if [ "$2" ]; then PROJECT=$2; shift; shift
87+
else die 'ERROR: "--name" requires a non-empty argument, cf --help'
88+
fi
89+
;;
90+
-V|--version)
91+
if [ "$2" ]; then VERSION=$2; shift; shift
92+
else die 'ERROR: "--name" requires a non-empty argument, cf --help'
93+
fi
94+
;;
95+
-U|--url)
96+
if [ "$2" ]; then URL=$2; shift; shift
97+
else die 'ERROR: "--name" requires a non-empty argument, cf --help'
98+
fi
99+
;;
100+
-e|--depth)
101+
if [ "$2" ]; then HDEPTH="$2"; DEPTH="--depth=$2"; shift; shift
102+
else die 'ERROR: "--name" requires a non-empty argument, cf --help'
103+
fi
104+
;;
105+
-x|--version-prefix)
106+
if [ "$2" ]; then PREFIX=$2; shift; shift
107+
else die 'ERROR: "--name" requires a non-empty argument, cf --help'
108+
fi
109+
;;
110+
-L|--no-lint)
111+
LINT=0; shift
112+
;;
113+
-d|--dev)
114+
TARGET="extra-dev"
115+
VERSION="dev"
116+
CHECKUPSTREAM=
117+
shift
118+
;;
119+
-C|--no-check-upstream)
120+
CHECKUPSTREAM=
121+
shift
122+
;;
123+
-v|--verbose)
124+
VERBOSE=1; shift
125+
;;
126+
-s|--show-defaults)
127+
SHOWDEFAULTS=1; shift
128+
;;
129+
-n|--do-nothing)
130+
NOTHING=1; shift
131+
;;
132+
*) # unknown option
133+
if ! [ "$*" ]; then
134+
break
135+
elif [ -f "$1" ]; then
136+
OPAM+=("$1")
137+
shift
138+
else die 'ERROR: positional arguments must be a file'
139+
fi
140+
;;
141+
esac
142+
done
143+
144+
if ! [ "$OPAM" ]; then
145+
OPAM=(); for opam in *.opam; do OPAM+=("$opam"); done
146+
fi
147+
148+
eval set -- "${OPAM[@]}"
149+
150+
if ! [ "GITHUBUSER" ]; then
151+
die 'ERROR: -u / --user argument is required, cf --help'
152+
fi
153+
154+
if ! [ "VERSION" ]; then
155+
die 'ERROR: -V / --version argument is required, cf --help'
156+
fi
157+
158+
159+
if [ "$PREFIX" ]; then
160+
TAG=$PREFIX$VERSION
161+
fi
162+
163+
case "${#OPAM[@]}" in
164+
0)
165+
die 'ERROR: no opam file provided or found cf --help'
166+
;;
167+
1)
168+
if ! [ "$PROJECT" ]; then
169+
PROJECT=$(basename "${OPAM[0]}" .opam)
170+
fi
171+
;;
172+
*)
173+
if ! [ "$PROJECT" ]; then
174+
die 'ERROR: -p / --project argument is required when more than one opam files are given, cf --help'
175+
fi
176+
;;
177+
esac
178+
179+
if ! [ "$URL" ]; then
180+
if [ "$TARGET" = "released" ]; then
181+
URL=$(opam show -f dev-repo --file "${OPAM[0]}" | sed -e "s/git+//" | sed -e "s+\.git+/archive/$TAG.tar.gz+")
182+
else
183+
URL="$(opam show -f dev-repo --file ${OPAM[0]})#master"
184+
fi
185+
fi
186+
187+
if [ "$VERBOSE" = 1 ] || [ "$SHOWDEFAULTS" = 1 ]; then
188+
echo "# this would call"
189+
echo "$0 \\"
190+
if [ "$VERBOSE" = 1 ]; then echo "-v \\"; fi
191+
echo "-u $GITHUBUSER \\"
192+
echo "-V $VERSION \\"
193+
echo "-p $PROJECT \\"
194+
echo "-U $URL \\"
195+
if [ "$LINT" = 0 ]; then echo "-L \\"; fi
196+
if [ "$NOTHING" = 1 ]; then echo "-n \\"; fi
197+
if [ "$HDEPTH" ]; then echo "-e $HDEPTH \\"; fi
198+
if [ "$TARGET" = "extra-dev" ]; then echo "--dev \\"; fi
199+
if ! [ "$CHECKUPSTREAM" ]; then echo "-C \\"; fi
200+
echo "${OPAM[@]}"
201+
fi
202+
203+
if [ "$SHOWDEFAULTS" = 1 ]; then
204+
exit
205+
fi
206+
207+
COA=$(mktemp -d) # stands for Coq Opam Archive
208+
git clone $DEPTH git@github.com:coq/opam-coq-archive $COA -o upstream
209+
git -C $COA remote add origin git@github.com:$GITHUBUSER/opam-coq-archive
210+
BRANCH=$PROJECT.$VERSION
211+
git -C $COA checkout -b $BRANCH
212+
PKGS=$COA/$TARGET/packages
213+
214+
ARCHIVE=$(mktemp)
215+
if [ "$TARGET" = "released" ]; then
216+
curl -L $URL -o $ARCHIVE
217+
SUM=$(sha256sum $ARCHIVE | cut -d " " -f 1)
218+
fi
219+
220+
if [ "$VERBOSE" = 1 ]; then
221+
echo "COA=$COA"
222+
echo "BRANCH=$BRANCH"
223+
echo "PKGS=$PKGS"
224+
echo "ARCHIVE=$ARCHIVE"
225+
echo "SUM=$SUM"
226+
fi
227+
228+
for opam in ${OPAM[@]}; do
229+
B=$(basename $opam .opam)
230+
P=$PKGS/$B/$B.$VERSION
231+
mkdir -p $P
232+
sed "/^version:.*/d" $opam > $P/opam
233+
sed -i -e '/^[ \t]*#/d' $P/opam
234+
echo "" >> $P/opam
235+
echo "url {" >> $P/opam
236+
echo " src: \"$URL\"" >> $P/opam
237+
if [ "$TARGET" = "released" ]; then
238+
echo " checksum: \"sha256=$SUM\"" >> $P/opam
239+
fi
240+
echo "}" >> $P/opam
241+
if [ "$LINT" = 1 ]; then
242+
opam lint $CHECKUPSTREAM $P/opam
243+
else
244+
echo "linting disabled (not recommended)"
245+
fi
246+
git -C $COA add $P/opam
247+
done
248+
249+
git -C $COA commit -m "Update $PROJECT $VERSION"
250+
if [ "$NOTHING" = 1 ]; then
251+
echo "**********************************************************************"
252+
echo "Dry run!"
253+
echo git -C $COA push origin -f $BRANCH
254+
echo "if you want to see the diff, run"
255+
echo git -C $COA diff HEAD~1
256+
echo "**********************************************************************"
257+
else
258+
git -C $COA push origin -f $BRANCH
259+
echo "**********************************************************************"
260+
echo "Create a pull request by visiting"
261+
echo "https://github.com/$GITHUBUSER/opam-coq-archive/pull/new/$BRANCH"
262+
echo "**** PLEASE CHECK CAREFULLY THE GENERATED CODE ***"
263+
echo "If you wish to delete the resulting branch, execute:"
264+
echo "git -C $COA push origin --delete $BRANCH"
265+
echo "**********************************************************************"
266+
fi

0 commit comments

Comments
 (0)