[25263] branches/release_1_4/base

source_changes at macosforge.org source_changes at macosforge.org
Wed May 16 18:10:16 PDT 2007


Revision: 25263
          http://trac.macosforge.org/projects/macports/changeset/25263
Author:   jberry at macports.org
Date:     2007-05-16 18:10:15 -0700 (Wed, 16 May 2007)

Log Message:
-----------
merge from trunk to release_1_4 branch in preparation for release 1.4.41

Modified Paths:
--------------
    branches/release_1_4/base/ChangeLog
    branches/release_1_4/base/doc/portfile.7
    branches/release_1_4/base/doc/sources.conf
    branches/release_1_4/base/portmgr/IndexRegen.sh
    branches/release_1_4/base/portmgr/autosubmit.tcl
    branches/release_1_4/base/src/darwinports1.0/darwinports.tcl
    branches/release_1_4/base/src/pextlib1.0/Pextlib.c
    branches/release_1_4/base/src/pextlib1.0/fs-traverse.c
    branches/release_1_4/base/src/pextlib1.0/tests/fs-traverse.tcl
    branches/release_1_4/base/src/pextlib1.0/uid.c
    branches/release_1_4/base/src/pextlib1.0/uid.h
    branches/release_1_4/base/src/port/port.1
    branches/release_1_4/base/src/port/port.tcl
    branches/release_1_4/base/src/port/portindex.tcl
    branches/release_1_4/base/src/port1.0/portdepends.tcl
    branches/release_1_4/base/src/port1.0/portsubmit.tcl
    branches/release_1_4/base/src/port1.0/portutil.tcl
    branches/release_1_4/base/src/port1.0/resources/fetch/mirror_sites.tcl
    branches/release_1_4/base/src/port1.0/resources/group/ruby-1.0.tcl
    branches/release_1_4/base/src/port1.0/tests/portutil.tcl
    branches/release_1_4/base/tests/test/trace/Makefile
    branches/release_1_4/base/tests/test/trace/Portfile

Modified: branches/release_1_4/base/ChangeLog
===================================================================
--- branches/release_1_4/base/ChangeLog	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/ChangeLog	2007-05-17 01:10:15 UTC (rev 25263)
@@ -4,10 +4,74 @@
 #   This is a log of major user-visible changes in each release
 #
 
-(unreleased):
+Release 1.4.41 (16-May-2007):
 
-Release 1.4.40 (7-May-2007):
+    - `port info` now supports new --index flag for using old behaviour (eridius r25256).
 
