Hi,
I got enough annoyed by check-reqs.eclass using epause and other nasty things so I updated it to do this things:

* eclassdoc
* use pkg_pretend and pkg_setup phases to run the checks
* warn if ebuild use deprecated calls and keep backompat
* remove duplicated/unused code
* support for metrics 1G 15T instead of requiring all values to be entered in megabytes.

Cheers

Tom
Index: check-reqs.eclass
===================================================================
RCS file: /var/cvsroot/gentoo-x86/eclass/check-reqs.eclass,v
retrieving revision 1.8
diff -u -b -B -r1.8 check-reqs.eclass
--- check-reqs.eclass	22 Aug 2011 04:46:31 -0000	1.8
+++ check-reqs.eclass	30 Aug 2011 06:56:43 -0000
@@ -4,8 +4,9 @@
 
 # @ECLASS: check-reqs.eclass
 # @MAINTAINER:
-# Bo Ørsted Andresen <z...@gentoo.org>
+# QA Team <q...@gentoo.org>
 # @AUTHOR:
+# Bo Ørsted Andresen <z...@gentoo.org>
 # Original Author: Ciaran McCreesh <ciar...@gentoo.org>
 # @BLURB: Provides a uniform way of handling ebuild which have very high build requirements
 # @DESCRIPTION:
@@ -13,49 +14,34 @@
 # build requirements in terms of memory or disk space. It provides a function
 # which should usually be called during pkg_setup().
 #
-# From a user perspective, the variable CHECKREQS_ACTION can be set to:
-#    * "warn" (default), which will display a warning and wait for 15s
-#    * "error", which will make the ebuild error out
-#    * "ignore", which will not take any action
-#
 # The chosen action only happens when the system's resources are detected
 # correctly and only if they are below the threshold specified by the package.
 #
-# For ebuild authors: only use this eclass if you reaaalllllly have stupidly
-# high build requirements. At an absolute minimum, you shouldn't be using this
-# unless the ebuild needs >256MBytes RAM or >1GByte temporary or install space.
-# The code should look something like:
-#
 # @CODE
-# pkg_setup() {
-#     # values in MBytes
-#
 #     # need this much memory (does *not* check swap)
-#     CHECKREQS_MEMORY="256"
+# CHECKREQS_MEMORY="256M"
 #
 #     # need this much temporary build space
-#     CHECKREQS_DISK_BUILD="2048"
+# CHECKREQS_DISK_BUILD="2G"
 #
 #     # install will need this much space in /usr
-#     CHECKREQS_DISK_USR="1024"
+# CHECKREQS_DISK_USR="1G"
 #
 #     # install will need this much space in /var
-#     CHECKREQS_DISK_VAR="1024"
+# CHECKREQS_DISK_VAR="1024M"
 #
 #     # go!
-#     check_reqs
+# pkg_pretend() {
+#    check-reqs_pkg_pretend
+# }
+# 
+# # Run once again to ensure that environment didn't
+# # change since the pretend phase.
+# pkg_setup() {
+#    check-reqs_pkg_setup
 # }
 # @CODE
 #
-# Alternatively, the check_reqs_conditional function can be used to carry out
-# alternate actions (e.g. using a much slower but far less memory intensive
-# build option that gives the same end result).
-#
-# You should *not* override the user's CHECKREQS_ACTION setting, nor should you
-# attempt to provide a value if it is unset. Note that the environment variables
-# are used rather than parameters for a few reasons:
-#   * easier to do if use blah ; then things
-#   * we might add in additional requirements things later
 # If you don't specify a value for, say, CHECKREQS_MEMORY, then the test is not
 # carried out.
 #
@@ -66,80 +52,234 @@
 
 # @ECLASS-VARIABLE: CHECKREQS_MEMORY
 # @DESCRIPTION:
-# How much RAM is needed in MB?
+# @DEAULT_UNSET
+# How much RAM is needed?
 
 # @ECLASS-VARIABLE:  CHECKREQS_DISK_BUILD
 # @DESCRIPTION:
