# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ # # Original Author: tiger683 # Purpose: Fetch the sources from a git repository # Basically it's a modified subversion.eclass... # ################################################################################## # # Settable stuff: # !!!!!!! Set these BEFORE inheriting this eclass !!!!!!! # ECOGITO_REPO_URI -> musthave # ECOGITO_PROJECT -> opt. , just project name, defaults to PN (strips -git) # ECOGITO_PATCHES -> opt. # ECOGITO_BOOTSTRAP -> opt. # ECOGITO_SEED_URI -> opt. # ECOGITO_SEED_REV -> don't set unless you know what u are doing # WGET_USER_AGENT -> for some paranoid servers, cloak wget as a useragent # (ie. Opera, Firefox etc.) ################################################################################## # FIXME: Clean stuff up so we don't have so many cg-commands chained? inherit eutils ECLASS="cogito" INHERITED="$INHERITED $ECLASS" ECOGITO="cogito.eclass" EXPORT_FUNCTIONS src_unpack # ------> REPO_URI # We support http(s):// and rsync:// . # We also need it here to determine wether we should depend # on net-misc/rsync, the result will also be reused in cogito_src_fetch # to determine if git needs USE="webdav" [ -z "${ECOGITO_REPO_URI}" ] && die "${ECOGITO}: nowhere to fetch from (ECOGITO_REPO_URI not set)" RSYNC_DEP="" case ${ECOGITO_REPO_URI%%:*} in http|https) ECOGITO_PROTOCOL="http/https" ;; rsync) RSYNC_DEP="net-misc/rsync" ECOGITO_PROTOCOL="rsync" ;; *) die "${ECOGITO}: Protocol not yet supported." ;; esac DEPEND="dev-util/git dev-util/cogito ${RSYNC_DEP}" # ------> URI of the seed tarball # seed tarball is of the form seed-${ECOGITO_SEED_REV}.tar.bz2 # ${ECOGITO_SEED_REV} is obtained from "${ECOGITO_SEED_URI}/seed_revision" [ -z "${ECOGITO_SEED_URI}" ] && ECOGITO_SEED_URI="" [ -z "${ECOGITO_SEED_REV}" ] && ECOGITO_SEED_REV="" # ------> Wget user agent parm [ -z "${ECOGITO_WGET_PARM}" ] && ECOGITO_WGET_PARM="" # ------> STOREDIR ECOGITO_STORE_DIR="${PORTAGE_ACTUAL_DISTDIR-${DISTDIR}}/git-src" # ------> Clone a git repo, this is checkout in cvs/svn ECOGITO_FETCH_CMD="cg-clone" # ------> Update previously cloned repo ECOGITO_UPDATE_CMD="cg-update" # ------> Project name # We checkout to ${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT} [ -z "${ECOGITO_PROJECT}" ] && ECOGITO_PROJECT="${PN/-git//}" # ------> Project source directory [ -z "${ECOGITO_PROJECT_SRC}" ] && ECOGITO_PROJECT_SRC="${ECOGITO_PROJECT}/src" # ------> Need patches before bootstrap? here is the right place [ -z "${ECOGITO_PATCHES}" ] && ECOGITO_PATCHES="" # ------> File or command to perform before return from exported src_unpack() [ -z "${ECOGITO_BOOTSTRAP}" ] && ECOGITO_BOOTSTRAP="" # This will actually become the command we'll perform ECOGITO_GIVE_IT_TO_ME="" ##-------------------------------------------------------------------------------## # @function: ecogito_setup_env # Check directory tree, setup global vars etc. function ecogito_setup_env() { addwrite / if [ ${ECOGITO_PROTOCOL} == "http/https" ]; then built_with_use dev-util/git webdav && \ built_with_use dev-util/git curl || \ die "Please reemerge dev-util/git with USE=\"webdav curl\" if you want ${ECOGITO_PROTOCOL} support !!!" fi if [ ! -d "${ECOGITO_STORE_DIR}" ]; then debug-print "${FUNCNAME}: first git-checkout ever. Creating git-src directory" mkdir -p "${ECOGITO_STORE_DIR}" || die "${ECOGITO}: can't mkdir ${ECOGITO_STORE_DIR}." chmod -f o+rw "${ECOGITO_STORE_DIR}" || die "${ECOGITO}: can't chmod ${ECOGITO_STORE_DIR}." export SANDBOX_WRITE="${SANDBOX_WRITE%%:/}" fi if [ "${WGET_USER_AGENT}" ]; then ECOGITO_WGET_PARM="--user-agent=${WGET_USER_AGENT} ${ECOGITO_WGET_PARM}" fi ECOGITO_WGET_PARM="--progress=bar:force ${ECOGITO_WGET_PARM}" addwrite "${ECOGITO_STORE_DIR}" if [ ! -d "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}" ]; then mkdir -p "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}" fi if [ -f "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/seed_revision ]; then rm "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/seed_revision fi } ##-------------------------------------------------------------------------------## # @function: seed_tarball_checksum function seed_tarball_checksum() { addwrite "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}" cd "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}" if [ -f seed-"${ECOGITO_SEED_REV}".md5sum ]; then rm seed-"${ECOGITO_SEED_REV}".md5sum fi wget "${ECOGITO_SEED_URI}"/seed-"${ECOGITO_SEED_REV}".md5sum ${ECOGITO_WGET_PARM} || \ die "Failed to fetch md5sum file for seed." md5sum -c seed-"${ECOGITO_SEED_REV}".md5sum || \ die "Checksum error on seed tarball, cowardly bailing out" } ##-------------------------------------------------------------------------------## # @function: seed_tarball_update # # This checks seed tarball and updates the repo if tarball revision changed # It normally happens on major tree change, when fast forward merge would not # work anymore. It's up to maintainers to keep seed in sync with repo ;) function seed_test_update() { local dounpack dofetch resume resume="" dofetch="" dounpack="" addwrite "${ECOGITO_STORE_DIR}" cd "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}" if [ "${ECOGITO_SEED_URI}" ]; then # Retrieve seed revision if none specified (plz. don't do it) [ ! ${ECOGITO_SEED_REV} ] && einfo "Checking seed revision..." && \ wget "${ECOGITO_SEED_URI}"/seed_revision ${ECOGITO_WGET_PARM} && \ ECOGITO_SEED_REV=`cat seed_revision` || die "Failed to fetch ${ECOGITO_SEED_URI}/seed_revision" # Tell wget to resume an eventually incomplete seed download: [ -f "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/seed-"${ECOGITO_SEED_REV}".tar.bz2 ] && \ ECOGITO_WGET_PARM="${ECOGITO_WGET_PARM} -c" && resume="1" # Check if THIS version of seed got previously completely unpacked [ ! -f "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/.seed_${ECOGITO_SEED_REV}_unpacked ] && dounpack="1" # Check for completely broken repo [ ! -d "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}"/.git ] && dounpack="1" # Check if previous download was complete (we stamp on completion) [ ! -f "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/.seed-"${ECOGITO_SEED_REV}" ] && dofetch="1" else echo "" einfo "No seed tarball URI specified, performing git-only checkout..." echo "" fi if [ ${dounpack} ]; then if [ ${dofetch} ]; then if [ ! ${resume} ]; then einfo "Outdated or missing seed tarball, downloading..." else einfo "Resuming seed download..." fi # Fetch the seed wget "${ECOGITO_SEED_URI}"/seed-"${ECOGITO_SEED_REV}".tar.bz2 ${ECOGITO_WGET_PARM} || \ die "Failed to fetch seed-${ECOGITO_SEED_REV}.tar.bz2" seed_tarball_checksum && touch "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/.seed-"${ECOGITO_SEED_REV}" fi einfo "Unpacking seed tarball..." if [ -f "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/.seed_${ECOGITO_SEED_REV}_unpacked ]; then rm "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/.seed_${ECOGITO_SEED_REV}_unpacked || \ die " Removing .seed_${ECOGITO_SEED_REV}_unpacked failed. " fi if [ ! -d "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}" ]; then mkdir "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}" else rm -Rf "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}" && \ mkdir "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}" || \ die "Cleaning up sourcedir failed..." fi tar xjf seed-"${ECOGITO_SEED_REV}".tar.bz2 -C "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}"/ && \ cd "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}" && \ cg-restore && \ touch "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/.seed_${ECOGITO_SEED_REV}_unpacked && \ echo " done." || \ die "Unpacking seed-${ECOGITO_SEED_REV}.tar.bz2 failed." # Make src_fetch happy ;) touch "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT}/.checked-out" else einfo "Seed tarball uptodate, skipping..." fi } ##-------------------------------------------------------------------------------## # @function: cogito_checkout function cogito_checkout() { einfo "Initializing cogito checkout ------>" einfo " cloning repository:" einfo " ${ECOGITO_REPO_URI}" if [ ! -d "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT_SRC}" ]; then mkdir "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT_SRC}" || die "${ECOGITO}: can't mkdir ./${ECOGITO_PROJECT_SRC}" chmod -Rf o+rw "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT}" || die "${ECOGITO}: can't chmod ${ECOGITO_PROJECT}." fi cd "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT_SRC}" || die "${ECOGITO}: cd failed, wtf?" ECOGITO_GIVE_IT_TO_ME="${ECOGITO_FETCH_CMD} -s ${ECOGITO_REPO_URI}" echo "" } ##-------------------------------------------------------------------------------## # @function: cogito_resume function cogito_resume() { # Incomplete fetch detected, but don't panic ;) einfo "Resuming cogito checkout ------>" echo "" cd "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT_SRC}" || die "${ECOGITO}: cd failed, wtf?" ECOGITO_GIVE_IT_TO_ME="${ECOGITO_UPDATE_CMD}" } ##-------------------------------------------------------------------------------## # @function: cogito_update function cogito_update() { # Standard update stuff einfo "Initializing cogito update ------>" einfo " updating ..." rm "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT}/.checked-out" || die "${ECOGITO}: removing stamp failed" cd "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT_SRC}" ECOGITO_GIVE_IT_TO_ME="${ECOGITO_UPDATE_CMD}" echo "" } ##-------------------------------------------------------------------------------## # @function: cogito_src_fetch # HERE BE MONSTERS function cogito_src_fetch() { einfo "Using GIT protocol: ${ECOGITO_PROTOCOL}" echo "" # Bypass symlinks cd -P "${ECOGITO_STORE_DIR}" || die "${ECOGITO}: can't chdir to ${ECOGITO_STORE_DIR}" ECOGITO_STORE_DIR=${PWD} addwrite "${ECOGITO_STORE_DIR}" # This is the checkout logic: # We stamp successfully completed checkouts with # ${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT}/.checked-out file ;) if [ ! -f "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT}/.checked-out" ]; then # incomplete checkout, investigate... if [ -d "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT_SRC}" ]; then # Hrmm, someone already was here... if [ ! -d "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT_SRC}/.git" ]; then # and messed up bigtime :? ewarn "Found completely b0rked repo: ${ECOGITO_PROJECT_SRC}" ewarn " deleting...." echo "" rm -R "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT_SRC}" || \ die "${ECOGITO}: this directory is messed up, remove manually: ${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT}" cogito_checkout else cogito_resume fi else # Mmmmm, virgin ..... XD cogito_checkout fi else cogito_update fi eval "${ECOGITO_GIVE_IT_TO_ME}" || die "${ECOGITO}: ${ECOGITO_GIVE_IT_TO_ME} failed" touch "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT}"/.checked-out einfo "Contents of repository" einfo " ${ECOGITO_REPO_URI}" einfo "are now in:" einfo " ${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT_SRC}" echo "" # Let's prepare stuff for src_compile() einfo "Copying source:" # paranoid :} cd "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT_SRC}" if [ ! -d "${ECOGITO_STORE_DIR}/${ECOGITO_PROJECT}"/.bak ]; then mkdir "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/.bak fi echo " moving \".git\" into temporary..." if [ -d "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/.bak/.git ]; then if [ -d "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}"/.git ]; then rm -Rf "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/.bak/.git || die "Impossible (1) happened, bug me about it --tiger683" else mv "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/.bak/.git "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}"/ || die "Impossible (2) happened, bug me about it --tiger683" fi fi mv "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}"/.git "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}"/.bak/ && \ echo " copying into sourcedir..." && \ cp -pPR "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}" "${S}" && \ echo " moving \".git\" back..." && \ mv "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT}/.bak/.git" "${ECOGITO_STORE_DIR}"/"${ECOGITO_PROJECT_SRC}"/ && \ echo " done." && \ einfo " exported to: ${S}" || die "Bug while exporting into {S}, contact tiger683 on gentoo forums and file a bug..." } ##-------------------------------------------------------------------------------## # @function: cogito_bootstrap # Copied from subversion.eclass almost 1:1 function cogito_bootstrap() { local patch lpatch cd "${S}" if [ "${ECOGITO_PATCHES}" ]; then einfo "apply patches ------>" for patch in ${ECOGITO_PATCHES}; do if [ -f "${patch}" ]; then epatch ${patch} else for lpatch in ${FILESDIR}/${patch}; do if [ -f "${lpatch}" ]; then epatch ${lpatch} else die "${ECOGITO}: ${patch} is not found" fi done fi done echo fi if [ "${ECOGITO_BOOTSTRAP}" ]; then einfo "begin bootstrap ------>" if [ -f "${ECOGITO_BOOTSTRAP}" -a -x "${ECOGITO_BOOTSTRAP}" ]; then einfo " bootstrap with a file: ${ECOGITO_BOOTSTRAP}" eval "./${ECOGITO_BOOTSTRAP}" || die "${ECOGITO}: can't execute ECOGITO_BOOTSTRAP." else einfo " bootstrap with commands: ${ECOGITO_BOOTSTRAP}" eval "${ECOGITO_BOOTSTRAP}" || die "${ECOGITO}: can't eval ECOGITO_BOOTSTRAP." fi fi } ##-------------------------------------------------------------------------------## # @function: cogito_src_unpack # This one is exported function cogito_src_unpack() { if [ -n "${A}" ]; then unpack ${A} fi ecogito_setup_env || die "${ECOGITO}: ecogito_setup_env messed up :/" seed_test_update || die "${ECOGITO}: seed_test_update messed up :/" cogito_src_fetch || die "${ECOGITO}: cogito_src_fetch messed up :/" cogito_bootstrap || die "${ECOGITO}: cogito_bootstrap messed up :/" }