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