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

Diff of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.35 Revision 1.49
1# Copyright 1999-2014 Gentoo Foundation 1# Copyright 1999-2015 Gentoo Foundation
2# Distributed under the terms of the GNU General Public License v2 2# Distributed under the terms of the GNU General Public License v2
3# $Header: /var/cvsroot/gentoo-x86/eclass/git-r3.eclass,v 1.35 2014/03/02 11:49:05 mgorny Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/git-r3.eclass,v 1.49 2015/06/22 08:39:36 mrueg Exp $
4 4
5# @ECLASS: git-r3.eclass 5# @ECLASS: git-r3.eclass
6# @MAINTAINER: 6# @MAINTAINER:
7# Michał Górny <mgorny@gentoo.org> 7# Michał Górny <mgorny@gentoo.org>
8# @BLURB: Eclass for fetching and unpacking git repositories. 8# @BLURB: Eclass for fetching and unpacking git repositories.
9# @DESCRIPTION: 9# @DESCRIPTION:
10# Third generation eclass for easing maitenance of live ebuilds using 10# Third generation eclass for easing maintenance of live ebuilds using
11# git as remote repository. 11# git as remote repository.
12 12
13case "${EAPI:-0}" in 13case "${EAPI:-0}" in
14 0|1|2|3|4|5) 14 0|1|2|3|4|5)
15 ;; 15 ;;
35# @ECLASS-VARIABLE: EGIT_CLONE_TYPE 35# @ECLASS-VARIABLE: EGIT_CLONE_TYPE
36# @DESCRIPTION: 36# @DESCRIPTION:
37# Type of clone that should be used against the remote repository. 37# Type of clone that should be used against the remote repository.
38# This can be either of: 'mirror', 'single', 'shallow'. 38# This can be either of: 'mirror', 'single', 'shallow'.
39# 39#
40# This is intended to be set by user in make.conf. Ebuilds are supposed
41# to set EGIT_MIN_CLONE_TYPE if necessary instead.
42#
40# The 'mirror' type clones all remote branches and tags with complete 43# The 'mirror' type clones all remote branches and tags with complete
41# history and all notes. EGIT_COMMIT can specify any commit hash. 44# history and all notes. EGIT_COMMIT can specify any commit hash.
42# Upstream-removed branches and tags are purged from the local clone 45# Upstream-removed branches and tags are purged from the local clone
43# while fetching. This mode is suitable for cloning the local copy 46# while fetching. This mode is suitable for cloning the local copy
44# for development or hosting a local git mirror. However, clones 47# for development or hosting a local git mirror. However, clones
45# of repositories with large diverged branches may quickly grow large. 48# of repositories with large diverged branches may quickly grow large.
46# 49#
50# The 'single+tags' type clones the requested branch and all tags
51# in the repository. All notes are fetched as well. EGIT_COMMIT
52# can safely specify hashes throughout the current branch and all tags.
53# No purging of old references is done (if you often switch branches,
54# you may need to remove stale branches yourself). This mode is intended
55# mostly for use with broken git servers such as Google Code that fail
56# to fetch tags along with the branch in 'single' mode.
57#
47# The 'single' type clones only the requested branch or tag. Tags 58# The 'single' type clones only the requested branch or tag. Tags
48# referencing commits throughout the branch history are fetched as well, 59# referencing commits throughout the branch history are fetched as well,
49# and all notes. EGIT_COMMIT can safely specify only hashes 60# and all notes. EGIT_COMMIT can safely specify only hashes
50# in the current branch. No purging of old references is done (if you 61# in the current branch. No purging of old references is done (if you
51# often switch branches, you may need to remove stale branches 62# often switch branches, you may need to remove stale branches
63# 'Minimum' clone type supported by the ebuild. Takes same values 74# 'Minimum' clone type supported by the ebuild. Takes same values
64# as EGIT_CLONE_TYPE. When user sets a type that's 'lower' (that is, 75# as EGIT_CLONE_TYPE. When user sets a type that's 'lower' (that is,
65# later on the list) than EGIT_MIN_CLONE_TYPE, the eclass uses 76# later on the list) than EGIT_MIN_CLONE_TYPE, the eclass uses
66# EGIT_MIN_CLONE_TYPE instead. 77# EGIT_MIN_CLONE_TYPE instead.
67# 78#
79# This variable is intended to be used by ebuilds only. Users are
80# supposed to set EGIT_CLONE_TYPE instead.
81#
68# A common case is to use 'single' whenever the build system requires 82# A common case is to use 'single' whenever the build system requires
69# access to full branch history or the remote (Google Code) does not 83# access to full branch history, or 'single+tags' when Google Code
70# support shallow clones. Please use sparingly, and to fix fatal errors 84# or a similar remote is used that does not support shallow clones
85# and fetching tags along with commits. Please use sparingly, and to fix
71# rather than 'non-pretty versions'. 86# fatal errors rather than 'non-pretty versions'.
72: ${EGIT_MIN_CLONE_TYPE:=shallow} 87: ${EGIT_MIN_CLONE_TYPE:=shallow}
73 88
74# @ECLASS-VARIABLE: EGIT3_STORE_DIR 89# @ECLASS-VARIABLE: EGIT3_STORE_DIR
75# @DESCRIPTION: 90# @DESCRIPTION:
76# Storage directory for git sources. 91# Storage directory for git sources.
97# @ECLASS-VARIABLE: EGIT_REPO_URI 112# @ECLASS-VARIABLE: EGIT_REPO_URI
98# @REQUIRED 113# @REQUIRED
99# @DESCRIPTION: 114# @DESCRIPTION:
100# URIs to the repository, e.g. git://foo, https://foo. If multiple URIs 115# URIs to the repository, e.g. git://foo, https://foo. If multiple URIs
101# are provided, the eclass will consider them as fallback URIs to try 116# are provided, the eclass will consider them as fallback URIs to try
102# if the first URI does not work. 117# if the first URI does not work. For supported URI syntaxes, read up
118# the manpage for git-clone(1).
103# 119#
104# It can be overriden via env using ${PN}_LIVE_REPO variable. 120# It can be overriden via env using ${PN}_LIVE_REPO variable.
105# 121#
106# Can be a whitespace-separated list or an array. 122# Can be a whitespace-separated list or an array.
107# 123#
113# @ECLASS-VARIABLE: EVCS_OFFLINE 129# @ECLASS-VARIABLE: EVCS_OFFLINE
114# @DEFAULT_UNSET 130# @DEFAULT_UNSET
115# @DESCRIPTION: 131# @DESCRIPTION:
116# If non-empty, this variable prevents any online operations. 132# If non-empty, this variable prevents any online operations.
117 133
134# @ECLASS-VARIABLE: EVCS_UMASK
135# @DEFAULT_UNSET
136# @DESCRIPTION:
137# Set this variable to a custom umask. This is intended to be set by
138# users. By setting this to something like 002, it can make life easier
139# for people who do development as non-root (but are in the portage
140# group), and then switch over to building with FEATURES=userpriv.
141# Or vice-versa. Shouldn't be a security issue here as anyone who has
142# portage group write access already can screw the system over in more
143# creative ways.
144
118# @ECLASS-VARIABLE: EGIT_BRANCH 145# @ECLASS-VARIABLE: EGIT_BRANCH
119# @DEFAULT_UNSET 146# @DEFAULT_UNSET
120# @DESCRIPTION: 147# @DESCRIPTION:
121# The branch name to check out. If unset, the upstream default (HEAD) 148# The branch name to check out. If unset, the upstream default (HEAD)
122# will be used. 149# will be used.
146_git-r3_env_setup() { 173_git-r3_env_setup() {
147 debug-print-function ${FUNCNAME} "$@" 174 debug-print-function ${FUNCNAME} "$@"
148 175
149 # check the clone type 176 # check the clone type
150 case "${EGIT_CLONE_TYPE}" in 177 case "${EGIT_CLONE_TYPE}" in
151 mirror|single|shallow) 178 mirror|single+tags|single|shallow)
152 ;; 179 ;;
153 *) 180 *)
154 die "Invalid EGIT_CLONE_TYPE=${EGIT_CLONE_TYPE}" 181 die "Invalid EGIT_CLONE_TYPE=${EGIT_CLONE_TYPE}"
155 esac 182 esac
156 case "${EGIT_MIN_CLONE_TYPE}" in 183 case "${EGIT_MIN_CLONE_TYPE}" in
158 ;; 185 ;;
159 single) 186 single)
160 if [[ ${EGIT_CLONE_TYPE} == shallow ]]; then 187 if [[ ${EGIT_CLONE_TYPE} == shallow ]]; then
161 einfo "git-r3: ebuild needs to be cloned in 'single' mode, adjusting" 188 einfo "git-r3: ebuild needs to be cloned in 'single' mode, adjusting"
162 EGIT_CLONE_TYPE=single 189 EGIT_CLONE_TYPE=single
190 fi
191 ;;
192 single+tags)
193 if [[ ${EGIT_CLONE_TYPE} == shallow || ${EGIT_CLONE_TYPE} == single ]]; then
194 einfo "git-r3: ebuild needs to be cloned in 'single+tags' mode, adjusting"
195 EGIT_CLONE_TYPE=single+tags
163 fi 196 fi
164 ;; 197 ;;
165 mirror) 198 mirror)
166 if [[ ${EGIT_CLONE_TYPE} != mirror ]]; then 199 if [[ ${EGIT_CLONE_TYPE} != mirror ]]; then
167 einfo "git-r3: ebuild needs to be cloned in 'mirror' mode, adjusting" 200 einfo "git-r3: ebuild needs to be cloned in 'mirror' mode, adjusting"
279 GIT_DIR=${EGIT3_STORE_DIR}/${repo_name} 312 GIT_DIR=${EGIT3_STORE_DIR}/${repo_name}
280 313
281 if [[ ! -d ${EGIT3_STORE_DIR} ]]; then 314 if [[ ! -d ${EGIT3_STORE_DIR} ]]; then
282 ( 315 (
283 addwrite / 316 addwrite /
284 mkdir -m0755 -p "${EGIT3_STORE_DIR}" || die 317 mkdir -p "${EGIT3_STORE_DIR}" || die
285 ) || die "Unable to create ${EGIT3_STORE_DIR}" 318 ) || die "Unable to create ${EGIT3_STORE_DIR}"
286 fi 319 fi
287 320
288 addwrite "${EGIT3_STORE_DIR}" 321 addwrite "${EGIT3_STORE_DIR}"
289 if [[ ! -d ${GIT_DIR} ]]; then 322 if [[ ! -d ${GIT_DIR} ]]; then
323 local saved_umask
324 if [[ ${EVCS_UMASK} ]]; then
325 saved_umask=$(umask)
326 umask "${EVCS_UMASK}" || die "Bad options to umask: ${EVCS_UMASK}"
327 fi
290 mkdir "${GIT_DIR}" || die 328 mkdir "${GIT_DIR}" || die
291 git init --bare || die 329 git init --bare || die
330 if [[ ${saved_umask} ]]; then
331 umask "${saved_umask}" || die
332 fi
292 fi 333 fi
293} 334}
294 335
295# @FUNCTION: _git-r3_set_submodules 336# @FUNCTION: _git-r3_set_submodules
296# @USAGE: <file-contents> 337# @USAGE: <file-contents>
329 submodule."${subname}".path || die)" 370 submodule."${subname}".path || die)"
330 ) 371 )
331 done < <(echo "${data}" | git config -f /dev/fd/0 -l || die) 372 done < <(echo "${data}" | git config -f /dev/fd/0 -l || die)
332} 373}
333 374
375# @FUNCTION: _git-r3_set_subrepos
376# @USAGE: <submodule-uri> <parent-repo-uri>...
377# @INTERNAL
378# @DESCRIPTION:
379# Create 'subrepos' array containing absolute (canonical) submodule URIs
380# for the given <submodule-uri>. If the URI is relative, URIs will be
381# constructed using all <parent-repo-uri>s. Otherwise, this single URI
382# will be placed in the array.
383_git-r3_set_subrepos() {
384 debug-print-function ${FUNCNAME} "$@"
385
386 local suburl=${1}
387 subrepos=( "${@:2}" )
388
389 if [[ ${suburl} == ./* || ${suburl} == ../* ]]; then
390 # drop all possible trailing slashes for consistency
391 subrepos=( "${subrepos[@]%%/}" )
392
393 while true; do
394 if [[ ${suburl} == ./* ]]; then
395 suburl=${suburl:2}
396 elif [[ ${suburl} == ../* ]]; then
397 suburl=${suburl:3}
398
399 # XXX: correctness checking
400
401 # drop the last path component
402 subrepos=( "${subrepos[@]%/*}" )
403 # and then the trailing slashes, again
404 subrepos=( "${subrepos[@]%%/}" )
405 else
406 break
407 fi
408 done
409
410 # append the preprocessed path to the preprocessed URIs
411 subrepos=( "${subrepos[@]/%//${suburl}}")
412 else
413 subrepos=( "${suburl}" )
414 fi
415}
416
417
334# @FUNCTION: _git-r3_is_local_repo 418# @FUNCTION: _git-r3_is_local_repo
335# @USAGE: <repo-uri> 419# @USAGE: <repo-uri>
336# @INTERNAL 420# @INTERNAL
337# @DESCRIPTION: 421# @DESCRIPTION:
338# Determine whether the given URI specifies a local (on-disk) 422# Determine whether the given URI specifies a local (on-disk)
440 "${repos[@]}" 524 "${repos[@]}"
441 ) 525 )
442 fi 526 fi
443 527
444 # try to fetch from the remote 528 # try to fetch from the remote
445 local r success 529 local r success saved_umask
530 if [[ ${EVCS_UMASK} ]]; then
531 saved_umask=$(umask)
532 umask "${EVCS_UMASK}" || die "Bad options to umask: ${EVCS_UMASK}"
533 fi
446 for r in "${repos[@]}"; do 534 for r in "${repos[@]}"; do
447 einfo "Fetching ${r} ..." 535 einfo "Fetching ${r} ..."
448 536
449 local fetch_command=( git fetch "${r}" ) 537 local fetch_command=( git fetch "${r}" )
538 local clone_type=${EGIT_CLONE_TYPE}
450 539
451 if [[ ${EGIT_CLONE_TYPE} == mirror ]]; then 540 if [[ ${r} == https://* ]] && ! ROOT=/ has_version 'dev-vcs/git[curl]'; then
541 eerror "git-r3: fetching from https:// requested. In order to support https,"
542 eerror "dev-vcs/git needs to be built with USE=curl. Example solution:"
543 eerror
544 eerror " echo dev-vcs/git curl >> /etc/portage/package.use"
545 eerror " emerge -1v dev-vcs/git"
546 die "dev-vcs/git built with USE=curl required."
547 fi
548
549 if [[ ${r} == https://code.google.com/* ]]; then
550 # Google Code has special magic on top of git that:
551 # 1) can't handle shallow clones at all,
552 # 2) fetches duplicately when tags are pulled in with branch
553 # so automatically switch to single+tags mode.
554 if [[ ${clone_type} == shallow ]]; then
555 einfo " Google Code does not support shallow clones"
556 einfo " using EGIT_CLONE_TYPE=single+tags"
557 clone_type=single+tags
558 elif [[ ${clone_type} == single ]]; then
559 einfo " git-r3: Google Code does not send tags properly in 'single' mode"
560 einfo " using EGIT_CLONE_TYPE=single+tags"
561 clone_type=single+tags
562 fi
563 fi
564
565 if [[ ${clone_type} == mirror ]]; then
452 fetch_command+=( 566 fetch_command+=(
453 --prune 567 --prune
454 # mirror the remote branches as local branches 568 # mirror the remote branches as local branches
455 "refs/heads/*:refs/heads/*" 569 "+refs/heads/*:refs/heads/*"
456 # pull tags explicitly in order to prune them properly 570 # pull tags explicitly in order to prune them properly
457 "refs/tags/*:refs/tags/*" 571 "+refs/tags/*:refs/tags/*"
458 # notes in case something needs them 572 # notes in case something needs them
459 "refs/notes/*:refs/notes/*" 573 "+refs/notes/*:refs/notes/*"
460 # and HEAD in case we need the default branch 574 # and HEAD in case we need the default branch
461 # (we keep it in refs/git-r3 since otherwise --prune interferes) 575 # (we keep it in refs/git-r3 since otherwise --prune interferes)
462 HEAD:refs/git-r3/HEAD 576 "+HEAD:refs/git-r3/HEAD"
463 ) 577 )
464 else # single or shallow 578 else # single or shallow
465 local fetch_l fetch_r 579 local fetch_l fetch_r
466 580
467 if [[ ${remote_ref} == HEAD ]]; then 581 if [[ ${remote_ref} == HEAD ]]; then
487 else 601 else
488 fetch_l=HEAD 602 fetch_l=HEAD
489 fi 603 fi
490 604
491 # fetching by commit in shallow mode? can't do. 605 # fetching by commit in shallow mode? can't do.
492 if [[ ${EGIT_CLONE_TYPE} == shallow ]]; then 606 if [[ ${clone_type} == shallow ]]; then
493 local EGIT_CLONE_TYPE=single 607 clone_type=single
494 fi 608 fi
495 fi 609 fi
496 fi 610 fi
497 611
498 if [[ ${fetch_l} == HEAD ]]; then 612 if [[ ${fetch_l} == HEAD ]]; then
500 else 614 else
501 fetch_r=${fetch_l} 615 fetch_r=${fetch_l}
502 fi 616 fi
503 617
504 fetch_command+=( 618 fetch_command+=(
505 "${fetch_l}:${fetch_r}" 619 "+${fetch_l}:${fetch_r}"
506 ) 620 )
621
622 if [[ ${clone_type} == single+tags ]]; then
623 fetch_command+=(
624 # pull tags explicitly as requested
625 "+refs/tags/*:refs/tags/*"
626 )
507 fi 627 fi
628 fi
508 629
509 if [[ ${EGIT_CLONE_TYPE} == shallow ]]; then 630 if [[ ${clone_type} == shallow ]]; then
510 # use '--depth 1' when fetching a new branch 631 if _git-r3_is_local_repo; then
632 # '--depth 1' causes sandbox violations with local repos
633 # bug #491260
634 clone_type=single
511 if [[ ! $(git rev-parse --quiet --verify "${fetch_r}") ]] 635 elif [[ ! $(git rev-parse --quiet --verify "${fetch_r}") ]]
512 then 636 then
637 # use '--depth 1' when fetching a new branch
513 fetch_command+=( --depth 1 ) 638 fetch_command+=( --depth 1 )
514 fi 639 fi
515 else # non-shallow mode 640 else # non-shallow mode
516 if [[ -f ${GIT_DIR}/shallow ]]; then 641 if [[ -f ${GIT_DIR}/shallow ]]; then
517 fetch_command+=( --unshallow ) 642 fetch_command+=( --unshallow )
519 fi 644 fi
520 645
521 set -- "${fetch_command[@]}" 646 set -- "${fetch_command[@]}"
522 echo "${@}" >&2 647 echo "${@}" >&2
523 if "${@}"; then 648 if "${@}"; then
524 if [[ ${EGIT_CLONE_TYPE} == mirror ]]; then 649 if [[ ${clone_type} == mirror ]]; then
525 # find remote HEAD and update our HEAD properly 650 # find remote HEAD and update our HEAD properly
526 git symbolic-ref HEAD \ 651 git symbolic-ref HEAD \
527 "$(_git-r3_find_head refs/git-r3/HEAD \ 652 "$(_git-r3_find_head refs/git-r3/HEAD \
528 < <(git show-ref --heads || die))" \ 653 < <(git show-ref --heads || die))" \
529 || die "Unable to update HEAD" 654 || die "Unable to update HEAD"
564 689
565 success=1 690 success=1
566 break 691 break
567 fi 692 fi
568 done 693 done
694 if [[ ${saved_umask} ]]; then
695 umask "${saved_umask}" || die
696 fi
569 [[ ${success} ]] || die "Unable to fetch from any of EGIT_REPO_URI" 697 [[ ${success} ]] || die "Unable to fetch from any of EGIT_REPO_URI"
698
699 # submodules can reference commits in any branch
700 # always use the 'clone' mode to accomodate that, bug #503332
701 local EGIT_CLONE_TYPE=mirror
570 702
571 # recursively fetch submodules 703 # recursively fetch submodules
572 if git cat-file -e "${local_ref}":.gitmodules &>/dev/null; then 704 if git cat-file -e "${local_ref}":.gitmodules &>/dev/null; then
573 local submodules 705 local submodules
574 _git-r3_set_submodules \ 706 _git-r3_set_submodules \
581 local commit=$(git rev-parse "${local_ref}:${path}") 713 local commit=$(git rev-parse "${local_ref}:${path}")
582 714
583 if [[ ! ${commit} ]]; then 715 if [[ ! ${commit} ]]; then
584 die "Unable to get commit id for submodule ${subname}" 716 die "Unable to get commit id for submodule ${subname}"
585 fi 717 fi
586 if [[ ${url} == ./* || ${url} == ../* ]]; then 718
587 local subrepos=( "${repos[@]/%//${url}}" ) 719 local subrepos
588 else 720 _git-r3_set_subrepos "${url}" "${repos[@]}"
589 local subrepos=( "${url}" )
590 fi
591 721
592 git-r3_fetch "${subrepos[*]}" "${commit}" "${local_id}/${subname}" 722 git-r3_fetch "${subrepos[*]}" "${commit}" "${local_id}/${subname}"
593 723
594 submodules=( "${submodules[@]:3}" ) # shift 724 submodules=( "${submodules[@]:3}" ) # shift
595 done 725 done
717 847
718 while [[ ${submodules[@]} ]]; do 848 while [[ ${submodules[@]} ]]; do
719 local subname=${submodules[0]} 849 local subname=${submodules[0]}
720 local url=${submodules[1]} 850 local url=${submodules[1]}
721 local path=${submodules[2]} 851 local path=${submodules[2]}
852 local subrepos
853 _git-r3_set_subrepos "${url}" "${repos[@]}"
722 854
723 if [[ ${url} == ./* || ${url} == ../* ]]; then
724 url=${repos[0]%%/}/${url}
725 fi
726
727 git-r3_checkout "${url}" "${out_dir}/${path}" \ 855 git-r3_checkout "${subrepos[*]}" "${out_dir}/${path}" \
728 "${local_id}/${subname}" 856 "${local_id}/${subname}"
729 857
730 submodules=( "${submodules[@]:3}" ) # shift 858 submodules=( "${submodules[@]:3}" ) # shift
731 done 859 done
732 fi 860 fi

Legend:
Removed from v.1.35  
changed lines
  Added in v.1.49

  ViewVC Help
Powered by ViewVC 1.1.20