Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Mar 2013 01:05:05 -0700 (PDT)
From:      Don Lewis <truckman@FreeBSD.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/177365: [patch] ports-mgmt/portupgrade-devel enhancements
Message-ID:  <201303250805.r2P855rs086773@mousie.catspoiler.org>
Resent-Message-ID: <201303250810.r2P8A0Gv070470@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         177365
>Category:       ports
>Synopsis:       [patch] ports-mgmt/portupgrade-devel enhancements
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Mar 25 08:10:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Don Lewis
>Release:        FreeBSD 10.0-CURRENT i386
>Organization:
FreeBSD project
>Environment:
System: FreeBSD scratch.catspoiler.org 10.0-CURRENT FreeBSD 10.0-CURRENT #23 r248434: Sun Mar 17 14:56:39 PDT 2013     dl@scratch.catspoiler.org:/usr/obj/usr/src/sys/GENERICSMB  i386

	portupgrade-devel-20130313,3

>Description:
	One problem with portupgrade is that if port A lists port D as
	an extract, patch, or fetch dependency, and port B lists port D
	as a build or run dependency, and if portupgrade decides to build
	port A before port B, then the following happens:

		portupgrade builds port A, which has the side effect of
		building and installing port D because D is listed as
		a dependency in the Makefile for A.

		portupgrade then installs port A.

		portupgrade then builds port D.

		portupgrade then attempts to install port D, which fails
		because D is already installed.

		portupgrade then skips port B because its dependency D
		failed.

	
	Portupgrade can be cumbersome to use if ports are only updated
	unfrequently.  Sometimes the instructions in ports/UPDATING
	will suggest running "portupgrade -fr someport" to force the
	rebuilding of all ports that depend on someport.  The problem is
	that some of the other ports that these ports depend on will
	still be out of date.  The -a option can't be included on the
	command line to fix that problem because *all* ports are rebuilt
	when both the -a and -f flags are specified, and the -a flag disables
	the -r flag.  The problem gets worse if multiple ports need to have
	all of their dependent ports rebuilt.


>How-To-Repeat:

>Fix:

	The following patch to lib/pkgtools/portinfo.rb causes the
	extract, patch, and fetch dependencies to be added to INDEX.db when
	it is built, and allows portupgrade to see these extra dependencies
	so that the ports are all built in the proper order.

	The following patch to bin/portupgrade does several things:

		Allows the -a and -r options to be used together.

		Does not apply the -f option to all ports if the -a
		option is specified.

		Adds a --force_all (or -ff) option to force all ports to
		be rebuilt if that is desired.

		Computes the upgrade_tasks list in a more efficient
		manner.

	These changes allow "portupgrade -afr port1 port2" to be used
	to rebuild all out of date ports as well port1, port2, and
	all ports that depend on these two ports to be built in the
	proper dependency order without duplicate rebuilds.

	There is also a patch for the man page to document the user
	visible changes.


--- lib/pkgtools/portinfo.rb	2008-01-08 03:32:27.000000000 -0800
+++ /tmp/portinfo.rb	2008-07-29 11:51:20.000000000 -0700
@@ -34,8 +34,10 @@
   include Comparable
 
   FIELDS = [ :pkgname, :origin, :prefix, :comment, :descr_file,
-             :maintainer, :categories, :build_depends, :run_depends, :www ]
-  LIST_FIELDS = [ :categories, :build_depends, :run_depends ]
+             :maintainer, :categories, :build_depends, :run_depends, :www,
+             :extract_depends, :patch_depends, :fetch_depends ]
+  LIST_FIELDS = [ :categories, :build_depends, :run_depends,
+                  :extract_depends, :patch_depends, :fetch_depends ]
   PORTS_DIR_FIELDS = [ :origin, :descr_file ]
   NFIELDS = FIELDS.size
   FIELD_SEPARATOR = '|'
@@ -135,7 +137,7 @@
   end
 
   def all_depends()
-    build_depends | run_depends
+    build_depends | run_depends | extract_depends | patch_depends | fetch_depends
   end
 
   def self.match?(pattern, origin)
--- bin/portupgrade.orig	2012-12-06 08:15:47.000000000 -0800
+++ bin/portupgrade	2013-01-07 19:30:26.000000000 -0800
@@ -192,6 +192,7 @@
   $fetch_only = false
   $fetch_recursive = false
   $force = false
+  $force_all = false
   $keep_going = false
   $ignore_moved = false
   $interactive = false
@@ -244,7 +245,6 @@
     opts.def_option("-a", "--all",
 		    "Do with all the installed packages") { |v|
       $all = v
-      $recursive = false
       $upward_recursive = false
     }
 
