[110016] trunk/base/src/macports1.0/macports.tcl

cal at macports.org cal at macports.org
Sat Aug 24 09:38:17 PDT 2013


Revision: 110016
          https://trac.macports.org/changeset/110016
Author:   cal at macports.org
Date:     2013-08-24 09:38:17 -0700 (Sat, 24 Aug 2013)
Log Message:
-----------
macports1.0: restore ability to install from a remote URL (binary archive or tarball of the port dir) removed in r109659

Adds more documentation, cleanup code and progress information for the download.

Revision Links:
--------------
    https://trac.macports.org/changeset/109659

Modified Paths:
--------------
    trunk/base/src/macports1.0/macports.tcl

Modified: trunk/base/src/macports1.0/macports.tcl
===================================================================
--- trunk/base/src/macports1.0/macports.tcl	2013-08-24 16:35:40 UTC (rev 110015)
+++ trunk/base/src/macports1.0/macports.tcl	2013-08-24 16:38:17 UTC (rev 110016)
@@ -1393,30 +1393,53 @@
     }
 }
 
+##
+# Extracts a Portfile from a tarball pointed to by the given \a url to a path
+# in \c $portdbpath and returns its path.
+#
+# @param url URL pointing to a tarball containing either a file named \c
+#            Portfile at the root level -- in which case the tarball is
+#            extracted completely, --  or a file named \c +CONTENTS at the root
+#            level (i.e., the archive is a valid MacPorts binary archive), in
+#            which case the Portfile is extracted from the file \c +PORTFILE
+#            and put in a separate directory.
+# @param local one, if the URL is local, zero otherwise
+# @return a path to a directory containing the Portfile, or an error code
 proc macports::fetch_port {url {local 0}} {
-    global macports::portdbpath
+    global macports::portdbpath macports::ui_prefix macports::portverbose
+
     set fetchdir [file join $portdbpath portdirs]
     file mkdir $fetchdir
     if {![file writable $fetchdir]} {
         return -code error "Port remote fetch failed: You do not have permission to write to $fetchdir"
     }
+
     if {$local} {
         set fetchfile $url
     } else {
+        ui_msg "$macports::ui_prefix Fetching port $url"
         set fetchfile [file tail $url]
-        if {[catch {curl fetch $url [file join $fetchdir $fetchfile]} result]} {
+        set verboseflag {}
+        if {$macports::portverbose eq {yes}} {
+            set verboseflag -v
+        }
+        if {[catch {eval curl fetch $verboseflag {$url} {[file join $fetchdir $fetchfile]}} result]} {
             return -code error "Port remote fetch failed: $result"
         }
     }
+
     set oldpwd [pwd]
     cd $fetchdir
-    # check if this is a binary archive or just the port dir
+
+    # check if this is a binary archive or just the port dir by checking
+    # whether the file "+CONTENTS" exists.
     set tarcmd [findBinary tar $macports::autoconf::tar_path]
     set tarflags [get_tar_flags [file extension $fetchfile]]
     set qflag $macports::autoconf::tar_q
     set cmdline "$tarcmd ${tarflags}${qflag}xOf \"$fetchfile\" +CONTENTS"
     ui_debug $cmdline
     if {![catch {set contents [eval exec $cmdline]}]} {
+        # the file is probably a valid binary archive
         set binary 1
         ui_debug "getting port name from binary archive"
         # get the portname from the contents file
@@ -1427,9 +1450,13 @@
             }
         }
         ui_debug "port name is '$portname'"
+
+        # create a correctly-named directory and put the Portfile there
         file mkdir $portname
         cd $portname
     } else {
+        # the file is not a valid binary archive, assume it's an archive just
+        # containing Portfile and the files directory
         set binary 0
         set portname [file rootname $fetchfile]
     }
@@ -1443,9 +1470,16 @@
     }
     ui_debug $cmdline
     if {[catch {eval exec $cmdline} result]} {
+        # clean up the archive, we don't need it anymore
+        file delete [file join $fetchdir $fetchfile]
+
+        cd $oldpwd
         return -code error "Port extract failed: $result"
     }
 
+    # clean up the archive, we don't need it anymore
+    file delete [file join $fetchdir $fetchfile]
+
     cd $oldpwd
     return [file join $fetchdir $portname]
 }
@@ -1459,20 +1493,43 @@
 }
 
 ##