-# How much diskspace is needed to build the package? In MB
+# @DEAULT_UNSET
+# How much diskspace is needed to build the package?
 
 # @ECLASS-VARIABLE: CHECKREQS_DISK_USR
 # @DESCRIPTION:
-# How much space in /usr is needed to install the package? In MB
+# @DEAULT_UNSET
+# How much space in /usr is needed to install the package?
 
 # @ECLASS-VARIABLE: CHECKREQS_DISK_VAR
 # @DESCRIPTION:
-# How much space is needed in /var? In MB
+# @DEAULT_UNSET
+# How much space is needed in /var?
+
+CHECKREQS_EXPORTED_FUNCTIONS="pkg_setup"
+case "${EAPI:-0}" in
+	0|1|2|3) ;;
+	4) CHECKREQS_EXPORTED_FUNCTIONS="${EXPORTED_FUNCTIONS} pkg_pretend" ;;
+	*) die "EAPI=${EAPI} is not supported" ;;
+esac
 
 # @FUNCTION: check_reqs
 # @DESCRIPTION:
-# Checks the requirements given in the specific variables. If not reached,
-# either prints a warning or dies.
+# Obsolete function executing all the checks and priting out results
 check_reqs() {
-	[[ -n "${1}" ]] && die "Usage: check_reqs"
+	debug-print-function ${FUNCNAME} "$@"
+
+	echo
+	ewarn "QA: Package calling old ${FUNCNAME} function."
+	ewarn "QA: Please file a bug against the package."
+	ewarn "QA: It should call check-reqs_pkg_pretend and check-reqs_pkg_setup"
+	ewarn "QA: and possibly use EAPI=4 or later."
+	echo
+
+	check-reqs_pkg_setup "$@"
+}
 
-	export CHECKREQS_NEED_SLEEP="" CHECKREQS_NEED_DIE=""
-	if [[ "$CHECKREQS_ACTION" != "ignore" ]] ; then
-		[[ -n "$CHECKREQS_MEMORY" ]] && check_build_memory
-		[[ -n "$CHECKREQS_DISK_BUILD" ]] && check_build_disk \
-			"${T}" "${CHECKREQS_DISK_BUILD}"
-		[[ -n "$CHECKREQS_DISK_USR" ]] && check_build_disk \
-			"${ROOT}/usr" "${CHECKREQS_DISK_USR}"
-		[[ -n "$CHECKREQS_DISK_VAR" ]] && check_build_disk \
-			"${ROOT}/var" "${CHECKREQS_DISK_VAR}"
+# @FUNCTION: check-reqs_pkg_setup
+# @DESCRIPTION:
+# Exported function running the resources checks in pkg_setup phase.
+# It should be run in both phases to ensure condition changes between
+# pkg_pretend and pkg_setup won't affect the build.
+check-reqs_pkg_setup() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	check-reqs_prepare
+	check-reqs_run
+	check-reqs_output
+}
+
+# @FUNCTION: check-reqs_pkg_pretend
+# @DESCRIPTION:
+# Exported function running the resources checks in pkg_pretend phase.
+check-reqs_pkg_pretend() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	check-reqs_pkg_setup "$@"
+}
+
+# @FUNCTION: check-reqs_prepare
+# @DESCRIPTION:
+# Internal function that checks the variables that should be defined.
+check-reqs_prepare() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	if [[ -z ${CHECKREQS_MEMORY} &&
+			-z ${CHECKREQS_DISK_BUILD} &&
+			-z ${CHECKREQS_DISK_USR} &&
+			-z ${CHECKREQS_DISK_VAR} ]]; then
+		eerror "Set some check-reqs eclass variables if you want to use it."
+		eerror "If you are user and see this message fill a bug against the package."
+		die "${FUNCNAME}: check-reqs eclass called but not actualy used!"
 	fi
+}
 