@@ -297,7 +297,17 @@
 
     opts.def_option("-f", "--force",
 		    "Force the upgrade of a port even if it is to be a" << NEXTLINE <<
-		    "downgrade or just a reinstall, or the port is held") { |v|
+		    "downgrade or just a reinstall, or the port is held" << NEXTLINE <<
+		    "Specified twice, --force-all is implied") { |v|
+      if $force
+	$force_all = v
+      end
+      $force = v
+    }
+
+    opts.def_option("--force_all",
+                    "Or -ff; Force upgrade or reinstall of all ports") { |v|
+      $force_all = v
       $force = v
     }
 
@@ -417,7 +427,7 @@
     opts.def_option("-r", "--recursive",
 		    "Do with all those depending on the given packages" << NEXTLINE <<
 		    "as well") {
-      $recursive = true unless $all
+      $recursive = true
     }
 
     opts.def_option("-R", "--upward-recursive",
@@ -601,7 +611,7 @@
 	      $pkgdb.glob(pattern, false).each do |pkgname|
 		first ||= pkgname
 
-		list |= $pkgdb.recurse(pkgname, $recursive, false, $sanity_check)
+		list |= $pkgdb.recurse(pkgname, $recursive && !(arg.equal? all), false, $sanity_check)
 	      end
 	    rescue => e
               raise e if e.class == PkgDB::NeedsPkgNGSupport
@@ -616,14 +626,14 @@
 	      end
 	    end
 
-	    upgrade_tasks |= list
+	    list -= upgrade_tasks
 
 	    found = true
 
 	    # Check packages for updates and gather dependecies
 	    depends = []
 	    not_need_upgrade = []
-	    upgrade_tasks.each do |task|
+	    list.each do |task|
 	      pkg = PkgInfo.new(task)
 	      if task == first && $origin
 		origin = $origin
@@ -675,7 +685,7 @@
 		end
 		name =~ /^(.+)-([^-]+)$/
 		newversion = PkgVersion.new($2)
-		if newversion <= pkg.version && !$force
+		if newversion <= pkg.version && !($force_all || ($force && !(arg.equal? all)))
 		  not_need_upgrade << task
 		  next
 		end
@@ -683,7 +693,8 @@
 		#install_tasks |= get_notinstalled_depends(origin)
 	      end
 	    end
-	    upgrade_tasks -= not_need_upgrade
+	    list -= not_need_upgrade
+	    upgrade_tasks |= list
 
 	    # Check dependencies for updates
 	    depends -= ['']
--- man/portupgrade.1.orig	2012-12-06 08:15:47.000000000 -0800
+++ man/portupgrade.1	2013-01-07 19:33:36.000000000 -0800
@@ -1,5 +1,5 @@
 .\"
-.Dd October 14, 2012
+.Dd January 7, 2013
 .Dt PORTUPGRADE 1
 .Os FreeBSD
 .Sh NAME
@@ -188,6 +188,21 @@
 a reinstall of the same version, or the port is held by user using the
 HOLD_PKGS variable in
 .Pa pkgtools.conf .
+This option is ignored when combined with 
+.Fl a
+or 
+.Ar '*'
+as
+.Ar pkgname_glob .
+.Pp
+.It Fl ff
+.It Fl -force-all
+Force the upgrade or reinstallation of all packages when combined with
+.Fl a
+or
+.Ar '*'
+as
+.Ar pkgname_glob .
 .Pp
 .It Fl F
 .It Fl -fetch-only
@@ -335,6 +350,12 @@
 .It Fl r
 .It Fl -recursive
 Act on all those packages depending on the given packages as well.
+This option is ignored when combined with 
+.Fl a
+or 
+.Ar '*'
+as
+.Ar pkgname_glob .
 .Pp
 .It Fl R
 .It Fl -upward-recursive
@@ -648,6 +669,37 @@
 is the option to specify an exclusion pattern.
 .Pp
 .It
+Rebuild and reinstall all ports that depend on
+.Ar sdl ,
+and upgrade all other ports in the proper order:
+.Pp
+.Dl portupgrade -arf sdl
+.Pp
+The
+.Fl f
+/
+.Fl -force
+and
+.Fl r
+/
+.Fl -recursive
+options only apply to the explicitly specified port(s) and not to
+all of the ports implied by
+.Fl a
+/
+.Fl all .
+.Pp
+.It
+Rebuild and reinstall all ports:
+.Pp
+.Dl portupgrade -aff
+.Pp
+.Fl ff
+/
+.Fl -force-all
+option applies to all ports.
+.Pp
+.It
 Rebuild and reinstall all that ports that were installed prior to the date
 2001-09-20:
 .Pp
>Release-Note:
>Audit-Trail:
>Unformatted:



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