-# Return the directory where the port identified by the given \c url is
-# located. This used to be called with remote URLs, but this feature (and
-# a formerly existing second parameter) has been removed in MacPorts 2.3. Only
-# called with file:// port URLs at the moment.
+# Return the directory where the port identified by the given \a url is
+# located. Can be called with either local paths (starting with \c file://), or
+# local or remote URLs pointing to a tarball that will be extracted.
 #
 # @param url URL identifying the port to be installed
 # @return normalized path to the port's directory, or error when called with an
-#         unsupported protocl
+#         unsupported protocol, or if the tarball pointed to by \a url didn't
+#         contain a Portfile.
 proc macports::getportdir {url} {
+    global macports::extracted_portdirs
+
     set protocol [macports::getprotocol $url]
     switch -- $protocol {
         file {
-            return [file normalize [string range $url [expr {[string length $protocol] + 3}] end]]
+            set path [file normalize [string range $url [expr {[string length $protocol] + 3}] end]]
+            if {![file isfile $path]} {
+                # the URL points to a local directory
+                return $path
+            } else {
+                # the URL points to a local tarball that (hopefully) contains a Portfile
+                # create a local dir for the extracted port, but only once
+                if {![info exists macports::extracted_portdirs($url)]} {
+                    set macports::extracted_portdirs($url) [macports::fetch_port $path 1]
+                }
+                return $macports::extracted_portdirs($url)
+            }
         }
+        https -
+        http -
+        ftp {
+            # the URL points to a remote tarball that (hopefully) contains a Portfile
+            # create a local dir for the extracted port, but only once
+            if {![info exists macports::extracted_portdirs($url)]} {
+                set macports::extracted_portdirs($url) [macports::fetch_port $url 0]
+            }
+            return $macports::extracted_portdirs($url)
+        }
         default {
             return -code error "Unsupported protocol $protocol"
         }
@@ -1535,12 +1592,27 @@
 }
 
 
-# mportopen
-# Opens a MacPorts portfile specified by a URL.  The Portfile is
-# opened with the given list of options and variations.  The result
-# of this function should be treated as an opaque handle to a
-# MacPorts Portfile.
-
+##
+# Opens a MacPorts portfile specified by a URL. The URL can be local (starting
+# with file://), or remote (http, https, or ftp). In the local case, the URL
+# can point to a directory containing a Portfile, or to a tarball in the format
+# detailed below. In the remote case, the URL must point to a tarball. The
+# Portfile is opened with the given list of options and variations. The result
+# of this function should be treated as an opaque handle to a MacPorts
+# Portfile.
+#
+# @param porturl URL to the directory of the port to be opened. Can the path to
+#                a local directory, or an URL (both remote and local) pointing
+#                to a tarball that
+#                \li either contains a \c Portfile and possible a \c files
+#                    directory, or
+#                \li is a MacPorts binary archive, where the Portfile is in
+#                    a file called \c +PORTFILE.
+# @param options an optional array (in list format) of options
+# @param variations an optional array (ist list format) of variations, passed
+#                   to \c eval_variants after running the Portfile
+# @param nocache a non-empty string, if port information caching should be
+#                avoided.
 proc mportopen {porturl {options {}} {variations {}} {nocache {}}} {
     global macports::portdbpath macports::portconf macports::open_mports auto_path
 
@@ -1560,6 +1632,7 @@
         return $mport
     }
 
+    # Will download if remote and extract if tarball.
     set portpath [macports::getportdir $porturl]
     ui_debug "Changing to port directory: $portpath"
     cd $portpath
@@ -2863,7 +2936,7 @@
 }
 
 proc mportclose {mport} {
-    global macports::open_mports
+    global macports::open_mports macports::extracted_portdirs
     set refcnt [ditem_key $mport refcnt]
     incr refcnt -1
     ditem_key $mport refcnt $refcnt
@@ -2874,6 +2947,18 @@
         if {[interp exists $workername]} {
             interp delete $workername
         }
+        set porturl [ditem_key $mport porturl]
+        if {[info exists macports::extracted_portdirs($porturl)]} {
+            # TODO port.tcl calls mportopen multiple times on the same port to
+            # determine a number of attributes and will close the port after
+            # each call. $macports::extracted_portdirs($porturl) will however
+            # stay set, which means it will not be extracted twice. We could
+            # (1) unset $macports::extracted_portdirs($porturl), which would
+            # lead to downloading the port multiple times, or (2) fix the
+            # port.tcl code to delay mportclose until the end.
+            #ui_debug "Removing temporary port directory $macports::extracted_portdirs($porturl)"
+            #file delete -force $macports::extracted_portdirs($porturl)
+        }
         ditem_delete $mport
     }
 }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20130824/0685fef7/attachment.html>


More information about the macports-changes mailing list