Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 Nov 2009 20:17:15 +0000 (UTC)
From:      Doug Barton <dougb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r199056 - user/dougb/portmaster
Message-ID:  <200911082017.nA8KHFHv096646@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dougb
Date: Sun Nov  8 20:17:15 2009
New Revision: 199056
URL: http://svn.freebsd.org/changeset/base/199056

Log:
  First run at package support! This version is functional and fairly well
  tested but I'm sure there are bugs and things that don't work as expected
  
  Supports the following new options:
  -P|--packages and -PP|--packages-only ala portupgrade
  --packages-if-newer
  	This feature will allow package installation if the available
  	package is newer than the installed version, even if it's not
  	the latest version according to your ports tree. [1]
  
  Still to come:
  Support for packages on filesystem, instead of http
  
  [1] Special funding committment for this feature and package support
  generally by:	Modirum MDpay
  
  Sponsored by:	http://dougbarton.us/portmaster-proposal.html
  Funded by:	Christer Solskogen
  Funded by:	Douglas Berry
  Funded by:	Beat Gatzi

Modified:
  user/dougb/portmaster/portmaster

Modified: user/dougb/portmaster/portmaster
==============================================================================
--- user/dougb/portmaster/portmaster	Sun Nov  8 20:03:52 2009	(r199055)
+++ user/dougb/portmaster/portmaster	Sun Nov  8 20:17:15 2009	(r199056)
@@ -224,6 +224,7 @@ usage () {
 	echo ''
 	echo 'Usage:'
 	echo "Common flags: [--force-config] [-CGHKgntvw B|b f|i D|d]"
+	echo "    [--packages|--packages-only] [-P|-PP] [--packages-if-newer]"
 	echo "    [-m <arguments for make>]"
 	echo "    [-x <glob pattern to exclude from building>]"
 	echo "${0##*/} [Common flags] <full name of port directory in $pdb>"
@@ -289,6 +290,12 @@ usage () {
 	echo '-R used with -[rf] to skip ports updated on a previous run'
 	echo '-a check all ports, update as necessary'
 	echo ''
+	echo 'NOTE: The package options imply -G'
+	echo '-P|--packages use packages, but build port if not available'
+	echo '-PP|--packages-only fail if no package is available'
+	echo '--packages-if-newer use package if newer than installed even'
+	echo '   if the package is not the latest according to the ports tree'
+	echo ''
 	echo '-l list installed ports by category'
 	echo '-L list installed ports by category, and search for updates'
 	echo ''
@@ -366,10 +373,24 @@ if [ "$$" -eq "$PM_PARENT_PID" ]; then
 	export pd pdb distdir
 fi
 
-echo '' ; echo "Debug> #: $# @: $@"
+pmuex () {
+fail "The -P/--packages and -PP/--packages-only options are mutually exclusive"
+}
 
+# XXX
 for var in "$@" ; do
 	case "$var" in
+	-P|--packages)		[ "$PM_PACKAGES" = only ] && pmuex
+				NO_RECURSIVE_CONFIG=Gopt; ARGS="-G $ARGS"
+				PM_PACKAGES=first ; export PM_PACKAGES ;;
+	-PP|--packages-only)	[ "$PM_PACKAGES" = first ] && pmuex
+				NO_RECURSIVE_CONFIG=Gopt; ARGS="-G $ARGS"
+				PM_PACKAGES=only  ; export PM_PACKAGES ;;
+	--packages-if-newer)	[ -z "$PM_PACKAGES" ] && {
+				PM_PACKAGES=newer ; export PM_PACKAGES;
+				NO_RECURSIVE_CONFIG=Gopt; ARGS="-G $ARGS"; }
+				PM_PACKAGES_NEWER=pm_packages_newer
+				export PM_PACKAGES_NEWER ;;
 	-[A-Za-z0-9]*)          newopts="$newopts $var" ;;
 	--help)			usage 0 ;;
 	--version)		version ; exit 0 ;;
@@ -389,8 +410,6 @@ done
 set -- $newopts
 unset var newopts
 
