For quite a while the KDE herd has had a modified version of subversion.eclass 
in the kde overlay. During that time we have added the following features to 
the eclass which we would like to put back in gentoo-x86 soon. Since the 
changes are fairly extensive we decided to send it to this list for review 
first.

1) ESVN_REVISION (before this people had to use ESVN_OPTIONS for this 
purpose).
2) ESVN_OFFLINE which disables svn up.
3) ESVN_UP_FREQ which uses GNU find to determine if the specified number of 
hours has passed and only do svn up if it has. This is currently used in the 
kde4svn-meta eclass for split kde ebuilds that use the same checkout of each 
module.
4) ESCM_LOGDIR for logging which revisions packages get installed with. See 
[1]. Users need to explicitly enable this feature to use it.

Other than this the eclass has been documented for use with eclass-manpages.

[1] http://thread.gmane.org/gmane.linux.gentoo.devel/54233

-- 
Bo Andresen
Gentoo KDE dev
--- /var/repositories/gentoo/eclass/subversion.eclass	2007-07-03 10:36:11.000000000 +0200
+++ /home/bo/git/genkde4svn-dev/eclass/subversion.eclass	2008-02-15 23:27:36.000000000 +0100
@@ -1,56 +1,52 @@
-# Copyright 1999-2007 Gentoo Foundation
+# Copyright 1999-2008 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/eclass/subversion.eclass,v 1.44 2007/07/03 08:27:40 peper Exp $
+# $Header: $
 
-## --------------------------------------------------------------------------- #
-# Author: Akinori Hattori <[EMAIL PROTECTED]>
+# @ECLASS: subversion.eclass
+# @MAINTAINER:
+# ???
+#
+# Original author: Akinori Hattori <[EMAIL PROTECTED]>
+# @BLURB: The subversion eclass is written to fetch software sources from subversion repositories
+# @DESCRIPTION:
+# The subversion eclass provides functions to fetch, patch and bootstrap
+# software sources from subversion repositories.
 #
-# The subversion eclass is written to fetch the software sources from
-# subversion repositories like the cvs eclass.
-#
-#
-# Description:
-#   If you use this eclass, the ${S} is ${WORKDIR}/${P}.
-#   It is necessary to define the ESVN_REPO_URI variable at least.
-#
-## --------------------------------------------------------------------------- #
+# You must define the ESVN_REPO_URI variable before inheriting this eclass.
 
 inherit eutils
 
 ESVN="subversion.eclass"
 
-EXPORT_FUNCTIONS src_unpack
+EXPORT_FUNCTIONS src_unpack pkg_preinst
 
 DESCRIPTION="Based on the ${ECLASS} eclass"
 
-
-## -- add subversion in DEPEND
-#
 DEPEND="dev-util/subversion"
 
-
-## -- ESVN_STORE_DIR:  subversion sources store directory
-#
-ESVN_STORE_DIR="${PORTAGE_ACTUAL_DISTDIR-${DISTDIR}}/svn-src"
-
-
-## -- ESVN_FETCH_CMD:  subversion fetch command
-#
+# @ECLASS-VARIABLE: ESVN_STORE_DIR
+# @DESCRIPTION:
+# subversion sources store directory
+ESVN_STORE_DIR="${PORTAGE_ACTUAL_DISTDIR:-${DISTDIR}}/svn-src"
+
+# @ECLASS-VARIABLE: ESVN_FETCH_CMD
+# @DESCRIPTION:
+# subversion fetch command
 ESVN_FETCH_CMD="svn checkout"
 
-## -- ESVN_UPDATE_CMD:  subversion update command
-#
+# @ECLASS-VARIABLE: ESVN_UPDATE_CMD
+# @DESCRIPTION:
+# subversion update command
 ESVN_UPDATE_CMD="svn update"
 
-
-## -- ESVN_OPTIONS:
-#
+# @ECLASS-VARIABLE: ESVN_OPTIONS:
+# @DESCRIPTION:
 # the options passed to checkout or update.
-#
-: ${ESVN_OPTIONS=}
-
+ESVN_OPTIONS="${ESVN_OPTIONS:=}"
 
-## -- ESVN_REPO_URI:  repository uri
+# @ECLASS-VARIABLE: ESVN_REPO_URI
+# @DESCRIPTION:
+# repository uri
 #
 # e.g. http://foo/trunk, svn://bar/trunk
 #
@@ -59,11 +55,19 @@
 #   https://
 #   svn://
 #   svn+ssh://
-#
-: ${ESVN_REPO_URI=}
-
+ESVN_REPO_URI="${ESVN_REPO_URI:=}"
 