-	if [[ -n "${CHECKREQS_NEED_SLEEP}" ]] ; then
-		echo
-		ewarn "Bad things may happen! You may abort the build by pressing ctrl+c in"
-		ewarn "the next 15 seconds."
-		ewarn " "
-		einfo "To make this kind of warning a fatal error, add a line to /etc/make.conf"
-		einfo "setting CHECKREQS_ACTION=\"error\". To skip build requirements checking,"
-		einfo "set CHECKREQS_ACTION=\"ignore\"."
-		epause 15
+# @FUNCTION: check-reqs_run
+# @DESCRIPTION:
+# Internal function that runs the check based on variable settings.
+check-reqs_run() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	# some people are *censored*
+	unset CHECKREQS_FAILED
+
+	[[ -n ${CHECKREQS_MEMORY} ]] && \
+		check-reqs_memory \
+			${CHECKREQS_MEMORY}
+
+	[[ -n ${CHECKREQS_DISK_BUILD} ]] && \
+		check-reqs_disk \
+			"${T}" \
+			"${CHECKREQS_DISK_BUILD}"
+
+	[[ -n ${CHECKREQS_DISK_USR} ]] && \
+		check-reqs_disk \
+			"${EROOT}/usr" \
+			"${CHECKREQS_DISK_USR}"
+
+	[[ -n ${CHECKREQS_DISK_VAR} ]] && \
+		check-reqs_disk \
+			"${EROOT}/var" \
+			"${CHECKREQS_DISK_VAR}"
+}
+
+# @FUNCTION: check-reqs_get_mesg
+# @DESCRIPTION:
+# Internal function that returns number in megabites.
+# Converts from 1G=1024 or 1T=1048576
+check-reqs_get_megs() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	[[ -z ${1} ]] && die "Usage: ${FUNCNAME} [size]"
+
+	local unit=${1//[[:digit:]]/}
+	local size=${1//[[:alpha:]]/}
+
+	if [[ ${unit//[[:alpha:]]/} != "" ]]; then
+		die "${FUNCNAME}: Failed to determine units, garbage in variables"
+	else
+		# temporary workaround for empty units
+		unit="M"
+	fi
+
+	case ${unit} in
+		[gG]) echo $((1024 * ${size})) ;;
+		[mM]) echo ${size} ;;
+		[tT]) echo $((1024 * 1024 * ${size})) ;;
+		*)
+			die "${FUNCNAME}: Unknown unit size: ${unit}"
+		;;
+	esac
+}
+
+# @FUNCTION: check-reqs_get_numbers
+# @DESCRIPTION:
+# Internal function that returns number without the unit.
+# Converts from 1G=1 or 150T=150.
+check-reqs_get_numbers() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	[[ -z ${1} ]] && die "Usage: ${FUNCNAME} [size]"
+
+	local size=${1//[[:alpha:]]/}
+
+	# warn about un-united variables
+	if [[ ${size} == ${1//[[:alpha:]]/} ]]; then
+		ewarn "QA: Package does not specify unit for the size check"
+		ewarn "QA: Assuming Megabytes."
+		ewarn "QA: File bug against the package. It should specify it."
 	fi
 
-	if [[ -n "${CHECKREQS_NEED_DIE}" ]] ; then
-		eerror "Bailing out as specified by CHECKREQS_ACTION"
-		die "Build requirements not met"
+	if [[ ${size//[[:digit:]]/} == "" ]]; then
+		echo ${size}
+	else
+		die "${FUNCNAME}: Failed to determine size, garbage in variables."
 	fi
 }
 
-# @FUNCTION: check_reqs_conditional
-# @RETURN: True if requirements check passed, else False
+# @FUNCTION: check-reqs_get_unit
 # @DESCRIPTION:
-# Checks the requirements given in the specific variables
-check_reqs_conditional() {
-	[[ -n "${1}" ]] && die "Usage: check_reqs"
+# Internal function that returns number without the unit.
+# Converts from 1G=1 or 150T=150.
+check-reqs_get_unit() {
+	debug-print-function ${FUNCNAME} "$@"
 
-	export CHECKREQS_NEED_SLEEP="" CHECKREQS_NEED_DIE=""
-	if [[ "$CHECKREQS_ACTION" != "ignore" ]] ; then
-		[[ -n "$CHECKREQS_MEMORY" ]] && check_build_memory
-		[[ -n "$CHECKREQS_DISK_BUILD" ]] && check_build_disk \
-			"${T}" "${CHECKREQS_DISK_BUILD}"
-		[[ -n "$CHECKREQS_DISK_USR" ]] && check_build_disk \
-			"${ROOT}/usr" "${CHECKREQS_DISK_USR}"
-		[[ -n "$CHECKREQS_DISK_VAR" ]] && check_build_disk \
-			"${ROOT}/var" "${CHECKREQS_DISK_VAR}"
+	[[ -z ${1} ]] && die "Usage: ${FUNCNAME} [size]"
+
+	local unit=${1//[[:digit:]]/}
+
+	if [[ ${unit//[[:alpha:]]/} != "" ]]; then
+		die "${FUNCNAME}: Failed to determine units, garbage in variables."
+	else
+		# temporary workaround for empty units
+		unit="M"
 	fi
 
-	[[ -z "${CHECKREQS_NEED_SLEEP}" && -z "${CHECKREQS_NEED_DIE}" ]]
+	case ${unit} in
+		[gG]) echo "Gigabytes" ;;
+		[mM]) echo "Megabytes" ;;
+		[tT]) echo "Terabytes" ;;
+		*)
+			die "${FUNCNAME}: Unknown unit size: ${unit}"
+		;;
+	esac
+}
+
+# @FUNCTION: check-reqs_output
+# @DESCRIPTION:
+# Internal function that prints the warning and dies if required based on
+# the test results.
+check-reqs_output() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	local msg="ewarn"
+
+	[[ ${EBUILD_PHASE} == "pretend" && -z ${I_KNOW_WHAT_I_AM_DOING} ]] && msg="eerror"
+	if [[ -n ${CHECKREQS_FAILED} ]]; then
+		${msg}
+		${msg} "Space constrains set in the ebuild were not met!"
+		${msg} "The build will most probably fail, you should enhance the space"
+		${msg} "as per failed tests."
+		${msg}
+
+		[[ ${EBUILD_PHASE} == "pretend" && -z ${I_KNOW_WHAT_I_AM_DOING} ]] && \
+			die "Build requirements not met!"
+	fi
 }
 
-# internal use only!
-check_build_memory() {
-	[[ -n "${1}" ]] && die "Usage: check_build_memory"
-	check_build_msg_begin "${CHECKREQS_MEMORY}" "MBytes" "RAM"
+# @FUNCTION: check-reqs_memory
+# @DESCRIPTION:
+# Internal function that checks space on the RAM.
+check-reqs_memory() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	[[ -z ${1} ]] && die "Usage: ${FUNCNAME} [size]"
+
+	local size=${1}
+	local actual_memory
+
+	check-reqs_start_phase \
+		$(check-reqs_get_numbers ${size}) \
+		$(check-reqs_get_unit ${size}) \
+		"RAM"
+
 	if [[ -r /proc/meminfo ]] ; then
 		actual_memory=$(sed -n -e '/MemTotal:/s/^[^:]*: *\([0-9]\+\) kB/\1/p' \
 			/proc/meminfo)
@@ -148,60 +288,89 @@
 		[[ "$?" == "0" ]] &&
 			actual_memory=$(echo $actual_memory | sed -e 's/^[^:=]*[:=]//' )
 	fi
-	if [[ -n "${actual_memory}" ]] ; then
-		if [[ ${actual_memory} -lt $((1024 * ${CHECKREQS_MEMORY})) ]] ; then
+	if [[ -n ${actual_memory} ]] ; then
+		if [[ ${actual_memory} -lt $((1024 * $(check-reqs_get_megs ${size}))) ]] ; then
 			eend 1
-			check_build_msg_ick "${CHECKREQS_MEMORY}" "MBytes" "RAM"
+			check-reqs_unsattisfied \
+				$(check-reqs_get_numbers ${size}) \
+				$(check-reqs_get_unit ${size}) \
+				"RAM"
 		else
 			eend 0
 		fi
 	else
 		eend 1
-		ewarn "Couldn't determine amount of memory, skipping ..."
+		ewarn "Couldn't determine amount of memory, skipping..."
 	fi
 }
 
-# internal use only!
-check_build_disk() {
-	[[ -z "${2}" ]] && die "Usage: check_build_disk where name needed"
-	check_build_msg_begin "${2}" "MBytes" \
-			"disk space at ${1}"
-	actual_space=$(df -Pm ${1} 2>/dev/null | sed -n \
-			'$s/\(\S\+\s\+\)\{3\}\([0-9]\+\).*/\2/p' 2>/dev/null )
-	if [[ "$?" == "0" && -n "${actual_space}" ]] ; then
-		if [[ ${actual_space} -lt ${2} ]] ; then
+# @FUNCTION: check-reqs_disk
+# @DESCRIPTION:
+# Internal function that checks space on the harddrive.
+check-reqs_disk() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	[[ -z ${2} ]] && die "Usage: ${FUNCNAME} [path] [size]"
+
+	local path=${1}
+	local size=${2}
+	local space_megs
+
+	check-reqs_start_phase \
+		$(check-reqs_get_numbers ${size}) \
+		$(check-reqs_get_unit ${size}) \
+		"disk space at \"${path}\""
+
+	space_megs=$(df -Pm ${1} 2>/dev/null | sed -n \
+		'$s/\(\S\+\s\+\)\{3\}\([0-9]\+\).*/\2/p' 2>/dev/null)
+
+	if [[ $? == 0 && -n ${space_megs} ]] ; then
+		if [[ ${space_megs} -lt $(check-reqs_get_megs ${size}) ]] ; then
 			eend 1
-			check_build_msg_ick "${2}" "MBytes" \
-					"disk space at ${1}"
+			check-reqs_unsattisfied \
+				$(check-reqs_get_numbers ${size}) \
+				$(check-reqs_get_unit ${size}) \
+				"disk space at \"${path}\""
 		else
 			eend 0
 		fi
 	else
 		eend 1
-		ewarn "Couldn't figure out disk space, skipping ..."
+		ewarn "Couldn't determine disk space, skipping..."
 	fi
 }
 
-# internal use only!
-check_build_msg_begin() {
-	ebegin "Checking for at least ${1}${2} ${3}"
-}
+# @FUNCTION: check-reqs_start_phase
+# @DESCRIPTION:
+# Internal function that inform about started check
+check-reqs_start_phase() {
+	debug-print-function ${FUNCNAME} "$@"
 
-# internal use only!
-check_build_msg_skip() {
-	ewarn "Skipping check for at least ${1}${2} ${3}"
+	[[ -z ${3} ]] && die "Usage: ${FUNCNAME} [size] [unit] [location]"
+
+	ebegin "Checking for at least ${1}${2} ${3}"
 }
 
-# internal use only!
-check_build_msg_ick() {
-	if [[ "${CHECKREQS_ACTION}" == "error" ]] ; then
-		eerror "Don't have at least ${1}${2} ${3}"
-		echo
-		export CHECKREQS_NEED_DIE="yes"
-	else
-		ewarn "Don't have at least ${1}${2} ${3}"
-		echo
-		export CHECKREQS_NEED_SLEEP="yes"
-	fi
+# @FUNCTION: check-reqs_unsattisfied
+# @DESCRIPTION:
+# Internal function that inform about check result.
+# It has different output between pretend and setup phase,
+# where in pretend phase it is fatal.
+check-reqs_unsattisfied() {
+	debug-print-function ${FUNCNAME} "$@"
+
+	[[ -z ${3} ]] && die "Usage: ${FUNCNAME} [size] [unit] [location]"
+
+	local msg="ewarn"
+
+	[[ ${EBUILD_PHASE} == "pretend" && -z ${I_KNOW_WHAT_I_AM_DOING} ]] && msg="eerror"
+	${msg} "Don't have at least ${1}${2} ${3}"
+
+	# @ECLASS-VARIABLE: CHECKREQS_FAILED
+	# @DESCRIPTION:
+	# @DEAULT_UNSET
+	# If set the checks failed and eclass should abort the build.
+	# Internal, do not set yourself.
+	CHECKREQS_FAILED="true"
 }
 

Reply via email to