-echo '' ; echo "Debug> #: $# @: $@"
-
 #=============== Begin functions relevant to --features and main ===============
 
 iport_from_origin () {
@@ -1693,7 +1712,6 @@ dependency_check () {
 		echo "===>>> Dependency check complete for $portdir"
 		case "$PM_DEPTH" in *\>\>*) echo "	$PM_DEPTH" ;; esac
 	fi
-	echo ''
 }
 
 create_master_rb_list () {
@@ -1837,7 +1855,8 @@ if [ "$$" -eq "$PM_PARENT_PID" -a -z "$S
 	[ -z "$NO_BACKUP" -a -z "$BACKUP" ] && export NB_DELETE
 
 	# Set the file name here so it's visible to the children
-	if [ -z "$DONT_SCRUB_DISTFILES" -a -z "$FETCH_ONLY" ]; then
+	if [ -z "$DONT_SCRUB_DISTFILES" -a -z "$FETCH_ONLY" \
+	    -a -z "$PM_PACKAGES" ]; then
 		export DI_FILES=`pm_mktemp DI-FILES`
 	fi
 
@@ -2089,7 +2108,7 @@ check_state || {
 	safe_exit 1; }
 
 # Do not start this in the background until we are sure we are going to build
-if [ "$$" -eq "$PM_PARENT_PID" -a -z "$SHOW_WORK" \
+if [ "$$" -eq "$PM_PARENT_PID" -a -z "$SHOW_WORK" -a -z "$PM_PACKAGES" \
 	-a -z "$DONT_SCRUB_DISTFILES" -a -z "$FETCH_ONLY" ]; then
 	echo ''; (read_distinfos)&
 fi
@@ -2110,7 +2129,9 @@ dofetch () {
 }
 
 	# Handle the problem of manual fetching
-	master_sites=`pm_make_b -V MASTER_SITES`
+# XXX Not for -P/-PP
+	[ -z "$PM_PACKAGES" ] &&  master_sites=`pm_make_b -V MASTER_SITES`
+
 	if [ -n "$master_sites" ]; then
 		# PATCHFILES may get added post-config, but we want to
 		# do as much of this as we can, as early as we can, and
@@ -2134,7 +2155,7 @@ dofetch () {
 	fi
 	unset master_sites
 
-	if [ -z "$FETCH_ONLY" ]; then
+	if [ -z "$FETCH_ONLY" -a ! "$PM_PACKAGES" = only ]; then
 		TESTINT=`grep -l ^IS_INTERACTIVE Makefile`
 	else
 		[ -n "$ALL_FETCH" ] && safe_exit
@@ -2217,8 +2238,10 @@ cd $pd/$portdir
 
 if [ -z "$NO_DEP_UPDATES" ]; then
 	if [ -z "$RECURSE_THOROUGH" ]; then
-		echo "===>>> Starting check for build dependencies"
-		dependency_check build-depends-list
+		if [ ! "$PM_PACKAGES" = only ]; then
+			echo "===>>> Starting check for build dependencies"
+			dependency_check build-depends-list
+		fi
 	else
 		echo "===>>> Starting check for all dependencies"
 		dependency_check all-depends-list
@@ -2234,32 +2257,174 @@ if [ -n "$NO_ACTION" -a -z "$CONFIG_ONLY
 	safe_exit
 fi
 
-[ -z "$DONT_PRE_CLEAN" ] && {
-	pm_make clean NOCLEANDEPENDS=ncd || fail 'make clean failed'; echo ''; }
+new_port=`pm_make -V PKGNAME`
 
-sleep=3
-fl_read=`echo ${TMPDIR}/f-${PM_PARENT_PID}-fetchlog-${portdir#*/}.*`
-while [ -f "$fl_read" ]; do
-	echo "===>>> Waiting on fetch & checksum for $portdir <<<==="
-	tail -10 $fl_read 2>/dev/null
-	echo '' ; echo ''
-	sleep $sleep
+# XXX Build or package?
+
+if [ -n "$PM_PACKAGES" ]; then
+	if [ -z "$PACKAGESITE" ]; then
+		release=`uname -r`
+		#release=7.0-RELEASE-p12
+		#release=8.0-RC1
+		#release=8.0-STABLE
+
+		case "$release" in
+		[678]\.[0-9]-STABLE)
+				release=packages-${release%%\.*}-stable ;;
+		[678]\.[0-9]-RELEASE*)
+				release=packages-${release%-RELEASE*}-release ;;
+		9\.0-CURRENT)	release=packages-8-current ;;	# XXX
+		*RC[0-9]*)	release=${release%-RC[0-9]}
+				release=packages-${release}-release ;;
+		*BETA[0-9]*)	release=${release%-BETA[0-9]}
+				release=packages-${release}-release ;;
+		esac
 
-	if [ $sleep -eq 10 ]; then
-		sleep=3
+		sitepath="${PACKAGEROOT:-"http://ftp.freebsd.org"}/pub/FreeBSD/ports/`uname -p`/${release}/"
+		unset release
 	else