-## -- ESVN_PROJECT:  project name of your ebuild (= name space)
+# @ECLASS-VARIABLE: ESVN_REVISION
+# @DESCRIPTION:
+# svn revision to fetch
+#
+# Note that if you're specifying a revision to fetch in ESVN_OPTIONS while
+# setting ESVN_REVISION, you will get an error message.
+ESVN_REVISION="${ESVN_REVISION:=}"
+
+# @ECLASS-VARIABLE: ESVN_PROJECT
+# @DESCRIPTION:
+# project name of your ebuild (= name space)
 #
 # subversion eclass will check out the subversion repository like:
 #
@@ -82,45 +86,62 @@
 #   ESVN_PROJECT=commons/logging
 #
 # default: ${PN/-svn}.
-#
-: ${ESVN_PROJECT:=${PN/-svn}}
-
+ESVN_PROJECT="${ESVN_PROJECT:=${PN/-svn}}"
 
-## -- ESVN_BOOTSTRAP:
-#
+# @ECLASS-VARIABLE: ESVN_BOOTSTRAP
+# @DESCRIPTION:
 # bootstrap script or command like autogen.sh or etc..
-#
-: ${ESVN_BOOTSTRAP=}
-
+ESVN_BOOTSTRAP="${ESVN_BOOTSTRAP:=}"
 
-## -- ESVN_PATCHES:
-#
-# subversion eclass can apply pathces in subversion_bootstrap().
+# @ECLASS-VARIABLE: ESVN_PATCHES
+# @DESCRIPTION:
+# subversion eclass can apply patches in subversion_bootstrap().
 # you can use regexp in this variable like *.diff or *.patch or etc.
 # NOTE: patches will be applied before ESVN_BOOTSTRAP is processed.
 #
 # Patches are searched both in / and ${FILESDIR}, if not found in both locations,
 # the installation dies.
-#
-: ${ESVN_PATCHES=}
-
+ESVN_PATCHES="${ESVN_PATCHES:=}"
 
-## -- ESVN_RESTRICT:
-#
+# @ECLASS-VARIABLE: ESVN_RESTRICT
+# @DESCRIPTION:
 # this should be a space delimited list of subversion eclass features to
 # restrict.
 #   export)
 #     don't export the working copy to S.
-#
-: ${ESVN_RESTRICT=}
-
+ESVN_RESTRICT="${ESVN_RESTRICT:=}"
 
