/[gentoo-x86]/eclass/git-2.eclass
Gentoo

Contents of /eclass/git-2.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations) (download)
Wed Apr 20 10:56:27 2011 UTC (2 years, 11 months ago) by scarabeus
Branch: MAIN
Introduce git-2 eclass
This is next-gen eclass for git using live ebuilds.
Complete usage is documented in eclassdoc.

Note that for migration some variables have different names so
the ebuilds should be doublechecked that nothing will break.
Also this eclass define just one phase src_unpack, so no git-2_src_prepare.

1 # Copyright 1999-2011 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Header: $
4
5 # @ECLASS: git-2.eclass
6 # @MAINTAINER:
7 # Tomas Chvatal <scarabeus@gentoo.org>
8 # @BLURB: Eclass for fetching and unpacking git repositories.
9 # @DESCRIPTION:
10 # Eclass for easing maitenance of live ebuilds using git as remote repository.
11 # Eclass support working with git submodules and branching.
12
13 # This eclass support all EAPIs
14 EXPORT_FUNCTIONS src_unpack
15
16 DEPEND="dev-vcs/git"
17
18 # @ECLASS-VARIABLE: EGIT_SOURCEDIR
19 # @DESCRIPTION:
20 # This variable specifies destination where the cloned
21 # data are copied to.
22 #
23 # EGIT_SOURCEDIR="${S}"
24
25 # @ECLASS-VARIABLE: EGIT_STORE_DIR
26 # @DESCRIPTION:
27 # Storage directory for git sources.
28 #
29 # EGIT_STORE_DIR="${DISTDIR}/egit-src"
30
31 # @ECLASS-VARIABLE: EGIT_HAS_SUBMODULES
32 # @DEFAULT_UNSET
33 # @DESCRIPTION:
34 # If non-empty this variable enables support for git submodules in our
35 # checkout. Also this makes the checkout to be non-bare for now.
36
37 # @ECLASS-VARIABLE: EGIT_OPTIONS
38 # @DEFAULT_UNSET
39 # @DESCRIPTION:
40 # Variable specifying additional options for fetch command.
41
42 # @ECLASS-VARIABLE: EGIT_MASTER
43 # @DESCRIPTION:
44 # Variable for specifying master branch.
45 # Usefull when upstream don't have master branch or name it differently.
46 #
47 # EGIT_MASTER="master"
48
49 # @ECLASS-VARIABLE: EGIT_DIR
50 # @DESCRIPTION:
51 # Directory where we want to store the git data.
52 # This should not be overriden unless really required.
53 #
54 # EGIT_DIR="${EGIT_STORE_DIR}/${EGIT_REPO_URI##*/}"
55
56 # @ECLASS-VARIABLE: EGIT_REPO_URI
57 # @REQUIRED
58 # @DEFAULT_UNSET
59 # @DESCRIPTION:
60 # URI for the repository
61 # e.g. http://foo, git://bar
62 #
63 # Support multiple values:
64 # EGIT_REPO_URI="git://a/b.git http://c/d.git"
65
66 # @ECLASS-VARIABLE: EVCS_OFFLINE
67 # @DEFAULT_UNSET
68 # @DESCRIPTION:
69 # If non-empty this variable prevents performance of any online
70 # operations.
71
72 # @ECLASS-VARIABLE: EGIT_BRANCH
73 # @DESCRIPTION:
74 # Variable containing branch name we want to check out.
75 # It can be overriden via env using packagename_LIVE_BRANCH
76 # variable.
77 #
78 # EGIT_BRANCH="${EGIT_MASTER}"
79
80 # @ECLASS-VARIABLE: EGIT_COMMIT
81 # @DESCRIPTION:
82 # Variable containing commit hash/tag we want to check out.
83 # It can be overriden via env using packagename_LIVE_COMMIT
84 # variable.
85 #
86 # EGIT_BRANCH="${EGIT_BRANCH}"
87
88 # @ECLASS-VARIABLE: EGIT_REPACK
89 # @DEFAULT_UNSET
90 # @DESCRIPTION:
91 # If non-empty this variable specifies that repository will be repacked to
92 # save space. However this can take a REALLY LONG time with VERY big
93 # repositories.
94
95 # @ECLASS-VARIABLE: EGIT_PRUNE
96 # @DEFAULT_UNSET
97 # @DESCRIPTION:
98 # If non-empty this variable enables pruning all loose objects on each fetch.
99 # This is useful if upstream rewinds and rebases branches often.
100
101 # @ECLASS-VARIABLE: EGIT_NONBARE
102 # @DEFAULT_UNSET
103 # @DESCRIPTION:
104 # If non-empty this variable specifies that all checkouts will be done using
105 # non bare repositories. This is useful if you can't operate with bare
106 # checkouts for some reason.
107
108 # @FUNCTION: git-2_init_variables
109 # @DESCRIPTION:
110 # Internal function initializing all git variables.
111 # We define it in function scope so user can define
112 # all the variables before and after inherit.
113 git-2_init_variables() {
114 debug-print-function ${FUNCNAME} "$@"
115
116 local x
117
118 : ${EGIT_SOURCEDIR="${S}"}
119
120 : ${EGIT_STORE_DIR:="${PORTAGE_ACTUAL_DISTDIR-${DISTDIR}}/egit-src"}
121
122 : ${EGIT_HAS_SUBMODULES:=}
123
124 : ${EGIT_OPTIONS:=}
125
126 : ${EGIT_MASTER:=master}
127
128 eval x="\$${PN//[-+]/_}_LIVE_REPO"
129 EGIT_REPO_URI=${x:-${EGIT_REPO_URI}}
130 [[ -z ${EGIT_REPO_URI} ]] && die "EGIT_REPO_URI must have some value"
131
132 : ${EVCS_OFFLINE:=}
133
134 eval x="\$${PN//[-+]/_}_LIVE_BRANCH"
135 [[ -n ${x} ]] && ewarn "QA: using \"${PN//[-+]/_}_LIVE_BRANCH\" variable, you won't get any support"
136 EGIT_BRANCH=${x:-${EGIT_BRANCH:-${EGIT_MASTER}}}
137
138 eval x="\$${PN//[-+]/_}_LIVE_COMMIT"
139 [[ -n ${x} ]] && ewarn "QA: using \"${PN//[-+]/_}_LIVE_COMMIT\" variable, you won't get any support"
140 EGIT_COMMIT=${x:-${EGIT_COMMIT:-${EGIT_BRANCH}}}
141
142 : ${EGIT_REPACK:=}
143
144 : ${EGIT_PRUNE:=}
145 }
146
147 # @FUNCTION: git-2_submodules
148 # @DESCRIPTION:
149 # Internal function wrapping the submodule initialisation and update.
150 git-2_submodules() {
151 debug-print-function ${FUNCNAME} "$@"
152 if [[ -n ${EGIT_HAS_SUBMODULES} ]]; then
153 if [[ -n ${EVCS_OFFLINE} ]]; then
154 # for submodules operations we need to be online
155 debug-print "${FUNCNAME}: not updating submodules in offline mode"
156 return 1
157 fi
158
159 debug-print "${FUNCNAME}: working in \"${1}\""
160 pushd "${EGIT_DIR}" > /dev/null
161
162 debug-print "${FUNCNAME}: git submodule init"
163 git submodule init || die
164 debug-print "${FUNCNAME}: git submodule sync"
165 git submodule sync || die
166 debug-print "${FUNCNAME}: git submodule update"
167 git submodule update || die
168
169 popd > /dev/null
170 fi
171 }
172
173 # @FUNCTION: git-2_branch
174 # @DESCRIPTION:
175 # Internal function that changes branch for the repo based on EGIT_COMMIT and
176 # EGIT_BRANCH variables.
177 git-2_branch() {
178 debug-print-function ${FUNCNAME} "$@"
179
180 debug-print "${FUNCNAME}: working in \"${EGIT_SOURCEDIR}\""
181 pushd "${EGIT_SOURCEDIR}" > /dev/null
182
183 local branchname=branch-${EGIT_BRANCH} src=origin/${EGIT_BRANCH}
184 if [[ ${EGIT_COMMIT} != ${EGIT_BRANCH} ]]; then
185 branchname=tree-${EGIT_COMMIT}
186 src=${EGIT_COMMIT}
187 fi
188 debug-print "${FUNCNAME}: git checkout -b ${branchname} ${src}"
189 git checkout -b ${branchname} ${src} \
190 || die "${FUNCNAME}: changing the branch failed"
191
192 popd > /dev/null
193
194 unset branchname src
195 }
196
197 # @FUNCTION: git-2_gc
198 # @DESCRIPTION:
199 # Internal function running garbage collector on checked out tree.
200 git-2_gc() {
201 debug-print-function ${FUNCNAME} "$@"
202
203 pushd "${EGIT_DIR}" > /dev/null
204 if [[ -n ${EGIT_REPACK} || -n ${EGIT_PRUNE} ]]; then
205 ebegin "Garbage collecting the repository"
206 local args
207 [[ -n ${EGIT_PRUNE} ]] && args='--prune'
208 debug-print "${FUNCNAME}: git gc ${args}"
209 git gc ${args}
210 eend $?
211 fi
212 popd > /dev/null
213 }
214
215 # @FUNCTION: git-2_prepare_storedir
216 # @DESCRIPTION:
217 # Internal function preparing directory where we are going to store SCM
218 # repository.
219 git-2_prepare_storedir() {
220 debug-print-function ${FUNCNAME} "$@"
221
222 local clone_dir
223
224 # initial clone, we have to create master git storage directory and play
225 # nicely with sandbox
226 if [[ ! -d ${EGIT_STORE_DIR} ]]; then
227 debug-print "${FUNCNAME}: Creating git main storage directory"
228 addwrite /
229 mkdir -p "${EGIT_STORE_DIR}" \
230 || die "${FUNCNAME}: can't mkdir \"${EGIT_STORE_DIR}\""
231 fi
232
233 cd -P "${EGIT_STORE_DIR}" \
234 || die "${FUNCNAME}: can't chdir to \"${EGIT_STORE_DIR}\""
235 # allow writing into EGIT_STORE_DIR
236 addwrite "${EGIT_STORE_DIR}"
237 # calculate the proper store dir for data
238 [[ -z ${EGIT_REPO_URI##*/} ]] && EGIT_REPO_URI="${EGIT_REPO_URI%/}"
239 if [[ -z ${EGIT_DIR} ]]; then
240 clone_dir=${EGIT_REPO_URI##*/}
241 EGIT_DIR=${EGIT_STORE_DIR}/${clone_dir}
242 fi
243 export EGIT_DIR=${EGIT_DIR}
244 debug-print "${FUNCNAME}: Storing the repo into \"${EGIT_DIR}\"."
245 }
246
247 # @FUNCTION: git-2_move_source
248 # @DESCRIPTION:
249 # Internal function moving sources from the EGIT_DIR to EGIT_SOURCEDIR dir.
250 git-2_move_source() {
251 debug-print-function ${FUNCNAME} "$@"
252
253 debug-print "${FUNCNAME}: ${MOVE_COMMAND} \"${EGIT_DIR}\" \"${EGIT_SOURCEDIR}\""
254 pushd "${EGIT_DIR}" > /dev/null
255 mkdir -p "${EGIT_SOURCEDIR}" \
256 || die "${FUNCNAME}: failed to create ${EGIT_SOURCEDIR}"
257 ${MOVE_COMMAND} "${EGIT_SOURCEDIR}" \
258 || die "${FUNCNAME}: sync to \"${EGIT_SOURCEDIR}\" failed"
259 popd > /dev/null
260 }
261
262 # @FUNCTION: git-2_initial_clone
263 # @DESCRIPTION:
264 # Internal function running initial clone on specified repo_uri.
265 git-2_initial_clone() {
266 debug-print-function ${FUNCNAME} "$@"
267
268 local repo_uri
269
270 EGIT_REPO_URI_SELECTED=""
271 for repo_uri in ${EGIT_REPO_URI}; do
272 debug-print "${FUNCNAME}: git clone ${EGIT_OPTIONS} \"${repo_uri}\" \"${EGIT_DIR}\""
273 git clone ${EGIT_OPTIONS} "${repo_uri}" "${EGIT_DIR}"
274 if [[ $? -eq 0 ]]; then
275 # global variable containing the repo_name we will be using
276 debug-print "${FUNCNAME}: EGIT_REPO_URI_SELECTED=\"${repo_uri}\""
277 EGIT_REPO_URI_SELECTED="${repo_uri}"
278 break
279 fi
280 done
281
282 if [[ -z ${EGIT_REPO_URI_SELECTED} ]]; then
283 die "${FUNCNAME}: can't fetch from ${EGIT_REPO_URI}"
284 fi
285 }
286
287 # @FUNCTION: git-2_update_repo
288 # @DESCRIPTION:
289 # Internal function running update command on specified repo_uri.
290 git-2_update_repo() {
291 debug-print-function ${FUNCNAME} "$@"
292
293 local repo_uri
294
295 if [[ -n ${EGIT_NONBARE} ]]; then
296 # checkout master branch and drop all other local branches
297 git checkout ${EGIT_MASTER} || die "${FUNCNAME}: can't checkout master branch ${EGIT_MASTER}"
298 for x in $(git branch | grep -v "* ${EGIT_MASTER}" | tr '\n' ' '); do
299 debug-print "${FUNCNAME}: git branch -D ${x}"
300 git branch -D ${x} > /dev/null
301 done
302 fi
303
304 EGIT_REPO_URI_SELECTED=""
305 for repo_uri in ${EGIT_REPO_URI}; do
306 # git urls might change, so reset it
307 git config remote.origin.url "${repo_uri}"
308
309 debug-print "${EGIT_UPDATE_CMD} ${EGIT_OPTIONS}"
310 ${EGIT_UPDATE_CMD} > /dev/null
311 if [[ $? -eq 0 ]]; then
312 # global variable containing the repo_name we will be using
313 debug-print "${FUNCNAME}: EGIT_REPO_URI_SELECTED=\"${repo_uri}\""
314 EGIT_REPO_URI_SELECTED="${repo_uri}"
315 break
316 fi
317 done
318
319 if [[ -z ${EGIT_REPO_URI_SELECTED} ]]; then
320 die "${FUNCNAME}: can't update from ${EGIT_REPO_URI}"
321 fi
322 }
323
324 # @FUNCTION: git-2_fetch
325 # @DESCRIPTION:
326 # Internal function fetching repository from EGIT_REPO_URI and storing it in
327 # specified EGIT_STORE_DIR.
328 git-2_fetch() {
329 debug-print-function ${FUNCNAME} "$@"
330
331 local oldsha cursha repo_type
332
333 [[ -n ${EGIT_NONBARE} ]] && repo_type="non-bare repository" || repo_type="bare repository"
334
335 if [[ ! -d ${EGIT_DIR} ]]; then
336 git-2_initial_clone
337 pushd "${EGIT_DIR}" > /dev/null
338 cursha=$(git rev-parse ${UPSTREAM_BRANCH})
339 echo "GIT NEW clone -->"
340 echo " repository: ${EGIT_REPO_URI_SELECTED}"
341 echo " at the commit: ${cursha}"
342
343 popd > /dev/null
344 elif [[ -n ${EVCS_OFFLINE} ]]; then
345 pushd "${EGIT_DIR}" > /dev/null
346 cursha=$(git rev-parse ${UPSTREAM_BRANCH})
347 echo "GIT offline update -->"
348 echo " repository: $(git config remote.origin.url)"
349 echo " at the commit: ${cursha}"
350 popd > /dev/null
351 else
352 pushd "${EGIT_DIR}" > /dev/null
353 oldsha=$(git rev-parse ${UPSTREAM_BRANCH})
354 git-2_update_repo
355 cursha=$(git rev-parse ${UPSTREAM_BRANCH})
356
357 # fetch updates
358 echo "GIT update -->"
359 echo " repository: ${EGIT_REPO_URI_SELECTED}"
360 # write out message based on the revisions
361 if [[ "${oldsha1}" != "${cursha1}" ]]; then
362 echo " updating from commit: ${oldsha}"
363 echo " to commit: ${cursha}"
364 else
365 echo " at the commit: ${cursha}"
366 fi
367
368 # print nice statistic of what was changed
369 git --no-pager diff --stat ${oldsha}..${UPSTREAM_BRANCH}
370 popd > /dev/null
371 fi
372 # export the version the repository is at
373 export EGIT_VERSION="${cursha1}"
374 # log the repo state
375 [[ ${EGIT_COMMIT} != ${EGIT_BRANCH} ]] \
376 && echo " commit: ${EGIT_COMMIT}"
377 echo " branch: ${EGIT_BRANCH}"
378 echo " storage directory: \"${EGIT_DIR}\""
379 echo " checkout type: ${repo_type}"
380 }
381
382 # @FUNCTION: git_bootstrap
383 # @DESCRIPTION:
384 # Internal function that runs bootstrap command on unpacked source.
385 git-2_bootstrap() {
386 debug-print-function ${FUNCNAME} "$@"
387
388 # @ECLASS_VARIABLE: EGIT_BOOTSTRAP
389 # @DESCRIPTION:
390 # Command to be executed after checkout and clone of the specified
391 # repository.
392 # enviroment the package will fail if there is no update, thus in
393 # combination with --keep-going it would lead in not-updating
394 # pakcages that are up-to-date.
395 if [[ -n ${EGIT_BOOTSTRAP} ]]; then
396 pushd "${EGIT_SOURCEDIR}" > /dev/null
397 einfo "Starting bootstrap"
398
399 if [[ -f ${EGIT_BOOTSTRAP} ]]; then
400 # we have file in the repo which we should execute
401 debug-print "${FUNCNAME}: bootstraping with file \"${EGIT_BOOTSTRAP}\""
402
403 if [[ -x ${EGIT_BOOTSTRAP} ]]; then
404 eval "./${EGIT_BOOTSTRAP}" \
405 || die "${FUNCNAME}: bootstrap script failed"
406 else
407 eerror "\"${EGIT_BOOTSTRAP}\" is not executable."
408 eerror "Report upstream, or bug ebuild maintainer to remove bootstrap command."
409 die "\"${EGIT_BOOTSTRAP}\" is not executable"
410 fi
411 else
412 # we execute some system command
413 debug-print "${FUNCNAME}: bootstraping with commands \"${EGIT_BOOTSTRAP}\""
414
415 eval "${EGIT_BOOTSTRAP}" \
416 || die "${FUNCNAME}: bootstrap commands failed"
417 fi
418
419 einfo "Bootstrap finished"
420 popd > /dev/null
421 fi
422 }
423
424 # @FUNCTION: git-2_migrate_repository
425 # @DESCRIPTION:
426 # Internal function migrating between bare and normal checkout repository.
427 # This is based on usage of EGIT_SUBMODULES, at least until they
428 # start to work with bare checkouts sanely.
429 git-2_migrate_repository() {
430 debug-print-function ${FUNCNAME} "$@"
431
432 local target returnstate
433
434 # first find out if we have submodules
435 if [[ -z ${EGIT_HAS_SUBMODULES} ]]; then
436 target="bare"
437 else
438 target="full"
439 fi
440 [[ -n ${EGIT_NONBARE} ]] && target="full"
441
442 # test if we already have some repo and if so find out if we have
443 # to migrate the data
444 if [[ -d ${EGIT_DIR} ]]; then
445 if [[ ${target} == bare && -d ${EGIT_DIR}/.git ]]; then
446 debug-print "${FUNCNAME}: converting \"${EGIT_DIR}\" to bare copy"
447
448 ebegin "Converting \"${EGIT_DIR}\" from non-bare to bare copy"
449 mv "${EGIT_DIR}/.git" "${EGIT_DIR}.bare"
450 export GIT_DIR="${EGIT_DIR}.bare"
451 git config core.bare true > /dev/null
452 returnstate=$?
453 unset GIT_DIR
454 rm -rf "${EGIT_DIR}"
455 mv "${EGIT_DIR}.bare" "${EGIT_DIR}"
456 eend ${returnstate}
457 fi
458 if [[ ${target} == full && ! -d ${EGIT_DIR}/.git ]]; then
459 debug-print "${FUNCNAME}: converting \"${EGIT_DIR}\" to non-bare copy"
460
461 ebegin "Converting \"${EGIT_DIR}\" from bare to non-bare copy"
462 git clone -l "${EGIT_DIR}" "${EGIT_DIR}.nonbare" > /dev/null
463 returnstate=$?
464 rm -rf "${EGIT_DIR}"
465 mv "${EGIT_DIR}.nonbare" "${EGIT_DIR}"
466 eend ${returnstate}
467 fi
468 fi
469 if [[ ${returnstate} -ne 0 ]]; then
470 debug-print "${FUNCNAME}: converting \"${EGIT_DIR}\" failed, removing to start from scratch"
471
472 # migration failed, remove the EGIT_DIR to play it safe
473 einfo "Migration failed, removing \"${EGIT_DIR}\" to start from scratch."
474 rm -rf "${EGIT_DIR}"
475 fi
476
477 # set various options to work with both targets
478 if [[ ${target} == bare ]]; then
479 debug-print "${FUNCNAME}: working in bare repository for \"${EGIT_DIR}\""
480 EGIT_OPTIONS+=" --bare"
481 MOVE_COMMAND="git clone -l -s -n ${EGIT_DIR// /\\ }"
482 EGIT_UPDATE_CMD="git fetch -f -u origin ${EGIT_BRANCH}:${EGIT_BRANCH}"
483 UPSTREAM_BRANCH="${EGIT_BRANCH}"
484 else
485 debug-print "${FUNCNAME}: working in bare repository for non-bare \"${EGIT_DIR}\""
486 MOVE_COMMAND="cp -pPR ."
487 EGIT_UPDATE_CMD="git pull -f -u ${EGIT_OPTIONS}"
488 UPSTREAM_BRANCH="origin/${EGIT_BRANCH}"
489 EGIT_NONBARE="true"
490 fi
491 }
492
493 # @FUNCTION: git-2_src_unpack
494 # @DESCRIPTION:
495 # Default git src_upack function.
496 git-2_src_unpack() {
497 debug-print-function ${FUNCNAME} "$@"
498
499 git-2_init_variables
500 git-2_prepare_storedir
501 git-2_migrate_repository
502 git-2_fetch "$@"
503 git-2_gc
504 git-2_submodules
505 git-2_move_source
506 git-2_branch
507 git-2_bootstrap
508 echo ">>> Unpacked to ${EGIT_SOURCEDIR}"
509 }

  ViewVC Help
Powered by ViewVC 1.1.20