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

Contents of /eclass/git-2.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Wed Apr 20 10:56:27 2011 UTC (3 years, 8 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 scarabeus 1.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