-## -- subversion_fetch() ----------------------------------------------------- #
-#
-# @param $1 - a repository URI. default is the ESVN_REPO_URI.
-# @param $2 - a check out path in S.
-#
-function subversion_fetch() {
+# @ECLASS-VARIABLE: ESVN_OFFLINE
+# @DESCRIPTION:
+# setting this variable to a non-empty value disables the automatic updating of an svn source
+# tree. It is meant to be set outside the subversion source tree by the user.
+ESVN_OFFLINE="${ESVN_OFFLINE:=${ESCM_OFFLINE}}"
+
+# @ECLASS-VARIABLE: ESVN_UP_FREQ
+# @DESCRIPTION:
+# Set the minimum number of hours between svn up'ing in any given svn module. This is particularly
+# useful for split KDE ebuilds where we want to ensure that all submodules are compiled for the same
+# revision. It should also be kept user overrideable.
+ESVN_UP_FREQ="${ESVN_UP_FREQ:=}"
+
+# @ECLASS-VARIABLE: ESCM_LOGDIR
+# @DESCRIPTION:
+# User configuration variable. If set to a path such as e.g. /var/log/scm any
+# package inheriting from subversion.eclass will record svn revision to
+# ${CATEGORY}/${PN}.log in that path in pkg_preinst. This is not supposed to be
+# set by ebuilds/eclasses. It defaults to empty so users need to opt in.
+ESCM_LOGDIR="${ESCM_LOGDIR:=}"
+
+# @FUNCTION: subversion_fetch
+# @USAGE: [repo_uri] [destination]
+# @DESCRIPTION:
+# Wrapper function to fetch sources from subversion ( either svn checkout or svn update, depending on
+# whether we're doing an initial checkout or an incremental update ).
+#
+# Can take two optional parameters:
+#   repo_uri    - a repository URI. default is ESVN_REPO_URI.
+#   destination - a check out path in S.
+subversion_fetch() {
 	local repo_uri="$(subversion__get_repository_uri "${1}")"
 	local S_dest="${2}"
 
@@ -147,7 +168,11 @@
 	addread "/etc/subversion"
 	addwrite "${ESVN_STORE_DIR}"
 
-	if [[ ! -d "${ESVN_STORE_DIR}" ]]; then
+	if [[ ! -d ${ESVN_STORE_DIR} ]]; then
+		if [[ ${ESVN_STORE_DIR} != ${PORTAGE_ACTUAL_DISTDIR:-${DISTDIR}}/svn-src && \
+			${ESVN_STORE_DIR} == ${PORTAGE_ACTUAL_DISTDIR:-${DISTDIR}}/svn-src* ]]; then
+			addwrite "${PORTAGE_ACTUAL_DISTDIR:-${DISTDIR}}/svn-src"
+		fi
 		debug-print "${FUNCNAME}: initial checkout. creating subversion directory"
 		mkdir -p "${ESVN_STORE_DIR}" || die "${ESVN}: can't mkdir ${ESVN_STORE_DIR}."
 	fi
@@ -155,38 +180,59 @@
 	cd "${ESVN_STORE_DIR}" || die "${ESVN}: can't chdir to ${ESVN_STORE_DIR}"
 
 	local wc_path="$(subversion__get_wc_path "${repo_uri}")"
+	local revision= nosvnup=
+	[[ -n ${ESVN_REVISION} ]] && revision="-r${ESVN_REVISION}"
 	local options="${ESVN_OPTIONS} --config-dir ${ESVN_STORE_DIR}/.subversion"
 
 	debug-print "${FUNCNAME}: wc_path = \"${wc_path}\""
+	debug-print "${FUNCNAME}: ESVN_REVISION = \"${ESVN_REVISION}\""
+	debug-print "${FUNCNAME}: revision = \"${revision}\""
 	debug-print "${FUNCNAME}: ESVN_OPTIONS = \"${ESVN_OPTIONS}\""
 	debug-print "${FUNCNAME}: options = \"${options}\""
 
-	if [[ ! -d "${wc_path}/.svn" ]]; then
+	if [[ ! -d ${wc_path}/.svn ]]; then
 		# first check out
 		einfo "subversion check out start -->"
 		einfo "     repository: ${repo_uri}"
 
-		debug-print "${FUNCNAME}: ${ESVN_FETCH_CMD} ${options} ${repo_uri}"
+		debug-print "${FUNCNAME}: ${ESVN_FETCH_CMD} ${revision} ${options} ${repo_uri}"
 
 		mkdir -p "${ESVN_PROJECT}" || die "${ESVN}: can't mkdir ${ESVN_PROJECT}."
 		cd "${ESVN_PROJECT}" || die "${ESVN}: can't chdir to ${ESVN_PROJECT}"
-		${ESVN_FETCH_CMD} ${options} "${repo_uri}" || die "${ESVN}: can't fetch from ${repo_uri}."
+		${ESVN_FETCH_CMD} ${revision} ${options} "${repo_uri}" || die "${ESVN}: can't fetch from ${repo_uri}."
 
 		subversion_wc_info "${repo_uri}" || die "${ESVN}: unknown problem occurred while accessing working copy."
+	elif [[ -n ${ESVN_OFFLINE} ]]; then
+		subversion_wc_info "${repo_uri}" || die "${ESVN}: unknown problem occurred while accessing working copy."
+		if [[ -n ${ESVN_REVISION} && ${ESVN_REVISION} != ${ESVN_WC_REVISION} ]]; then
+			die "${ESVN}: You requested off-line updating and revision ${ESVN_REVISION} but only revision ${ESVN_WC_REVISION} is available locally."
+		fi
+		einfo "Fetching disabled: Using existing repository copy"
 	else
 		subversion_wc_info "${repo_uri}" || die "${ESVN}: unknown problem occurred while accessing working copy."
-		if [ "${ESVN_WC_URL}" != "$(subversion__get_repository_uri "${repo_uri}" 1)" ]; then
+		if [[ ${ESVN_WC_URL} != $(subversion__get_repository_uri "${repo_uri}" 1) ]]; then
 			die "${ESVN}: ESVN_REPO_URI (or specified URI) and working copy's URL are not matched."
 		fi
 
-		# update working copy
-		einfo "subversion update start -->"
-		einfo "     repository: ${repo_uri}"
+		if [[ -n ${ESVN_UP_FREQ} ]]; then
+			if [[ -n ${ESVN_UP_FREQ//[[:digit:]]} ]]; then
+				die "${ESVN}: ESVN_UP_FREQ must be an integer value corresponding to the minimum number of hours between svn up."
+			fi
+			if [[ -z $(find "${wc_path}/.svn/entries" -mmin "+$((ESVN_UP_FREQ*60))") ]]; then
+				nosvnup=0
+			fi
+		fi
 
-		debug-print "${FUNCNAME}: ${ESVN_UPDATE_CMD} ${options}"
+		if [[ -z ${nosvnup} ]]; then
+			# update working copy
+			einfo "subversion update start -->"
+			einfo "     repository: ${repo_uri}"
 
-		cd "${wc_path}" || die "${ESVN}: can't chdir to ${wc_path}"
-		${ESVN_UPDATE_CMD} ${options} || die "${ESVN}: can't update from ${repo_uri}."
+			debug-print "${FUNCNAME}: ${ESVN_UPDATE_CMD} ${revision} ${options}"
+
+			cd "${wc_path}" || die "${ESVN}: can't chdir to ${wc_path}"
+			${ESVN_UPDATE_CMD} ${revision} ${options} || die "${ESVN}: can't update from ${repo_uri}."
+		fi
 	fi
 
 	einfo "   working copy: ${wc_path}"
@@ -205,26 +251,26 @@
 	echo
 }
 
-
-## -- subversion_bootstrap() ------------------------------------------------ #
-#
-function subversion_bootstrap() {
+# @FUNCTION: subversion_bootstrap
+# @DESCRIPTION:
+# Apply patches in ${ESVN_PATCHES} and run ${ESVN_BOOTSTRAP} if specified.
+subversion_bootstrap() {
 	if has "export" ${ESVN_RESTRICT}; then
 		return
 	fi
 
 	cd "${S}"
 
-	if [[ -n "${ESVN_PATCHES}" ]]; then
+	if [[ -n ${ESVN_PATCHES} ]]; then
 		einfo "apply patches -->"
 
 		local patch fpatch
 		for patch in ${ESVN_PATCHES}; do
-			if [[ -f "${patch}" ]]; then
+			if [[ -f ${patch} ]]; then
 				epatch "${patch}"
 			else
 				for fpatch in ${FILESDIR}/${patch}; do
-					if [[ -f "${fpatch}" ]]; then
+					if [[ -f ${fpatch} ]]; then
 						epatch "${fpatch}"
 					else
 						die "${ESVN}: ${patch} not found"
@@ -235,10 +281,10 @@
 		echo
 	fi
 
-	if [[ -n "${ESVN_BOOTSTRAP}" ]]; then
+	if [[ -n ${ESVN_BOOTSTRAP} ]]; then
 		einfo "begin bootstrap -->"
 
-		if [[ -f "${ESVN_BOOTSTRAP}" && -x "${ESVN_BOOTSTRAP}" ]]; then
+		if [[ -f ${ESVN_BOOTSTRAP} && -x ${ESVN_BOOTSTRAP} ]]; then
 			einfo "   bootstrap with a file: ${ESVN_BOOTSTRAP}"
 			eval "./${ESVN_BOOTSTRAP}" || die "${ESVN}: can't execute ESVN_BOOTSTRAP."
 		else
@@ -248,26 +294,27 @@
 	fi
 }
 
-## -- subversion_src_unpack() ------------------------------------------------ #
-#
-function subversion_src_unpack() {
+# @FUNCTION: subversion_src_unpack
+# @DESCRIPTION:
+# default src_unpack. fetch and bootstrap.
+subversion_src_unpack() {
 	subversion_fetch     || die "${ESVN}: unknown problem occurred in subversion_fetch."
 	subversion_bootstrap || die "${ESVN}: unknown problem occurred in subversion_bootstrap."
 }
 
-
-## -- subversion_wc_info() --------------------------------------------------- #
-#
-# @param $1 - repository URI. default is ESVN_REPO_URI.
-#
-function subversion_wc_info() {
+# @FUNCTION: subversion_wc_info
+# @USAGE: [repo_uri]
+# @RETURN: ESVN_WC_URL and ESVN_WC_REVISION
+# @DESCRIPTION:
+# Get svn info for the specified repo_uri. The default repo_uri is ESVN_REPO_URI.
+subversion_wc_info() {
 	local repo_uri="$(subversion__get_repository_uri "${1}")"
 	local wc_path="$(subversion__get_wc_path "${repo_uri}")"
 
 	debug-print "${FUNCNAME}: repo_uri = ${repo_uri}"
 	debug-print "${FUNCNAME}: wc_path = ${wc_path}"
 
-	if [[ ! -e "${wc_path}" ]]; then
+	if [[ ! -e ${wc_path} ]]; then
 		return 1
 	fi
 
@@ -282,10 +329,10 @@
 
 ## -- subversion__svn_info() ------------------------------------------------- #
 #
-# @param $1 - a target.
-# @param $2 - a key name.
+# param $1 - a target.
+# param $2 - a key name.
 #
-function subversion__svn_info() {
+subversion__svn_info() {
 	local target="${1}"
 	local key="${2}"
 
@@ -295,27 +342,27 @@
 
 ## -- subversion__get_repository_uri() --------------------------------------- #
 #
-# @param $1 - a repository URI.
-# @param $2 - a peg revision is deleted from a return value if this is
+# param $1 - a repository URI.
+# param $2 - a peg revision is deleted from a return value if this is
 #             specified.
 #
-function subversion__get_repository_uri() {
+subversion__get_repository_uri() {
 	local repo_uri="${1:-${ESVN_REPO_URI}}"
 	local remove_peg_revision="${2}"
 
 	debug-print "${FUNCNAME}: repo_uri = ${repo_uri}"
 	debug-print "${FUNCNAME}: remove_peg_revision = ${remove_peg_revision}"
 
-	if [[ -z "${repo_uri}" ]]; then
+	if [[ -z ${repo_uri} ]]; then
 		die "${ESVN}: ESVN_REPO_URI (or specified URI) is empty."
 	fi
 
 	# delete trailing slash
-	if [[ -z "${repo_uri##*/}" ]]; then
+	if [[ -z ${repo_uri##*/} ]]; then
 		repo_uri="${repo_uri%/}"
 	fi
 
-	if [[ -n "${remove_peg_revision}" ]]; then
+	if [[ -n ${remove_peg_revision} ]]; then
 		if subversion__has_peg_revision "${repo_uri}"; then
 			repo_uri="[EMAIL PROTECTED]"
 
@@ -330,9 +377,9 @@
 
 ## -- subversion__get_wc_path() ---------------------------------------------- #
 #
-# @param $1 - a repository URI.
+# param $1 - a repository URI.
 #
-function subversion__get_wc_path() {
+subversion__get_wc_path() {
 	local repo_uri="$(subversion__get_repository_uri "${1}" 1)"
 
 	debug-print "${FUNCNAME}: repo_uri = ${repo_uri}"
@@ -343,15 +390,15 @@
 
 ## -- subversion__has_peg_revision() ----------------------------------------- #
 #
-# @param $1 - a repository URI.
+# param $1 - a repository URI.
 #
-function subversion__has_peg_revision() {
+subversion__has_peg_revision() {
 	local repo_uri="${1}"
 
 	debug-print "${FUNCNAME}: repo_uri = ${repo_uri}"
 
 	# repo_uri has peg revision ?
-	if [[ "${repo_uri}" != [EMAIL PROTECTED] ]]; then
+	if [[ ${repo_uri} != [EMAIL PROTECTED] ]]; then
 		debug-print "${FUNCNAME}: repo_uri does not have a peg revision."
 		return 1
 	fi
@@ -381,8 +428,31 @@
 
 ## -- subversion__to_upper_case() ----------------------------------------- #
 #
-# @param $@ - the strings to upper case.
+# param $@ - the strings to upper case.
 #
-function subversion__to_upper_case() {
-	echo "[EMAIL PROTECTED]" | tr "[a-z]" "[A-Z]"
+subversion__to_upper_case() {
+	echo "[EMAIL PROTECTED]" | tr "[:lower:]" "[:upper:]"
+}
+
+# @FUNCTION: subversion_pkg_preinst
+# @DESCRIPTION:
+# Log the svn revision of source code. Doing this in pkg_preinst because we
+# want the logs to stick around if packages are uninstalled without messing with
+# config protection.
+subversion_pkg_preinst() {
+	local pkgdate=$(date "+%Y%m%d %H:%M:%S")
+	subversion_wc_info
+	if [[ -n ${ESCM_LOGDIR} ]]; then
+		local dir="${ROOT}/${ESCM_LOGDIR}/${CATEGORY}"
+		if [[ ! -d ${dir} ]]; then
+			mkdir -p "${dir}" || \
+				eerror "Failed to create '${dir}' for logging svn revision to '${PORTDIR_SCM}'"
+		fi
+		local logmessage="svn: ${pkgdate} - ${PF}:${SLOT} was merged at revision ${ESVN_WC_REVISION}"
+		if [[ -d ${dir} ]]; then
+			echo "${logmessage}" >> "${dir}/${PN}.log"
+		else
+			eerror "Could not log the message '${logmessage}' to '${dir}/${PN}.log'"
+		fi
+	fi
 }

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to