Fixed bug parsing -N.
[dcp.git] / dcp-init
1 #!/bin/bash
2
3 set -e
4
5 usage() {
6     echo "usage: dcp-init [-sh] [-C key=val] [-d REPODIR] PACKAGE [(PATCH|-m)...]"
7     echo "       PATCH ::= [-p LEVEL] [-bB BRANCH] FILE"
8     echo "       -b creates a new branch at the current patch"
9     echo "       -B creates a new branch at the upstream sources"
10     echo "       -m merges the current branch into the master branch"
11 }
12
13 rungit() {
14     (
15         cd "$td"
16         git "$@"
17     ) || false
18 }
19
20 getaptsrc() {
21     mkdir "$td/apt-tmp"
22     (cd "$td/apt-tmp"; apt-get source "$1") || false
23     
24     sdir=
25     for f in "$td/apt-tmp"/*; do
26         if [ -d "$f" ]; then
27             if [ -z "$sdir" ]; then
28                 sdir="$f"
29             else
30                 echo "dcp-init: got more than one directory from apt-get; cannot continue" >&2
31                 exit 1
32             fi
33         fi
34     done
35     if [ -z "$sdir" ]; then
36         echo "dcp-init: could not find any source directory" >&2
37         exit 1
38     fi
39     mv "$sdir" "$td/src"
40     rm -rf "$td/apt-tmp"
41
42     rungit add src
43 }
44
45 initrepo() {
46     rungit init
47     mkdir "$td/control"
48     touch "$td/control/conf"
49     rungit add control
50     rungit commit -q -m "Initial repo"
51     rungit tag empty
52 }
53
54 initbase() {
55     mkdir "$td/control/build.d"
56     mkdir "$td/control/update.d"
57     cat >"$td/control/functions" <<EOF
58 readconf() {
59     if [ -r "\$HOME/.dcp-build-conf" ]; then
60         while read key val; do
61             export "CONF_\$key"="\$val"
62         done <"\$HOME/.dcp-build-conf"
63     fi
64     while read key val; do
65         export "CONF_\$key"="\$val"
66     done <control/conf
67 }
68
69 rungit() {
70     (cd repo; git "\$@") || false
71 }
72 EOF
73     cat >"$td/control/build" <<EOF
74 #!/bin/sh
75
76 set -e
77
78 . control/functions
79 readconf
80
81 for file in control/build.d/*; do
82     if [ -x "\$file" ]; then "\$file"; fi
83 done
84 EOF
85     chmod 755 "$td/control/build"
86     cat >"$td/control/update" <<EOF
87 #!/bin/sh
88
89 set -e
90
91 . control/functions
92 readconf
93
94 for branch in repo/.git/refs/heads/*; do
95     branch="\${branch##*/}"
96     if [ -x "control/update.d/\$branch" ]; then
97         rungit checkout "\$branch"
98         lastrev="\$(rungit rev-parse HEAD)"
99         "control/update.d/\$branch"
100         newrev="\$(rungit rev-parse HEAD)"
101         rungit checkout master
102         if [ "\$newrev" != "\$lastrev" ]; then
103             rungit merge -n "\$branch"
104         fi
105     fi
106 done
107 EOF
108     chmod 755 "$td/control/update"
109     rungit add control
110 }
111
112 initapt() {
113     cat >"$td/control/build.d/99dpkg" <<EOF
114 #!/bin/bash
115
116 set -e
117
118 cmd=(dpkg-buildpackage -b -rfakeroot)
119 if [ -n "\$CONF_MAINTAINER" ]; then
120     cmd=("\${cmd[@]}" "-m\$CONF_MAINTAINER")
121 fi
122 if [ -n "\$CONF_GPGKEY" ]; then
123     cmd=("\${cmd[@]}" "-k\$CONF_GPGKEY")
124 fi
125 (cd repo/src; "\${cmd[@]}") || false
126 mv repo/*.deb output/
127 EOF
128     chmod 755 "$td/control/build.d/99dpkg"
129     rungit add control/build.d/99dpkg
130     cat >"$td/control/update.d/upstream" <<EOF
131 #!/bin/sh
132
133 set -e
134
135 cd repo
136 dcp-update-apt "\$CONF_APTPKG"
137
138 EOF
139     chmod 755 "$td/control/update.d/upstream"
140     rungit add control/update.d/upstream
141     echo "APTPKG $pkg" >>"$td/control/conf"
142     rungit add control/conf
143 }
144
145 defdir=/srv/dcp
146 repodir=
147 confopts=()
148 shared=n
149
150 while [ "${1:0:1}" = - ]; do
151     opt="${1:1}"
152     shift
153     if [ "$opt" = d ]; then
154         repodir="$1"
155         shift
156     elif [ "$opt" = h ]; then
157         usage
158         exit 0
159     elif [ "$opt" = s ]; then
160         shared=y
161     elif [ "$opt" = C ]; then
162         confopts=("${confopts[@]}" "$1")
163         shift
164     else
165         echo "dcp-init: unknown option '$opt'" >&2
166         exit 1
167     fi
168 done
169
170 if [ $# -lt 1 ]; then
171     usage >&2
172     exit 1
173 fi
174 pkg="$1"
175 shift
176 if [ -z "$repodir" ]; then repodir="$pkg"; fi
177 if [[ "$repodir" != */* ]]; then
178     repodir="$defdir/${repodir}.git"
179 fi
180
181 td="$(mktemp -d "/tmp/dcp-XXXXXX")"
182 initrepo
183
184 initbase
185 rungit commit -q -m "Base control files"
186
187 if [ "${#confopts[@]}" -gt 0 ]; then
188     for opt in "${confopts[@]}"; do
189         key="${opt%%=*}"
190         val="${opt#*=}"
191         echo "$key $val" >>"$td/control/conf"
192     done
193     rungit add control/conf
194     rungit commit -q -m "Custom configuration file"
195 fi
196
197 rungit checkout -q -b upstream empty
198 getaptsrc "$pkg"
199 rungit commit -q -m "Initial upstream import"
200 rungit checkout master
201 rungit merge -n upstream
202
203 initapt
204 rungit commit -q -m "APT control files"
205
206 initvals() {
207     level=0
208 }
209 initvals
210 curbranch=master
211 while [ $# -gt 0 ]; do
212     arg="$1"
213     shift
214     if [ "${arg:0:1}" = - ]; then
215         if [ "$arg" = -p ]; then
216             level="$1"
217             shift
218         elif [ "$arg" = -b ]; then
219             curbranch="$1"
220             shift
221             rungit checkout -q -b "$curbranch"
222         elif [ "$arg" = -B ]; then
223             curbranch="$1"
224             shift
225             rungit checkout -q -b "$curbranch" upstream
226         elif [ "$arg" = -m ]; then
227             rungit checkout -q master
228             rungit merge -n "$curbranch"
229         else
230             echo "dcp-init: unknown patch option '$arg'" >&2
231             exit 1
232         fi
233     else
234         (
235             if [[ "$arg" == *.gz ]]; then
236                 zcat "$arg"
237             else
238                 cat "$arg"
239             fi
240         ) | patch -d "$td/src" -p"$level"
241         rungit add src
242         rungit commit -q -m "Applied $(basename "$arg")"
243         initvals
244     fi
245 done
246
247 git clone -q --bare "$td" "$repodir"
248 if [ "$shared" = y ]; then
249     chmod -R g+w "$repodir"
250     td="$repodir" rungit config core.sharedrepository 1
251 fi
252
253 rm -rf "$td"