-		sleep=$(( $sleep + 1 ))
+		sitepath="$PACKAGESITE"
+	fi
+
+	sitepath="${sitepath%/}/${portdir%/*}/"
+
+#echo "Debug> sitepath: $sitepath"
+
+	[ -n "$PM_VERBOSE" ] && echo "===>>> Checking package repository"
+	latest_link=`pm_make -V LATEST_LINK`
+	latest_pv=`fetch -q -o - ${sitepath} 2>/dev/null | grep ">$latest_link"`
+	unset latest_link
+
+	if [ -z "$latest_pv" ]; then
+		echo "===>>> Package and/or archive not found at:"
+		echo "${sitepath}"
+		echo ''
+		echo "       Check the pkg_add(1) man page for information"
+		echo "       on setting the PACKAGESITE environment variable"
+		fail 'No package archive found'
+	fi
+	latest_pv=${latest_pv#*tbz\">}
+	latest_pv=${latest_pv%%\.tbz*}
+
+#echo "Debug> new_port: $new_port latest_pv: $latest_pv"
+
+notnewer () {
+	echo ''
+	echo "===>>> The newest available package ($latest_pv)"
+	echo "       is not newer than the installed version ($upg_port)"
+}
+
+	if [ "$latest_pv" = "$new_port" ]; then
+		use_package=up_equal
+		[ -n "$PM_VERBOSE" ] &&
+	echo "===>>> Available package ($latest_pv) matches the ports tree"
+	elif [ -n "$PM_PACKAGES_NEWER" ]; then
+		if [ -n "$upg_port" ]; then
+			case `pkg_version -t $upg_port $latest_pv` in
+			\<)	use_package=up_newer
+				[ -n "$PM_VERBOSE" ] && {
+			echo "===>>> Available package ($latest_pv)";
+			echo "       is newer than installed ($upg_port)"; } ;;
+			=)	if [ -n "$PM_FORCE" ]; then
+					use_package=up_force
+				else
+					notnewer
+				fi ;;
+			*)	notnewer ;;
+			esac
+		else
+			use_package=up_no_installed
+			[ -n "$PM_VERBOSE" ] &&
+			echo "===>>> There is a package available ($latest_pv)"
+		fi
+	else
+		# Could happen if ports tree is out of date
+		case `pkg_version -t $new_port $latest_pv` in
+		\<)	use_package=up_old_tree
+			[ -n "$PM_VERBOSE" ] && {
+			echo "===>>> Available package ($latest_pv)";
+			echo "       is newer than ports tree ($new_port)"; } ;;
+		=)	;;	# Should not be reached
+		*)	echo ''
+			echo "===>>> The newest available package ($latest_pv)"
+		echo "       is older than the version in ports ($new_port)"
+			if [ "$PM_PACKAGES" = only ]; then
+				if [ -n "$PM_FORCE" ]; then 
+					use_package=up_force2
+				echo "===>>> Installing anyway due to -f"
+				else
+	fail "Try --packages-if-newer, or do not use -PP/--packages-only"
+				fi
+			fi ;;
+		esac
 	fi
-done
-unset sleep
 
-if [ -n "$HIDE_BUILD" ]; then
-	port_log=`mktemp -t port_log-${PM_PARENT_PID}-${portdir#*/}`
-	port_log_args=">> $port_log 2>&1"
-	echo "===>>> Logging build to $port_log"
+	if [ -n "$use_package" ]; then
+		new_port=$latest_pv
+	else
+		if [ "$PM_PACKAGES" = only ]; then
+			fail "There is no valid package to install"
+		else
+			echo ''
+echo "===>>> There is no valid package to install, building port instead"
+			echo ''
+		fi
+	fi
 fi
 