+    - `port info` now opens the Portfile and displays up-to-date information.
+      This allows information about variants to be displayed (eg. dependencies).
+      Also allow `port info` to default to current directory if no name is provided
+      (eridius r25255).
+    
+    - Add -E flag to reinplace, does the same thing as in sed (eridius r25251).
+
+    - Add support for [nosync] flag in sources.conf to prevent a source from syncing
+      during a `port sync` or `port selfupdate` (eridius r25236).
+      Example: file:///Users/landonf/misc/MacPorts/dports [nosync]
+
+    - Updating a file: source via svn update during port sync now uses the uid/gid
+      of the owner of the working copy (eridius r25142).
+
+    - Make port(1) convert description and long_description from lists to
+      strings before printing to stdout; this enables the proper printing of
+      semi-colons, brackets and other characters by way of Tcl escape sequences.
+      The exceptions to this are the sequences for newline and carriage return
+      (these break the flatfile PortIndex format by introducing line breaks).
+      (boeyms r25110)
+
+    - Evaluate variants at dportopen instead of dportexec. This ensures that
+      the portfile represents the proper information if queried before targets
+      are executed. It also prevents variants from being executed twice if multiple
+      targets are executed separately on the portfile (ticket #11296, eridius r25033).
+
+    - Fix copy and move commands (eridius r25024).
+
+    - Passing multiple arguments to $option-delete now works as expected
+      (ticket #11929, eridius r25006).
+
+    - fs-traverse no longer follows symlinks specified on the root. This fixes
+      the incorrect behaviour of delete seen in #11862 (eridius r25003).
+
+    - Remove bundled xar. (jberry r24913).
+
+    - Tighten checking of port name in depspecs. neither + nor / is allowed.
+      (jberry r24929, r24934, r24940).
+      
+    - Restore ability for portindex lines to contain carriage returns, allowing
+      fields such as descriptions to contain line breaks. Note that any portindex
+      containing such entries will not be readable by a recent version of macports.
+      (jberry r25146)
+      
+    - Add support for descriptions on variants:
+         * The syntax follows the syntax for variant depends, etc.
+         * Descriptions for variants are entirely optional
+         * The change to the portindex format to allow variant descriptions
+           should be backwards compatible. Variant descriptions are stored,
+           keyed by the variant name, in a new portinfo array named "variant_desc".
+   
+        Example:
+
+            variant myvariant description "This variant does this and that" {
+                configure.args-append   --do-this --do-that
+            }
+            
+        (jberry r25147)
+        
+    - Only look for, or create, ~/.macports user directory if the HOME environment
+      variable is defined. (jberry r25177)
+
+Release 1.4.40 (7-May-2007, tagged at r24909 by jberry):
+
     - Note the bump in version naming. To leave ourselves lots of room in our versioning
       scheme, we've jumped from 1.4.3 to 1.4.40. The floating point represenation as
       reported by port version (1.440) will still be the same; we're just interpreting

Modified: branches/release_1_4/base/doc/portfile.7
===================================================================
--- branches/release_1_4/base/doc/portfile.7	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/doc/portfile.7	2007-05-17 01:10:15 UTC (rev 25263)
@@ -96,7 +96,11 @@
 .Sy Example:
 .Dl epoch 20041231
 .It Ic description
-One line description of the software and what it does.
+One line description of the software and what it does.  To appear in the
+description, brackets and semi-colons need to be escaped with a backslash (i.e.
+they must be written as "\\[", "\\]" and "\\;").  The escape sequences listed in
+.Xr re_syntax n
+may also be used, with the exception of \\n, \\r and \\f.
 .br
 .Sy Type:
 .Em required
@@ -104,7 +108,11 @@
 .Sy Example:
 .Dl description Dictionary Server Protocol (RFC2229) client
 .It Ic long_description
-A verbose description of the software and what it does.
+A verbose description of the software and what it does.  To appear in the
+description, brackets and semi-colons need to be escaped with a backslash (i.e.
+they must be written as "\\[", "\\]" and "\\;").  The escape sequences listed in
+.Xr re_syntax n
+may also be used, with the exception of \\n, \\r and \\f.
 .br
 .Sy Type:
 .Em required
@@ -676,7 +684,7 @@
 .Em none
 .br
 .Sy Example:
-.Dl cvs.root :pserver:anonymous cvs.sv.gnu.org:/sources/emacs
+.Dl cvs.root :pserver:anonymous at cvs.sv.gnu.org:/sources/emacs
 .It Ic cvs.tag
 Specify a CVS tag identifying the code to checkout.
 .br
@@ -1583,8 +1591,17 @@
 .Dl adduser foo gid=[existsgroup foo]
 .It Ic nextgid
 Returns the highest used gid plus one.
-.It Ic reinplace Ar regex Ar filename
-Provide in-place sed like editing of a file.
+.It Xo
+.Ic reinplace
+.Op Fl E
+.Ar regex
+.Ar
+.Xc
+Provide in-place
+.Xr sed 1
+like editing of a file.
+The -E flag does the same thing as in
+.Xr sed 1
 .br
 .Sy Example:
 .Dl reinplace \*qs|/usr/local|${prefix}|g\*q doc/manpage.1
@@ -1599,10 +1616,12 @@
 Built-in shorthand alternative to "file copy".
 .It Ic move
 Built-in shorthand alternative to "file rename".
-.It Ic delete
-Built-in shorthand alternative to "file delete". Required over the latter for Portfiles that perform deleting
-operations on directories while building the port on Mac OS X 10.3 and earlier, due to a Tcl anomaly on those systems
-that causes "file delete" to fail.
+.It Ic delete Ar
+Deletes each of the given files/directories. Behaves similarly to
+.Ic file delete -force
+except that
+.Ic file delete -force
+will fail to delete directories properly on 10.3 systems.
 .It Ic touch
 Built-in command mimicking the BSD touch command.
 .It Ic ln

Modified: branches/release_1_4/base/doc/sources.conf
===================================================================
--- branches/release_1_4/base/doc/sources.conf	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/doc/sources.conf	2007-05-17 01:10:15 UTC (rev 25263)
@@ -2,6 +2,10 @@
 # following line to point at your local dports directory
 # Example: file:///Users/landonf/misc/MacPorts/dports
 #
+# To prevent a source from synchronizing when `port sync` is used,
+# append [nosync] to the end of the line
+# Example: file:///Users/landonf/misc/MacPorts/dports [nosync]
+#
 # To get MacPorts from the www.macports.org rsync server use:
 # rsync://rsync.darwinports.org/dpupdate/dports
 rsync://rsync.darwinports.org/dpupdate/dports

Modified: branches/release_1_4/base/portmgr/IndexRegen.sh
===================================================================
--- branches/release_1_4/base/portmgr/IndexRegen.sh	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/portmgr/IndexRegen.sh	2007-05-17 01:10:15 UTC (rev 25263)
@@ -21,9 +21,10 @@
 SPAM_LOVERS=macports-mgr at lists.macosforge.org,dluke at geeklair.net
 
 # Other settings (probably don't need to be changed).
-SVN_DPORTS_URL=http://svn.macports.org/repository/macports/trunk/dports
-SVN_BASE_URL=http://svn.macports.org/repository/macports/branches/release_1_4/base
 SVN_CONFIG_DIR=${ROOT}/svnconfig
+REPO_BASE=http://svn.macports.org/repository/macports
+RELEASE_URL_FILE="config/RELEASE_URL"
+SVN="/opt/local/bin/svn -q --non-interactive --config-dir $SVN_CONFIG_DIR"
 # Where to checkout the source code. This needs to exist!
 SRCTREE=${ROOT}/source
 # Where MP will install its world. This gets created.
@@ -60,24 +61,40 @@
     exit 1
 fi
 
-# Update both the ports tree and base sources, bail out if they don't exist beforehand.
-if [ ! -d ${SRCTREE}/dports/.svn ]; then
-    echo "No dports tree found at ${SRCTREE}. This needs to exist (with proper svn \
-        credentials at ${SVN_CONFIG_DIR}) prior to runnig this script." > $FAILURE_LOG; bail
+# Checkout/update the dports tree
+if [ -d ${SRCTREE}/dports ]; then
+    $SVN update ${SRCTREE}/dports > $FAILURE_LOG 2>&1 \
+        || { echo "Updating the dports tree from $REPO_BASE/trunk/dports failed." >> $FAILURE_LOG; bail ; }
 else
-    cd ${SRCTREE}/dports && \
-	svn -q --non-interactive --config-dir $SVN_CONFIG_DIR update > $FAILURE_LOG 2>&1 \
-	|| { echo "Updating the ports tree from $SVN_DPORTS_URL failed." >> $FAILURE_LOG ; bail ; }
+    $SVN checkout ${REPO_BASE}/trunk/dports ${SRCTREE}/dports > $FAILURE_LOG 2>&1 \
+        || { echo "Checking out the dports tree from $REPO_BASE/trunk/dports failed." >> $FAILURE_LOG; bail ; }
 fi
-if [ ! -d ${SRCTREE}/base/.svn ]; then
-    echo "No base sources found at ${SRCTREE}. This needs to exist (with proper svn \
-        credentials at ${SVN_CONFIG_DIR}) prior to running this script." > $FAILURE_LOG; bail
+
+# Checkout/update HEAD
+TMPDIR=mp_trunk/base
+if [ -d ${ROOT}/${TMPDIR} ]; then
+    $SVN update ${ROOT}/${TMPDIR} > $FAILURE_LOG 2>&1 \
+        || { echo "Updating the trunk from $REPO_BASE/trunk/base failed." >> $FAILURE_LOG; bail ; }
 else
-    cd ${SRCTREE}/base && \
-	svn -q --non-interactive --config-dir $SVN_CONFIG_DIR update > $FAILURE_LOG 2>&1 \
-       || { echo "Updating the base sources from $SVN_BASE_URL failed." >> $FAILURE_LOG ; bail ; }
+    $SVN checkout ${REPO_BASE}/trunk/base ${ROOT}/${TMPDIR} > $FAILURE_LOG 2>&1 \
+        || { echo "Checking out the trunk from $REPO_BASE/trunk/base failed." >> $FAILURE_LOG; bail ; }
 fi
+echo `date -u +%s` > ${ROOT}/DPORTS-TIMESTAMP
 
+# Extract the release URL from HEAD
+read RELEASE_URL < ${ROOT}/${TMPDIR}/${RELEASE_URL_FILE}
+[ -n ${RELEASE_URL} ] || { echo "no RELEASE_URL specified in svn HEAD." >> $FAILURE_LOG; bail ; }
+
+# Checkout/update the release base
+if [ -d ${SRCTREE}/base ]; then
+    $SVN switch ${RELEASE_URL}/base ${SRCTREE}/base > $FAILURE_LOG 2>&1 \
+        || { echo "Updating base from ${RELEASE_URL}/base failed." >> $FAILURE_LOG; bail ; }
+else
+    $SVN checkout $RELEASE_URL/base ${SRCTREE}/base > $FAILURE_LOG 2>&1 \
+        || { echo "Checking out base from ${RELEASE_URL}/base failed." >> $FAILURE_LOG ; bail ; }
+fi
+echo `date -u +%s` > ${ROOT}/BASE-TIMESTAMP
+
 # (re)configure.
 cd ${SRCTREE}/base/ && \
     mkdir -p ${TCLPKG} && \

Modified: branches/release_1_4/base/portmgr/autosubmit.tcl
===================================================================
--- branches/release_1_4/base/portmgr/autosubmit.tcl	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/portmgr/autosubmit.tcl	2007-05-17 01:10:15 UTC (rev 25263)
@@ -132,9 +132,6 @@
 set SUBMITTER_EMAIL "autosubmit at macports.org"
 array set submit_options "submitter_name $SUBMITTER_NAME submitter_email $SUBMITTER_EMAIL"
 
-global darwinports::autoconf::macports_user_dir
-set db_file [file normalize "${darwinports::autoconf::macports_user_dir}/autosubmit.db"]
-
 # Do argument processing
 set verbose 0
 if { [lsearch $argv -v] >= 0 } {
@@ -145,7 +142,8 @@
 dportinit
 
 # Submit ports
-puts "Using database at $db_file"
+set db_file [file normalize "${darwinports::macports_user_dir}/autosubmit.db"]
+if { $verbose } { puts "Using database at $db_file" }
 open_db $db_file
 submit_ports
 close_db

Modified: branches/release_1_4/base/src/darwinports1.0/darwinports.tcl
===================================================================
--- branches/release_1_4/base/src/darwinports1.0/darwinports.tcl	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/darwinports1.0/darwinports.tcl	2007-05-17 01:10:15 UTC (rev 25263)
@@ -224,6 +224,7 @@
 	}
 }
 
+
 proc dportinit {{up_ui_options {}} {up_options {}} {up_variations {}}} {
 	if {$up_ui_options eq ""} {
 		array set ui_options {}
@@ -243,7 +244,7 @@
 	
 	global auto_path env
 	global darwinports::autoconf::dports_conf_path
-	global darwinports::autoconf::macports_user_dir
+	global darwinports::macports_user_dir
 	global darwinports::bootstrap_options
 	global darwinports::user_options
 	global darwinports::extra_env
@@ -267,22 +268,38 @@
    	global darwinports::xcodebuildcmd
    	global darwinports::xcodeversion
    	
-    # Ensure that the macports user directory exists
-    file mkdir $macports_user_dir
-    
+    # Ensure that the macports user directory exists if HOME is defined
+    if {[info exists env(HOME)]} {
+	    set darwinports::macports_user_dir [file normalize $darwinports::autoconf::macports_user_dir]
+		if { ![file exists $macports_user_dir] } {
+			# If not, create it with ownership of the enclosing directory, rwx by the user only
+			file mkdir $macports_user_dir 
+			file attributes $macports_user_dir -permissions u=rwx,go= \
+											   -owner [file attributes $macports_user_dir/.. -owner] \
+											   -group [file attributes $macports_user_dir/.. -group]
+		}
+	} else {
+		# Otherwise define the user directory as a direcotory that will never exist
+		set darwinports::macports_user_dir "/dev/null/NO_HOME_DIR" 
+	}
+	
    	# Configure the search path for configuration files
    	set conf_files ""
-    if {[llength [array names env PORTSRC]] > 0} {
-		set PORTSRC [lindex [array get env PORTSRC] 1]
+    if {[info exists env(PORTSRC)]} {
+		set PORTSRC $env(PORTSRC)
 		lappend conf_files ${PORTSRC}
     }
-    lappend conf_files "${macports_user_dir}/ports.conf" "${dports_conf_path}/ports.conf"
+    if { [file isdirectory macports_user_dir] } {
+ 		lappend conf_files "${macports_user_dir}/ports.conf"
+ 	}
+    lappend conf_files "${dports_conf_path}/ports.conf"
     
     # Process the first configuration file we find on conf_files list
 	foreach file $conf_files {
 		if [file exists $file] {
 			set portconf $file
 			set fd [open $file r]
+			fconfigure $fd -encoding utf-8
 			while {[gets $fd line] >= 0} {
 				if {[regexp {^(\w+)([ \t]+(.*))?$} $line match option ignore val] == 1} {
 					if {[regexp {^"(.*)"[ \t]*$} $val match val2] == 1} {
@@ -304,6 +321,7 @@
 	set per_user "${macports_user_dir}/user.conf"
 	if [file exists $per_user] {
 		set fd [open $per_user r]
+		fconfigure $fd -encoding utf-8
 		while {[gets $fd line] >= 0} {
 			if {[regexp {^(\w+)([ \t]+(.*))?$} $line match option ignore val] == 1} {
 				if {[lsearch $user_options $option] >= 0} {
@@ -317,14 +335,23 @@
     if {![info exists sources_conf]} {
         return -code error "sources_conf must be set in $dports_conf_path/ports.conf or in $macports_user_dir/ports.conf"
     }
-    if {[catch {set fd [open $sources_conf r]} result]} {
-        return -code error "$result"
-    }
+    set fd [open $sources_conf r]
+    fconfigure $fd -encoding utf-8
     while {[gets $fd line] >= 0} {
         set line [string trimright $line]
-        if {![regexp {[\ \t]*#.*|^$} $line]} {
-            lappend sources $line
-	}
+        if {![regexp {^\s*#|^$} $line]} {
+            if {[regexp {^([\w-]+://\S+)(?:\s+\[(\w+(?:,\w+)*)\])?$} $line _ url flags]} {
+                set flags [split $flags ,]
+                foreach flag $flags {
+                    if {[lsearch -exact [list nosync] $flag] == -1} {
+                        ui_warn "$sources_conf source '$line' specifies invalid flag '$flag'"
+                    }
+                }
+                lappend sources [concat [list $url] $flags]
+            } else {
+                ui_warn "$sources_conf specifies invalid source '$line', ignored."
+            }
+        }
     }
     if {![info exists sources]} {
 	if {[file isdirectory dports]} {
@@ -336,9 +363,8 @@
 
 	if {[info exists variants_conf]} {
 		if {[file exist $variants_conf]} {
-			if {[catch {set fd [open $variants_conf r]} result]} {
-				return -code error "$result"
-			}
+			set fd [open $variants_conf r]
+			fconfigure $fd -encoding utf-8
 			while {[gets $fd line] >= 0} {
 				set line [string trimright $line]
 				if {![regexp {^[\ \t]*#.*$|^$} $line]} {
@@ -706,18 +732,14 @@
     global darwinports::portdbpath tcl_platform
     set fetchdir [file join $portdbpath portdirs]
     set fetchfile [file tail $url]
-    if {[catch {file mkdir $fetchdir} result]} {
-        return -code error $result
-    }
+    file mkdir $fetchdir
     if {![file writable $fetchdir]} {
     	return -code error "Port remote fetch failed: You do not have permission to write to $fetchdir"
     }
     if {[catch {exec curl -L -s -S -o [file join $fetchdir $fetchfile] $url} result]} {
         return -code error "Port remote fetch failed: $result"
     }
-    if {[catch {cd $fetchdir} result]} {
-	return -code error $result
-    }
+    cd $fetchdir
     if {[catch {exec tar -zxf $fetchfile} result]} {
 	return -code error "Port extract failed: $result"
     }
@@ -813,6 +835,12 @@
     darwinports::worker_init $workername $portpath [darwinports::getportbuildpath $portpath] $options $variations
 
     $workername eval source Portfile
+    
+    # evaluate the variants
+	if {[$workername eval eval_variants variations] != 0} {
+	    dportclose $dport
+		error "Error evaluating variants"
+	}
 
     ditem_key $dport provides [$workername eval return \$portname]
 
@@ -1034,7 +1062,7 @@
 proc _dportexec {target dport} {
 	# xxx: set the work path?
 	set workername [ditem_key $dport workername]
-	if {![catch {$workername eval eval_variants variations $target} result] && $result == 0 &&
+	if {![catch {$workername eval check_variants variations $target} result] && $result == 0 &&
 		![catch {$workername eval eval_targets $target} result] && $result == 0} {
 		# If auto-clean mode, clean-up after dependency install
 		if {[string equal ${darwinports::portautoclean} "yes"]} {
@@ -1061,9 +1089,9 @@
     global darwinports::registry.installtype
 
 	set workername [ditem_key $dport workername]
-
-	# XXX: move this into dportopen?
-	if {[$workername eval eval_variants variations $target] != 0} {
+	
+	# check variants
+	if {[$workername eval check_variants variations $target] != 0} {
 		return 1
 	}
 	
@@ -1164,11 +1192,18 @@
 	return [file join [darwinports::getsourcepath $source] PortIndex]
 }
 
-proc dportsync {args} {
+proc dportsync {} {
 	global darwinports::sources darwinports::portdbpath tcl_platform
 	global darwinports::autoconf::rsync_path
 
+    ui_debug "Synchronizing dports tree(s)"
 	foreach source $sources {
+	    set flags [lrange $source 1 end]
+	    set source [lindex $source 0]
+	    if {[lsearch -exact $flags nosync] != -1} {
+	        ui_debug "Skipping $source"
+	        continue
+	    }
 		ui_info "Synchronizing from $source"
 		switch -regexp -- [darwinports::getprotocol $source] {
 			{^file$} {
@@ -1177,12 +1212,19 @@
 				    if {[catch {set svncmd [darwinports::binaryInPath "svn"]}] == 0} {
 				        set svn_commandline "${svncmd} update --non-interactive \"${portdir}\""
 				        ui_debug $svn_commandline
-				        if {[catch {system $svn_commandline}]} {
+				        if {[catch {
+				            set euid [geteuid]
+				            set egid [getegid]
+				            ui_debug "changing euid/egid - current euid: $euid - current egid: $egid"
+				            setegid [name_to_gid [file attributes $portdir -group]]
+				            seteuid [name_to_uid [file attributes $portdir -owner]]
+				            system $svn_commandline
+				            seteuid $euid
+				            setegid $egid
+				        }]} {
+				            ui_debug "$::errorInfo"
 				            return -code error "sync failed doing svn update"
 				        }
-				        if {[catch {system "chmod -R a+r \"${portdir}\""}]} {
-				            ui_warn "Setting world read permissions on parts of the ports tree failed, need root?"
-				        }
 				    } else {
 				        return -code error "svn command not found"
 				    }
@@ -1195,9 +1237,7 @@
 				# Where to, boss?
 				set destdir [file dirname [darwinports::getindex $source]]
 
-				if {[catch {file mkdir $destdir} result]} {
-					return -code error $result
-				}
+				file mkdir $destdir
 
 				# Keep rsync happy with a trailing slash
 				if {[string index $source end] != "/"} {
@@ -1214,11 +1254,12 @@
 			}
 			{^https?$|^ftp$} {
 				set indexfile [darwinports::getindex $source]
-				if {[catch {file mkdir [file dirname $indexfile]} result]} {
-					return -code error $result
-				}
+				file mkdir [file dirname $indexfile]
 				exec curl -L -s -S -o $indexfile $source/PortIndex
 			}
+			default {
+			    ui_warn "Unknown protocol for $source"
+			}
 		}
 	}
 }
@@ -1230,6 +1271,8 @@
 	
 	set found 0
 	foreach source $sources {
+	    set flags [lrange $source 1 end]
+	    set source [lindex $source 0]
 		if {[darwinports::getprotocol $source] == "dports"} {
 			array set attrs [list name $pattern]
 			set res [darwinports::index::search $darwinports::portdbpath $source [array get attrs]]
@@ -1238,12 +1281,14 @@
 			if {[catch {set fd [open [darwinports::getindex $source] r]} result]} {
 				ui_warn "Can't open index file for source: $source"
 			} else {
+			    fconfigure $fd -encoding utf-8
 				incr found 1
 				while {[gets $fd line] >= 0} {
 					array unset portinfo
 					set name [lindex $line 0]
-					gets $fd line
-					
+					set len [lindex $line 1]
+					set line [read $fd $len]
+						
 					if {$easy} {
 						set target $name
 					} else {

Modified: branches/release_1_4/base/src/pextlib1.0/Pextlib.c
===================================================================
--- branches/release_1_4/base/src/pextlib1.0/Pextlib.c	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/pextlib1.0/Pextlib.c	2007-05-17 01:10:15 UTC (rev 25263)
@@ -1155,10 +1155,16 @@
 	
 	Tcl_CreateObjCommand(interp, "getuid", getuidCmd, NULL, NULL);
 	Tcl_CreateObjCommand(interp, "geteuid", geteuidCmd, NULL, NULL);
+	Tcl_CreateObjCommand(interp, "getgid", getgidCmd, NULL, NULL);
+	Tcl_CreateObjCommand(interp, "getegid", getegidCmd, NULL, NULL);
 	Tcl_CreateObjCommand(interp, "setuid", setuidCmd, NULL, NULL);
 	Tcl_CreateObjCommand(interp, "seteuid", seteuidCmd, NULL, NULL);
+	Tcl_CreateObjCommand(interp, "setgid", setgidCmd, NULL, NULL);
+	Tcl_CreateObjCommand(interp, "setegid", setegidCmd, NULL, NULL);
 	Tcl_CreateObjCommand(interp, "name_to_uid", name_to_uidCmd, NULL, NULL);
 	Tcl_CreateObjCommand(interp, "uid_to_name", uid_to_nameCmd, NULL, NULL);
+	Tcl_CreateObjCommand(interp, "name_to_gid", name_to_gidCmd, NULL, NULL);
+	Tcl_CreateObjCommand(interp, "gid_to_name", gid_to_nameCmd, NULL, NULL);
 
 	if (Tcl_PkgProvide(interp, "Pextlib", "1.0") != TCL_OK)
 		return TCL_ERROR;

Modified: branches/release_1_4/base/src/pextlib1.0/fs-traverse.c
===================================================================
--- branches/release_1_4/base/src/pextlib1.0/fs-traverse.c	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/pextlib1.0/fs-traverse.c	2007-05-17 01:10:15 UTC (rev 25263)
@@ -133,7 +133,7 @@
     FTS *root_fts;
     FTSENT *ent;
     
-    root_fts = fts_open(targets, FTS_PHYSICAL | FTS_COMFOLLOW | FTS_NOCHDIR | FTS_XDEV, NULL);
+    root_fts = fts_open(targets, FTS_PHYSICAL /*| FTS_COMFOLLOW */| FTS_NOCHDIR | FTS_XDEV, NULL);
     
     while ((ent = fts_read(root_fts)) != NULL) {
         switch (ent->fts_info) {

Modified: branches/release_1_4/base/src/pextlib1.0/tests/fs-traverse.tcl
===================================================================
--- branches/release_1_4/base/src/pextlib1.0/tests/fs-traverse.tcl	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/pextlib1.0/tests/fs-traverse.tcl	2007-05-17 01:10:15 UTC (rev 25263)
@@ -33,6 +33,13 @@
         }
         check_output $output $trees(sub1)
         
+        # Test starting with a slash-ended symlink
+        set output [list]
+        fs-traverse file $root/a/c/a/ {
+            lappend output $file
+        }
+        check_output $output $trees(sub2)
+        
         # Test -depth
         set output [list]
         fs-traverse -depth file $root {
@@ -226,12 +233,16 @@
     
     set trees(sub1) "
         $root/a/c/a     {link ../d}
-        $root/a/c/a/a   file
-        $root/a/c/a/b   {link ../../b/a}
-        $root/a/c/a/c   directory
-        $root/a/c/a/d   file
     "
     
+    set trees(sub2) "
+        $root/a/c/a/     {link ../d}
+        $root/a/c/a//a   file
+        $root/a/c/a//b   {link ../../b/a}
+        $root/a/c/a//c   directory
+        $root/a/c/a//d   file
+    "
+    
     set trees(2) "
         $root/a/a       file
         $root/a/b       file

Modified: branches/release_1_4/base/src/pextlib1.0/uid.c
===================================================================
--- branches/release_1_4/base/src/pextlib1.0/uid.c	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/pextlib1.0/uid.c	2007-05-17 01:10:15 UTC (rev 25263)
@@ -9,6 +9,7 @@
  */
  
 #include "uid.h"
+#include "grp.h"
 
 #if HAVE_CONFIG_H
 #include <config.h>
@@ -40,7 +41,6 @@
 
 #include <tcl.h>
 
-
 /*
 	getuid
 	
@@ -48,20 +48,16 @@
 */
 int getuidCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
 {
-	Tcl_Obj *tcl_result;
-	
 	/* Check the arg count */
 	if (objc != 1) {
-		Tcl_WrongNumArgs(interp, 1, objv, "getuid");
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
 		return TCL_ERROR;
 	}
 	
-	tcl_result = Tcl_NewLongObj(getuid());	
-	Tcl_SetObjResult(interp, tcl_result);
+	Tcl_SetObjResult(interp, Tcl_NewLongObj(getuid()));
 	return TCL_OK;
 }
 
-
 /*
 	geteuid
 	
@@ -69,21 +65,45 @@
 */
 int geteuidCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
 {
-	Tcl_Obj *tcl_result;
-	
 	/* Check the arg count */
 	if (objc != 1) {
-		Tcl_WrongNumArgs(interp, 1, objv, "geteuid");
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
 		return TCL_ERROR;
 	}
 	
-	tcl_result = Tcl_NewLongObj(geteuid());	
-	Tcl_SetObjResult(interp, tcl_result);
+	Tcl_SetObjResult(interp, Tcl_NewLongObj(geteuid()));
 	return TCL_OK;
 }
 
+/*
+    getgid
+*/
+int getgidCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+{
+    if (objc != 1) {
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
+        return TCL_ERROR;
+    }
+    
+    Tcl_SetObjResult(interp, Tcl_NewLongObj(getgid()));
+    return TCL_OK;
+}
 
 /*
+    getegid
+*/
+int getegidCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+{
+    if (objc != 1) {
+        Tcl_WrongNumArgs(interp, 1, objv, NULL);
+        return TCL_ERROR;
+    }
+    
+    Tcl_SetObjResult(interp, Tcl_NewLongObj(getegid()));
+    return TCL_OK;
+}
+
+/*
 	setuid
 	
 	synopsis: setuid uid
@@ -94,7 +114,7 @@
 	
 	/* Check the arg count */
 	if (objc != 2) {
-		Tcl_WrongNumArgs(interp, 1, objv, "setuid");
+		Tcl_WrongNumArgs(interp, 1, objv, "uid");
 		return TCL_ERROR;
 	}
 	
@@ -103,14 +123,16 @@
 		return TCL_ERROR;
 		
 	/* set the uid */
-	if (0 != setuid(uid))
-		Tcl_SetResult(interp, "setuid failed", NULL);
+	if (0 != setuid(uid)) {
+        Tcl_Obj *result = Tcl_NewStringObj("could not set uid to ", -1);
+        Tcl_AppendObjToObj(result, objv[1]);
+        Tcl_SetObjResult(interp, result);
+        return TCL_ERROR;
+    }
 		
 	return TCL_OK;
 }
 
-
-
 /*
 	seteuid
 	
@@ -122,7 +144,7 @@
 
 	/* Check the arg count */
 	if (objc != 2) {
-		Tcl_WrongNumArgs(interp, 1, objv, "seteuid");
+		Tcl_WrongNumArgs(interp, 1, objv, "uid");
 		return TCL_ERROR;
 	}
 	
@@ -131,13 +153,67 @@
 		return TCL_ERROR;
 		
 	/* set the euid */
-	if (0 != seteuid(uid))
-		Tcl_SetResult(interp, "seteuid failed", NULL);
+	if (0 != seteuid(uid)) {
+        Tcl_Obj *result = Tcl_NewStringObj("could not set effective uid to ", -1);
+        Tcl_AppendObjToObj(result, objv[1]);
+        Tcl_SetObjResult(interp, result);
+        return TCL_ERROR;
+    }
 		
 	return TCL_OK;
 }
 
+/*
+    setgid
+*/
+int setgidCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+{
+    long gid;
+    
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "gid");
+        return TCL_ERROR;
+    }
+    
+    if (TCL_OK != Tcl_GetLongFromObj(interp, objv[1], &gid)) {
+        return TCL_ERROR;
+    }
+    
+    if (0 != setgid(gid)) {
+        Tcl_Obj *result = Tcl_NewStringObj("could not set gid to ", -1);
+        Tcl_AppendObjToObj(result, objv[1]);
+        Tcl_SetObjResult(interp, result);
+        return TCL_ERROR;
+    }
+    
+    return TCL_OK;
+}
 
+/*
+    setegid
+*/
+int setegidCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+{
+    long gid;
+    
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "gid");
+        return TCL_ERROR;
+    }
+    
+    if (TCL_OK != Tcl_GetLongFromObj(interp, objv[1], &gid)) {
+        return TCL_ERROR;
+    }
+    
+    if (0 != setegid(gid)) {
+        Tcl_Obj *result = Tcl_NewStringObj("could not set effective gid to ", -1);
+        Tcl_AppendObjToObj(result, objv[1]);
+        Tcl_SetObjResult(interp, result);
+        return TCL_ERROR;
+    }
+    
+    return TCL_OK;
+}
 
 /*
 	name_to_uid
@@ -151,7 +227,7 @@
 	
 	/* Check the arg count */
 	if (objc != 2) {
-		Tcl_WrongNumArgs(interp, 1, objv, "name_to_uid");
+		Tcl_WrongNumArgs(interp, 1, objv, "name");
 		return TCL_ERROR;
 	}
 	
@@ -171,8 +247,6 @@
 	return TCL_OK;
 }
 
-
-
 /*
 	uid_to_name
 	
@@ -185,7 +259,7 @@
 	
 	/* Check the arg count */
 	if (objc != 2) {
-		Tcl_WrongNumArgs(interp, 1, objv, "getpwnam");
+		Tcl_WrongNumArgs(interp, 1, objv, "uid");
 		return TCL_ERROR;
 	}
 	
@@ -196,10 +270,57 @@
 	/* Map the uid --> name, or empty result on error */
 	pwent = getpwuid(uid);
 	if (pwent != NULL)
-		Tcl_SetResult(interp, pwent->pw_name, NULL);
+		Tcl_SetResult(interp, pwent->pw_name, TCL_STATIC);
 
 	return TCL_OK;
 }
 
+/*
+    name_to_gid
+*/
+int name_to_gidCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+{
+    struct group *grent;
+    char *name;
+    
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "name");
+        return TCL_ERROR;
+    }
+    
+    name = Tcl_GetString(objv[1]);
+    if (name == NULL || !*name)
+        return TCL_ERROR;
+    
+    grent = getgrnam(name);
+    
+    if (grent == NULL)
+        Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
+    else
+        Tcl_SetObjResult(interp, Tcl_NewIntObj(grent->gr_gid)); 
+    
+    return TCL_OK;
+}
 
-
+/*
+    gid_to_name
+*/
+int gid_to_nameCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+{
+    long gid;
+    struct group *grent;
+    
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "gid");
+        return TCL_ERROR;
+    }
+    
+    if (TCL_OK != Tcl_GetLongFromObj(interp, objv[1], &gid))
+        return TCL_ERROR;
+    
+    grent = getgrgid(gid);
+    if (grent != NULL)
+        Tcl_SetResult(interp, grent->gr_name, TCL_STATIC);
+    
+    return TCL_OK;
+}

Modified: branches/release_1_4/base/src/pextlib1.0/uid.h
===================================================================
--- branches/release_1_4/base/src/pextlib1.0/uid.h	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/pextlib1.0/uid.h	2007-05-17 01:10:15 UTC (rev 25263)
@@ -37,10 +37,16 @@
 
 int getuidCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
 int geteuidCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
+int getgidCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
+int getegidCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
 int setuidCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
 int seteuidCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
+int setgidCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
+int setegidCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
 int name_to_uidCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
 int uid_to_nameCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
+int name_to_gidCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
+int gid_to_nameCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
 
 
 #endif

Modified: branches/release_1_4/base/src/port/port.1
===================================================================
--- branches/release_1_4/base/src/port/port.1	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/port/port.1	2007-05-17 01:10:15 UTC (rev 25263)
@@ -254,15 +254,24 @@
 .Fl -category
 (recognized field names are those from the portindex). If the global option
 .Fl q
-is in effect, the meta-info fields will not be labeled; if the option
+is in effect, the meta-info fields will not be labeled.
+If the option
 .Fl -line
-is provided, all such data will be consolidated into a single line per port, suitable for processing in a pipe of commands.
+is provided, all such data will be consolidated into a single line per port,
+suitable for processing in a pipe of commands.
+If the option
+.Fl -index
+is provided, the information will be pulled from the PortIndex rather than
+from the Portfile (in this case variant information, such as dependencies,
+will not affect the output).
+.Pp
 For example:
-.Pp
-.Dl "port info vim"
+.br
+.Dl "port info vim +ruby"
 .Dl "port info --category --name apache*"
 .Dl "port -q info --category --name --version category:java"
 .Dl "port info --line --category --name all"
+.Dl "port info --index python24"
 .Ss variants
 Lists the build variants available for
 .Ar portname .
@@ -309,6 +318,12 @@
 from the MacPorts rsync server. To update you would normally do:
 .Pp
 .Dl "sudo port -d sync"
+.Pp
+If any of the dports tree(s) uses a file: URL that points to a local subversion working copy,
+.Ic sync
+will perform an
+.Ic "svn update"
+on the working copy with the user set to the owner of the working copy.
 .Ss outdated
 List the installed ports that need upgrading.
 .Ss upgrade
@@ -394,6 +409,10 @@
 installing the newest infrastructure available. To update you would typically do:
 .Pp
 .Dl "sudo port -d selfupdate"
+.Pp
+See
+.Ic sync
+for more information about updating dports tree(s).
 .Ss help
 Displays a summary of all available actions and port command syntax on stdout.
 .Sh DEVELOPER TARGETS

Modified: branches/release_1_4/base/src/port/port.tcl
===================================================================
--- branches/release_1_4/base/src/port/port.tcl	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/port/port.tcl	2007-05-17 01:10:15 UTC (rev 25263)
@@ -1133,169 +1133,173 @@
 
 
 proc action_info { action portlist opts } {
-	set status 0
-	require_portlist portlist
-	foreachport $portlist {	
-		# Get information about the named port
-		if {[catch {dportsearch $portname no exact} result]} {
-			global errorInfo
-			ui_debug "$errorInfo"
-			break_softcontinue "search for portname $portname failed: $result" 1 status
-		}
-	
-		if {$result == ""} {
-			puts "No port $portname found."
-		} else {
-			set found [expr [llength $result] / 2]
-			if {$found > 1} {
-				ui_warn "Found $found port $portname definitions, displaying first one."
-			}
-			array unset portinfo
-			array set portinfo [lindex $result 1]
-			
-			
-			# Map from friendly to less-friendly but real names
-			array set name_map "
-					category		categories
-					maintainer		maintainers
-					platform		platforms
-					variant			variants
-					"
-					
-			# Understand which info items are actually lists
-			# (this could be overloaded to provide a generic formatting code to
-			# allow us to, say, split off the prefix on libs)
-			array set list_map "
-					categories		1
-					depends_build	1
-					depends_lib		1
-					maintainers		1
-					platforms		1
-					variants		1
-					"
-					
-			# Set up our field separators
-			set show_label 1
-			set field_sep "\n"
-			set subfield_sep ", "
-			
-			# Tune for sort(1)
-			if {[info exists options(ports_info_line)]} {
-				array unset options ports_info_line
-				set show_label 0
-				set field_sep "\t"
-				set subfield_sep ","
-			}
+    set status 0
+    require_portlist portlist
+    foreachport $portlist {
+        # If we have a url, use that, since it's most specific
+        # otherwise try to map the portname to a url
+        if {$porturl eq ""} {
+            # Verify the portname, getting portinfo to map to a porturl
+            if {[catch {dportsearch $portname no exact} result]} {
+                ui_debug "$::errorInfo"
+                break_softcontinue "search for portname $portname failed: $result" 1 status
+            }
+            if {[llength $result] < 2} {
+                break_softcontinue "Port $portname not found" 1 status
+            }
+            set found [expr [llength $result] / 2]
+            if {$found > 1} {
+                ui_warn "Found $found port $portname definitions, displaying first one."
+            }
+            array unset portinfo
+            array set portinfo [lindex $result 1]
+            set porturl $portinfo(porturl)
+            set portdir $portinfo(portdir)
+        }
+        
+        if {!([info exists options(ports_info_index)] && $options(ports_info_index) eq "yes")} {
+            if {[catch {set dport [dportopen $porturl [array get options] [array get variations]]} result]} {
+                ui_debug "$::errorInfo"
+                break_softcontinue "Unable to open port: $result" 1 status
+            }
+            array unset portinfo
+            array set portinfo [dportinfo $dport]
+            dportclose $dport
+            if {[info exists portdir]} {
+                set portinfo(portdir) $portdir
+            }
+        } elseif {![info exists portinfo]} {
+            ui_warn "port info --index does not work with 'current' pseudo-port"
+            continue
+        }
+        
+        # Map from friendly to less-friendly but real names
+        array set name_map "
+                category        categories
+                maintainer      maintainers
+                platform        platforms
+                variant         variants
+                "
+                
+        # Understand which info items are actually lists
+        # (this could be overloaded to provide a generic formatting code to
+        # allow us to, say, split off the prefix on libs)
+        array set list_map "
+                categories      1
+                depends_build   1
+                depends_lib     1
+                maintainers     1
+                platforms       1
+                variants        1
+                "
+                
+        # Set up our field separators
+        set show_label 1
+        set field_sep "\n"
+        set subfield_sep ", "
+        
+        # Tune for sort(1)
+        if {[info exists options(ports_info_line)]} {
+            array unset options ports_info_line
+            set show_label 0
+            set field_sep "\t"
+            set subfield_sep ","
+        }
 
-			# Figure out whether to show field name
-			set quiet [ui_isset ports_quiet]
-			if {$quiet} {
-				set show_label 0
-			}
-			
-			# Spin through action options, emitting information for any found
-			set fields {}
-			foreach { option } [array names options ports_info_*] {
-				set opt [string range $option 11 end]
-				
-				# Map from friendly name
-				set ropt $opt
-				if {[info exists name_map($opt)]} {
-					set ropt $name_map($opt)
-				}
-				
-				# If there's no such info, move on
-				if {![info exists portinfo($ropt)]} {
-					if {!$quiet} {
-						puts "no info for '$opt'"
-					}
-					continue
-				}
-				
-				# Calculate field label
-				set label ""
-				if {$show_label} {
-					set label "$opt: "
-				}
-				
-				# Format the data
-				set inf $portinfo($ropt)
-				if [info exists list_map($ropt)] {
-					set field [join $inf $subfield_sep]
-				} else {
-					set field $inf
-				}
-				
-				lappend fields "$label$field"
-			}
-			
-			if {[llength $fields]} {
-				# Show specific fields
-				puts [join $fields $field_sep]
-			} else {
-			
-				# If we weren't asked to show any specific fields, then show general information
-				puts -nonewline "$portinfo(name) $portinfo(version)"
-				if {[info exists portinfo(revision)] && $portinfo(revision) > 0} { 
-					puts -nonewline ", Revision $portinfo(revision)" 
-				}
-				puts -nonewline ", $portinfo(portdir)" 
-				if {[info exists portinfo(variants)]} {
-					puts -nonewline " (Variants: "
-					for {set i 0} {$i < [llength $portinfo(variants)]} {incr i} {
-						if {$i > 0} { puts -nonewline ", " }
-						puts -nonewline "[lindex $portinfo(variants) $i]"
-					}
-					puts -nonewline ")"
-				}
-				puts ""
-				if {[info exists portinfo(homepage)]} { 
-					puts "$portinfo(homepage)"
-				}
-		
-				if {[info exists portinfo(long_description)]} {
-					puts "\n$portinfo(long_description)\n"
-				}
-	
-				# find build dependencies
-				if {[info exists portinfo(depends_build)]} {
-					puts -nonewline "Build Dependencies: "
-					for {set i 0} {$i < [llength $portinfo(depends_build)]} {incr i} {
-						if {$i > 0} { puts -nonewline ", " }
-						puts -nonewline "[lindex [split [lindex $portinfo(depends_build) $i] :] end]"
-					}
-					set nodeps false
-					puts ""
-				}
-		
-				# find library dependencies
-				if {[info exists portinfo(depends_lib)]} {
-					puts -nonewline "Library Dependencies: "
-					for {set i 0} {$i < [llength $portinfo(depends_lib)]} {incr i} {
-						if {$i > 0} { puts -nonewline ", " }
-						puts -nonewline "[lindex [split [lindex $portinfo(depends_lib) $i] :] end]"
-					}
-					set nodeps false
-					puts ""
-				}
-		
-				# find runtime dependencies
-				if {[info exists portinfo(depends_run)]} {
-					puts -nonewline "Runtime Dependencies: "
-					for {set i 0} {$i < [llength $portinfo(depends_run)]} {incr i} {
-						if {$i > 0} { puts -nonewline ", " }
-						puts -nonewline "[lindex [split [lindex $portinfo(depends_run) $i] :] end]"
-					}
-					set nodeps false
-					puts ""
-				}
-				if {[info exists portinfo(platforms)]} { puts "Platforms: $portinfo(platforms)"}
-				if {[info exists portinfo(maintainers)]} { puts "Maintainers: $portinfo(maintainers)"}
-			}
-		}
-	}
-	
-	return $status
+        # Figure out whether to show field name
+        set quiet [ui_isset ports_quiet]
+        if {$quiet} {
+            set show_label 0
+        }
+        
+        # Spin through action options, emitting information for any found
+        set fields {}
+        foreach { option } [array names options ports_info_*] {
+            set opt [string range $option 11 end]
+            if {$opt eq "index"} {
+                continue
+            }
+            
+            # Map from friendly name
+            set ropt $opt
+            if {[info exists name_map($opt)]} {
+                set ropt $name_map($opt)
+            }
+            
+            # If there's no such info, move on
+            if {![info exists portinfo($ropt)]} {
+                if {!$quiet} {
+                    puts "no info for '$opt'"
+                }
+                continue
+            }
+            
+            # Calculate field label
+            set label ""
+            if {$show_label} {
+                set label "$opt: "
+            }
+            
+            # Format the data
+            set inf $portinfo($ropt)
+            if [info exists list_map($ropt)] {
+                set field [join $inf $subfield_sep]
+            } else {
+                set field $inf
+            }
+            
+            lappend fields "$label$field"
+        }
+        
+        if {[llength $fields]} {
+            # Show specific fields
+            puts [join $fields $field_sep]
+        } else {
+        
+            # If we weren't asked to show any specific fields, then show general information
+            puts -nonewline "$portinfo(name) $portinfo(version)"
+            if {[info exists portinfo(revision)] && $portinfo(revision) > 0} { 
+                puts -nonewline ", Revision $portinfo(revision)" 
+            }
+            if {[info exists portinfo(portdir)]} {
+                puts -nonewline ", $portinfo(portdir)"
+            }
+            if {[info exists portinfo(variants)]} {
+                puts -nonewline " (Variants: [join $portinfo(variants) ", "])"
+            }
+            puts ""
+            if {[info exists portinfo(homepage)]} { 
+                puts "$portinfo(homepage)"
+            }
+    
+            if {[info exists portinfo(long_description)]} {
+                puts "\n[join $portinfo(long_description)]\n"
+            }
+
+            # Emit build, library, and runtime dependencies
+            foreach {key title} {
+                depends_build "Build Dependencies"
+                depends_lib "Library Dependencies"
+                depends_run "Runtime Dependencies"
+            } {
+                if {[info exists portinfo($key)]} {
+                    puts -nonewline "$title:"
+                    set joiner ""
+                    foreach d $portinfo($key) {
+                        puts -nonewline "$joiner [lindex [split $d :] end]"
+                        set joiner ","
+                    }
+                    set nodeps false
+                    puts ""
+                }
+            }
+                
+            if {[info exists portinfo(platforms)]} { puts "Platforms: $portinfo(platforms)"}
+            if {[info exists portinfo(maintainers)]} { puts "Maintainers: $portinfo(maintainers)"}
+        }
+    }
+    
+    return $status
 }
 
 
@@ -1758,10 +1762,21 @@
 		if {![info exists portinfo(variants)]} {
 			puts "$portname has no variants"
 		} else {
+			# Get the variant descriptions
+			if {[info exists portinfo(variant_desc)]} {
+				array set descs $portinfo(variant_desc)
+			} else {
+				array set descs ""
+			}
+
 			# print out all the variants
 			puts "$portname has the variants:"
-			for {set i 0} {$i < [llength $portinfo(variants)]} {incr i} {
-				puts "\t[lindex $portinfo(variants) $i]"
+			foreach v $portinfo(variants) {
+				if {[info exists descs($v)]} {
+					puts "\t$v: $descs($v)"
+				} else {
+					puts "\t$v"
+				}
 			}
 		}
 	}
@@ -1802,9 +1817,9 @@
 				continue
 			}
 			if {![info exists portinfo(portdir)]} {
-				set output [format "%-30s %-12s %s" $portinfo(name) $portinfo(version) $portinfo(description)]
+				set output [format "%-30s %-12s %s" $portinfo(name) $portinfo(version) [join $portinfo(description)]]
 			} else {
-				set output [format "%-30s %-14s %-12s %s" $portinfo(name) $portinfo(portdir) $portinfo(version) $portinfo(description)]
+				set output [format "%-30s %-14s %-12s %s" $portinfo(name) $portinfo(portdir) $portinfo(version) [join $portinfo(description)]]
 			}
 			set portfound 1
 			puts $output
@@ -2434,16 +2449,15 @@
 
 proc process_command_file { in } {
 	global current_portdir
-	global darwinports::autoconf::macports_user_dir
 
 	# Initialize readline
 	set isstdin [string match $in "stdin"]
 	set name "port"
 	set use_readline [expr $isstdin && [readline init $name]]
-	set history_file [file normalize "${macports_user_dir}/history"]
+	set history_file [file normalize "${darwinports::macports_user_dir}/history"]
 
 	# Read readline history
-	if {$use_readline} {
+	if {$use_readline && [file isdirectory $darwinports::macports_user_dir]} {
 		rl_history read $history_file
 		rl_history stifle 100
 	}
@@ -2486,7 +2500,7 @@
 	}
 	
 	# Save readine history
-	if {$use_readline} {
+	if {$use_readline && [file isdirectory $darwinports::macports_user_dir]} {
 		rl_history write $history_file
 	}
 	

Modified: branches/release_1_4/base/src/port/portindex.tcl
===================================================================
--- branches/release_1_4/base/src/port/portindex.tcl	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/port/portindex.tcl	2007-05-17 01:10:15 UTC (rev 25263)
@@ -202,6 +202,7 @@
 
 puts "Creating software index in $outdir"
 set fd [open [file join $outdir PortIndex] w]
+fconfigure $fd -encoding utf-8
 dporttraverse pindex $directory
 close $fd
 puts "\nTotal number of ports parsed:\t$stats(total)\

Modified: branches/release_1_4/base/src/port1.0/portdepends.tcl
===================================================================
--- branches/release_1_4/base/src/port1.0/portdepends.tcl	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/port1.0/portdepends.tcl	2007-05-17 01:10:15 UTC (rev 25263)
@@ -48,8 +48,8 @@
 		set {
 			foreach depspec $value {
 				switch -regex $depspec {
-					^(lib|bin|path):([-A-Za-z0-9_/.${}^?+()|\\\\]+):([-A-Za-z./0-9_]+)$ {}
-					^(port):([-A-Za-z./0-9_]+)$ {}
+					^(lib|bin|path):([-A-Za-z0-9_/.${}^?+()|\\\\]+):([-._A-Za-z0-9]+)$ {}
+					^(port):([-._A-Za-z0-9]+)$ {}
 					default { return -code error [format [msgcat::mc "invalid depspec: %s"] $depspec] }
 				}
 			}

Modified: branches/release_1_4/base/src/port1.0/portsubmit.tcl
===================================================================
--- branches/release_1_4/base/src/port1.0/portsubmit.tcl	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/port1.0/portsubmit.tcl	2007-05-17 01:10:15 UTC (rev 25263)
@@ -149,8 +149,8 @@
 			putel $sd version $version
 			putel $sd revision $revision
 			
-			putel $sd description $description
-			putel $sd long_description $long_description
+			putel $sd description [join $description]
+			putel $sd long_description [join $long_description]
 		
 			# TODO: variants has platforms in it
 			if {[info exists PortInfo(variants)]} {

Modified: branches/release_1_4/base/src/port1.0/portutil.tcl
===================================================================
--- branches/release_1_4/base/src/port1.0/portutil.tcl	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/port1.0/portutil.tcl	2007-05-17 01:10:15 UTC (rev 25263)
@@ -99,9 +99,9 @@
         proc ${option}-delete {args} [subst -nocommands {
             global $option user_options option_procs
             if {![info exists user_options($option)] && [info exists $option]} {
-                set temp $option
+                set temp [set $option]
                 foreach val \$args {
-                   set temp [ldelete \${$option} \$val]
+                   set temp [ldelete \$temp \$val]
                 }
                 if {\$temp eq ""} {
                     unset $option
@@ -353,7 +353,6 @@
 # Portfile level procedure to provide support for declaring variants
 proc variant {args} {
     global all_variants PortInfo
-    upvar $args upargs
     
     set len [llength $args]
     set code [lindex $args end]
@@ -368,9 +367,10 @@
     set mode "provides"
     foreach arg $args {
 	switch -exact $arg {
-	    provides { set mode "provides" }
-	    requires { set mode "requires" }
-	    conflicts { set mode "conflicts" }
+	    description -
+	    provides -
+	    requires -
+	    conflicts { set mode $arg }
 	    default { ditem_append $ditem $mode $arg }		
         }
     }
@@ -389,6 +389,10 @@
 		variant_remove_ditem $variant_provides
 	} else {
 	    lappend PortInfo(variants) $variant_provides
+	    set vdesc [join [ditem_key $ditem description]]
+	    if {$vdesc != ""} {
+		    lappend PortInfo(variant_desc) $variant_provides $vdesc
+		}
 	}
 
 	# Finally append the ditem to the dlist.
@@ -481,7 +485,6 @@
 # be more readable, and support arch and version specifics
 proc platform {args} {
     global all_variants PortInfo os.platform os.arch os.version
-    upvar $args upargs
     
     set len [llength $args]
     set code [lindex $args end]
@@ -658,13 +661,34 @@
 
 # reinplace
 # Provides "sed in place" functionality
-proc reinplace {pattern args}  {
-    if {$args == ""} {
-    	ui_error "reinplace: no value given for parameter \"file\""
-	return -code error "no value given for parameter \"file\" to \"reinplace\"" 
+proc reinplace {args}  {
+    set extended 0
+    while 1 {
+        set arg [lindex $args 0]
+        if {[string first - $arg] != -1} {
+            set args [lrange $args 1 end]
+            switch [string range $arg 1 end] {
+                E {
+                    set extended 1
+                }
+                - {
+                    break
+                }
+                default {
+                    error "reinplace: unknown flag '-$arg'"
+                }
+            }
+        } else {
+            break
+        }
     }
+    if {[llength $args] < 2} {
+        error "reinplace ?-E? pattern file ..."
+    }
+    set pattern [lindex $args 0]
+    set files [lrange $args 1 end]
     
-    foreach file $args {
+    foreach file $files {
 	if {[catch {set tmpfile [mkstemp "/tmp/[file tail $file].sed.XXXXXXXX"]} error]} {
 		global errorInfo
 		ui_debug "$errorInfo"
@@ -677,7 +701,12 @@
 	    set tmpfile [lindex $tmpfile 1]
 	}
 	
-	if {[catch {exec sed $pattern < $file >@ $tmpfd} error]} {
+	set cmdline sed
+	if {$extended} {
+	    lappend cmdline -E
+	}
+	set cmdline [concat $cmdline [list $pattern < $file >@ $tmpfd]]
+	if {[catch {eval exec $cmdline} error]} {
 		global errorInfo
 		ui_debug "$errorInfo"
 	    ui_error "reinplace: $error"
@@ -825,12 +854,12 @@
 
 # copy
 proc copy {args} {
-    exec file copy $args
+    eval file copy $args
 }
 
 # move
 proc move {args} {
-    exec file rename $args
+    eval file rename $args
 }
 
 # ln
@@ -1367,10 +1396,9 @@
     return 0
 }
 
-proc eval_variants {variations target} {
+proc eval_variants {variations} {
     global all_variants ports_force PortInfo
     set dlist $all_variants
-    set result 0
     upvar $variations upvariations
     set chosen [choose_variants $dlist upvariations]
 	set portname $PortInfo(name)
@@ -1402,6 +1430,15 @@
 		return 1
     }
     
+    return 0
+}
+
+proc check_variants {variations target} {
+    global ports_force PortInfo
+    upvar $variations upvariations
+    set result 0
+    set portname $PortInfo(name)
+    
     # Make sure the variations match those stored in the statefile.
     # If they don't match, print an error indicating a 'port clean' 
     # should be performed.  

Modified: branches/release_1_4/base/src/port1.0/resources/fetch/mirror_sites.tcl
===================================================================
--- branches/release_1_4/base/src/port1.0/resources/fetch/mirror_sites.tcl	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/port1.0/resources/fetch/mirror_sites.tcl	2007-05-17 01:10:15 UTC (rev 25263)
@@ -173,7 +173,7 @@
     http://easynews.dl.sourceforge.net/
     http://ufpr.dl.sourceforge.net/
     http://kent.dl.sourceforge.net/
-    http://jaist.dl.sourceforge.net
+    http://jaist.dl.sourceforge.net/
 }
 
 set portfetch::mirror_sites::sites(sunsite) {

Modified: branches/release_1_4/base/src/port1.0/resources/group/ruby-1.0.tcl
===================================================================
--- branches/release_1_4/base/src/port1.0/resources/group/ruby-1.0.tcl	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/port1.0/resources/group/ruby-1.0.tcl	2007-05-17 01:10:15 UTC (rev 25263)
@@ -92,7 +92,7 @@
 			master_sites	http://rubyforge.org/frs/download.php/${num}/
 			livecheck.check	regex
 			livecheck.url	http://rubyforge.org/projects/${ruby.project}
-			livecheck.regex	"<strong>${ruby.project}</strong></td><td>REL (.*)$"
+			livecheck.regex	"<strong>${ruby.project}</strong></td><td>(?:REL )?(.*)$"
 		}
 		rubyforge:* {
 			set num [lindex [split ${source} {:}] 1]
@@ -100,7 +100,7 @@
 			master_sites	http://rubyforge.org/frs/download.php/${num}/
 			livecheck.check	regex
 			livecheck.url	http://rubyforge.org/projects/${ruby.project}
-			livecheck.regex	"<strong>${ruby.project}</strong></td><td>REL (.*)$"
+			livecheck.regex	"<strong>${ruby.project}</strong></td><td>(?:REL )?(.*)$"
 		}
 		rubyforge_gem:* {
 			set ruby.project [lindex [split ${source} {:}] 1]

Modified: branches/release_1_4/base/src/port1.0/tests/portutil.tcl
===================================================================
--- branches/release_1_4/base/src/port1.0/tests/portutil.tcl	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/src/port1.0/tests/portutil.tcl	2007-05-17 01:10:15 UTC (rev 25263)
@@ -40,18 +40,55 @@
             b/c/b           file
             b/d             file
         }
-    
+        
+        # test deleting a symlink
+        delete $root/a/c/b
+        
+        if {[file exists $root/a/c/b] || ![file exists $root/a/b]} {
+            error "delete (symlink) failed"
+        }
+        
         # test multiple args
         delete $root/a $root/b
-    
+        
         if {[file exists $root/a] || [file exists $root/b]} {
-            error "delete failed"
+            error "delete (multiple args) failed"
         }
     } finally {
         file delete -force $root
     }
 }
 
+proc test_depends_lib-delete {} {
+    # tests depends_lib-delete
+    # actually tests all option-deletes
+    # but the bug was originally documented with depends_lib
+    
+    # depends_lib is intended to work from within a worker thread
+    # so we shall oblige
+    set workername [interp create]
+    darwinports::worker_init $workername {} [darwinports::getportbuildpath {}] {} {}
+    set body {
+        # load the current copy of portutil instead of the installed one
+        source [file dirname [info script]]/../portutil.tcl
+        package require port
+        
+        depends_lib port:foo port:bar port:blah
+        depends_lib-delete port:blah port:bar
+        array get PortInfo
+    }
+    if {[catch {$workername eval $body} result]} {
+        interp delete $workername
+        error $result $::errorInfo $::errorCode
+    } else {
+        interp delete $workername
+    }
+    array set temp $result
+    if {$temp(depends_lib) ne "port:foo"} {
+        error "depends_lib-delete did not delete properly"
+    }
+}
+
 proc test_touch {} {
     set root "/tmp/macports-portutil-touch"
     file delete -force $root

Modified: branches/release_1_4/base/tests/test/trace/Makefile
===================================================================
--- branches/release_1_4/base/tests/test/trace/Makefile	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/tests/test/trace/Makefile	2007-05-17 01:10:15 UTC (rev 25263)
@@ -15,7 +15,11 @@
 	@rm -f create-trace-modenv
 	@rm -rf mkdir-trace
 	@rm -f /tmp/hello-trace
+	@rm -f link-trace
+	@ln -s /usr/include/unistd.h /tmp/link-trace2
 	@PORTSRC=$(PORTSRC) $(bindir)/port -t test > output 2>&1 || (cat output; exit 1)
+	@rm -f link-trace
+	@rm -f /tmp/link-trace2
 	@rm -f delete-trace
 	@rm -f rename-trace
 	@rm -f rename-new-trace

Modified: branches/release_1_4/base/tests/test/trace/Portfile
===================================================================
--- branches/release_1_4/base/tests/test/trace/Portfile	2007-05-17 01:06:17 UTC (rev 25262)
+++ branches/release_1_4/base/tests/test/trace/Portfile	2007-05-17 01:10:15 UTC (rev 25263)
@@ -25,6 +25,8 @@
 	catch {system "rm delete-trace"}
 	system "touch /tmp/hello-trace"
 	system "rm /tmp/hello-trace"
+	system "ln -s /usr/include/ link-trace"
+	system "rm /tmp/link-trace2"
 	catch {system "mkdir mkdir-trace"}
 	catch {system "rmdir rmdir-trace"}
 	catch {system "mv rename-trace rename-new-trace"}

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20070516/1ac82809/attachment.html


More information about the macports-changes mailing list