-eval pm_make $port_log_args || fail "make failed for $portdir"
+if [ -z "$use_package" ]; then
+	[ -z "$DONT_PRE_CLEAN" ] && { pm_make clean NOCLEANDEPENDS=ncd ||
+		fail 'make clean failed'; echo ''; }
+
+	sleep=3
+	fl_read=`echo ${TMPDIR}/f-${PM_PARENT_PID}-fetchlog-${portdir#*/}.*`
+	while [ -f "$fl_read" ]; do
+		echo "===>>> Waiting on fetch & checksum for $portdir <<<==="
+		tail -10 $fl_read 2>/dev/null
+		echo '' ; echo ''
+		sleep $sleep
+
+		if [ $sleep -eq 10 ]; then
+			sleep=3
+		else
+			sleep=$(( $sleep + 1 ))
+		fi
+	done
+	unset sleep
+
+	if [ -n "$HIDE_BUILD" ]; then
+		port_log=`mktemp -t port_log-${PM_PARENT_PID}-${portdir#*/}`
+		port_log_args=">> $port_log 2>&1"
+		echo "===>>> Logging build to $port_log"
+	fi
+
+	eval pm_make $port_log_args || fail "make failed for $portdir"
+else
+	# XXX fetch
+
+	# Duplicated from pkg_init()
+	packages=`pm_make -f/usr/share/mk/bsd.port.mk -V PACKAGES`
+	[ -n "$packages" ] || fail 'The value of PACKAGES cannot be empty'
+
+	ppd=$packages/portmaster-download
+
+	if [ ! -d "$ppd" ]; then
+		[ -n "$PM_SU_VERBOSE" ] &&
+			echo "===>>> Creating $ppd"
+		pm_mkdir_s $ppd
+	fi
+	export ppd
+
+	[ -n "$PM_VERBOSE" ] && echo "===>>> Starting package fetch"
+
+	fetch_args=`pm_make -f/usr/share/mk/bsd.port.mk -V FETCH_ARGS`
+	fetch $fetch_args -o $ppd ${sitepath}${latest_pv}.tbz 2>/dev/null || {
+		pm_unlink ${ppd}/${latest_pv}.tbz;
+		fetch $fetch_args -o $ppd ${sitepath}${latest_pv}.tbz ||
+			fail "Fetch for ${latest_pv}.tbz failed"; }
+fi
+
+# XXX Build or package?
 
 # Ignore if no old port exists
 if [ -n "$upg_port" ]; then
@@ -2319,25 +2484,37 @@ if [ -z "$RECURSE_THOROUGH" -a -z "$NO_D
 	cd $pd/$portdir
 fi
 
-new_port=`pm_make -V PKGNAME`
-
-if [ -n "$PM_SU_UNSET_PORT_LOG_ARGS" ]; then
-	unset port_log_args
-else
-	[ -n "$HIDE_BUILD" ] && echo "===>>> Logging install to $port_log"
-fi
-
-# Defining NO_DEPENDS ensures that we will control the installation of the
-# depends, not bsd.port.mk.
-[ -n "$PM_SU_VERBOSE" ] && echo "===>>> Running make install"
-
-eval pm_make_s -DNO_DEPENDS install $port_log_args || {
+install_failed () {
 	if [ -z "$NO_BACKUP" -a -n "$upg_port" ]; then
 		echo ''
 		echo "===>>> A backup package for $upg_port should"
 		echo "       be located in $pbu"
 	fi
-	fail "Installation of $new_port ($portdir) failed"; }
+	fail "Installation of $1 ($portdir) failed"
+}
+
+echo ''
+if [ -z "$use_package" ]; then
+	[ -n "$PM_SU_VERBOSE" ] && echo "===>>> Running make install"
+
+	if [ -n "$PM_SU_UNSET_PORT_LOG_ARGS" ]; then
+		unset port_log_args
+	else
+		[ -n "$HIDE_BUILD" ] &&
+			echo "===>>> Logging install to $port_log"
+	fi
+
+	# Defining NO_DEPENDS ensures that we will control the installation
+	# of the depends, not bsd.port.mk.
+	eval pm_make_s -DNO_DEPENDS install $port_log_args ||
+		install_failed $new_port
+else
+	# XXX Install the package
+	echo "===>>> Installing package"
+	pkg_add --no-deps --force ${ppd}/${latest_pv}.tbz ||
+		install_failed ${latest_pv}.tbz
+fi
+echo ''
 
 # Remove saved libs that match newly installed files
 
@@ -2367,7 +2544,7 @@ fi
 unset temp
 
 # This will serve for *delete*distfiles() as well
-distfiles=`pm_make -V ALLFILES | sed -e 's# *$##g'`
+[ -z "$use_package" ] && distfiles=`pm_make -V ALLFILES | sed -e 's# *$##g'`
 if [ -n "$distfiles" ]; then
 	distfiles=" ${distfiles} "
 
@@ -2417,7 +2594,8 @@ if [ -n "$MAKE_PACKAGE" ]; then
 	echo "	===>>> Package saved to $packages/All" ; echo ''
 fi
 
-[ -z "$DONT_POST_CLEAN" ] && { pm_make clean NOCLEANDEPENDS=ncd2 ; echo ''; }
+[ -z "$DONT_POST_CLEAN" -a -z "$use_package" ] && {
+	pm_make clean NOCLEANDEPENDS=ncd2 ; echo ''; }
 
 check_dependency_files $portdir $new_port
 if [ -s "$grep_deps" ]; then



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911082017.nA8KHFHv096646>