Changeset 77511


Ignore:
Timestamp:
Apr 2, 2011, 1:47:03 AM (9 years ago)
Author:
jmr@…
Message:

manual merge/rewrite of images-and-archives branch, integrated with archivefetch and registry2.0

Location:
trunk/base
Files:
1 added
1 deleted
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/base/Makefile.in

    r71039 r77511  
    3939ifeq ($(DESTDIR),)
    4040# Add [default] tag to the central MacPorts repository, if it isn't already
    41         $(TCLSH) src/upgrade_sources_conf_default.tcl ${prefix}
     41        $(TCLSH) src/upgrade_sources_conf_default.tcl "${prefix}"
    4242# Remove duplicate entries from the dependency map (could occur with 1.6 and earlier):
    4343        $(TCLSH) src/dep_map_clean.tcl "${macports_tcl_dir}"
     44# Convert image directories (and direct mode installs) to image archives
     45        $(TCLSH) src/images_to_archives.tcl "${macports_tcl_dir}"
    4446endif
    4547        @echo ""; echo "Congratulations, you have successfully installed the MacPorts system. To get the Portfiles and update the system, add ${prefix}/bin to your PATH and run:"; echo ""
  • trunk/base/doc/macports.conf.5

    r73696 r77511  
    6868.Ic Default:
    6969sqlite
    70 .It Va portinstalltype
    71 Sets the mode in which ports are installed by MacPorts. Supported values are 'direct' or 'image'.
    72 The 'direct' mode is often used on systems that do not support 'image' due to limitations in their
    73 installed version of Tcl. In 'direct' mode ports are installed directly into '${prefix}' and only
    74 one flavor of a port can be installed at any given time. In 'image' mode multiple flavors of a port
    75 (i.e., different versions and/or any possible combination of its variants) can be installed concurrently
    76 into '${portdbpath}/software/${portname}' and only one can be "activated" onto '${prefix}' via soft or
    77 hard links from the former to the latter.
    78 .br
    79 .Ic Default:
    80 image
    8170.It Va applications_dir
    8271Directory containing Applications installed from ports.
     
    10392.Ic Default:
    10493${prefix}/etc/macports/variants.conf
    105 .It Va portarchivemode
    106 Key governing the creation of binary archives of installed ports for installation/reinstallation ease.
    107 .br
    108 .Ic Default:
    109 yes
    110 .It Va portarchivepath
    111 Location to store ports' binary archive files when archive mode is active.
    112 .br
    113 .Ic Default:
    114 ${portdbpath}/packages
    11594.It Va portarchivetype
    116 Colon or comma separated, space free list of supported formats of archives to create or read from when
    117 \&'${archivemode}' is set to 'yes'. Use of multiple types will cause archive creation to build all the
    118 specified types in one step. Unarchive uses multiple types as a search list to locate any existing archive,
    119 with the first found match being used.
     95Format of archives in which to store port images. This controls both the type
     96of archive created locally after building from source, and the type to request
     97from remote servers. Changing this will not affect the usability of already
     98installed archives; they can be of any supported type.
    12099.br
    121100Supported types are: tgz, tar, tbz, tbz2, tlz, txz, xar, zip, cpgz, cpio
    122101.br
    123102.Ic Default:
    124 tgz
     103tbz2
    125104.It Va configureccache
    126105Use ccache (C/C++ compiler cache). Requires that ccache has been installed.
  • trunk/base/doc/macports.conf.in

    r71844 r77511  
    1414# default is sqlite, flat is legacy
    1515#portdbformat           sqlite
    16 
    17 # Type of installation to do for ports, "direct" or "image".  See macports.conf(5) and online documentation.
    18 #portinstalltype                image
    1916
    2017# PATH settings that are used for external tools (configure, make, etc.) while installing ports. The default
     
    3734variants_conf           @MPCONFIGDIR_EXPANDED@/variants.conf
    3835
    39 # Create and use binary archive packages for installation/reinstallation ease
    40 #portarchivemode                no
    41 
    42 # Where to store/retrieve ports binary archive files
    43 #portarchivepath                @localstatedir_expanded@/macports/packages
    44 
    45 # Type of binary archive packages to create when using archive mode
     36# Type of archives to use for port images
    4637#
    47 # Note: Multiple types ARE allowed and must be a colon or comma
    48 # separated list of choices (NO spaces). Use of multiple types will
    49 # cause archive creation to build all the specified types in one step.
    50 # Unarchive uses multiple types as a search list to locate the archive,
    51 # first archive to match one of the specified types in order is used.
    52 #
    53 # Supported types: tgz (default), tar, tbz, tbz2, tlz, txz, xar, zip, cpgz, cpio
    54 #portarchivetype                tgz
     38# Supported types: tgz, tar, tbz, tbz2 (default), tlz, txz, xar, zip, cpgz, cpio
     39#portarchivetype                tbz2
    5540
    5641# CPU architecture to compile for. Defaults to i386 or ppc on Mac OS X 10.5
  • trunk/base/doc/port.1

    r76676 r77511  
    250250honor state files older than Portfile
    251251.It Fl s
    252 source-only mode (build and install from source, ignore all binary archives, do not create/recreate binary archives) (only applies when archive mode is enabled)
     252source-only mode (build and install from source, do not attempt to fetch binary archives)
    253253.It Fl b
    254 binary-only mode (build and install from binary archives, ignore source, abort if no archive present; do not create/recreate binary archives from source) (only applies when archive mode is enabled)
     254binary-only mode (build and install from binary archives, ignore source, abort if no archive available)
    255255.It Fl c
    256256autoclean mode (execute clean after install)
     
    472472To remove the distribution files (tarballs, etc), specify
    473473.Fl -dist .
    474 To remove the archive(s) for the current version of a port, pass
    475 .Fl -archive .
    476 To remove the work files, distribution files and archives, pass
     474To remove the work files, distribution files and logs, pass
    477475.Fl -all .
    478476To remove log files for certain port, pass
     
    481479.Pp
    482480.Dl "port clean --dist vim"
    483 .Dl "port clean --archive vim"
    484481.Dl "port clean --logs vim"
    485482.Pp
    486 To remove only certain version(s) of a port's archives (
    487 .Ar version
    488 is any valid UNIX glob pattern), you can use:
    489 .Pp
    490 .Dl "port clean --archive vim 6.2.114"
    491 .Pp
    492 or:
    493 .Pp
    494 .Dl "port clean --archive vim '6.*'"
    495483.Ss log
    496484Parses and shows log files for
     
    606594An alias for
    607595.Ic edit .
    608 .Ss unarchive
    609 Unpack the port from a pre-built binary archive. When archive mode is enabled, this command is called automatically, prior to
    610 .Ar fetch ,
    611 to check for an existing binary archive to unpack. If found, it is unpacked and all stages up to
    612 .Ar install
    613 are then skipped.
    614596.Ss fetch
    615597Fetches the distribution files required to build
     
    645627To nitpick about whitespace and patchfile names, use
    646628.Fl -nitpick .
    647 .Ss archive
    648 Archive the port for a later
    649 .Ar unarchive .
    650 When archive mode is enabled, binary archives will be created automatically whenever an
    651 .Ar install
    652 is performed, or when the
    653 .Ar archive
    654 target is called explicitly.
    655629.Ss distcheck
    656630Check if the distfiles haven't changed and can be fetched.
  • trunk/base/doc/porthier.7

    r73668 r77511  
    9999.It Pa distfiles/
    100100Holds the distfiles of the fetched ports
    101 .It Pa packages/
    102 Contains archives (packages) of installed ports
    103101.It Pa receipts/
    104102Holds the registry information and receipts for the installed ports
    105103.It Pa software/
    106 In Image-mode (which is default) Holds the installed files. These
    107 are linked to ${prefix}.
     104Holds compressed images of the installed ports. These
     105are extracted to ${prefix} when activated.
    108106.It Pa sources/
    109107Holds the sources of both the porttree (the Portfiles) and the
  • trunk/base/src/macports1.0/macports.tcl

    r74924 r77511  
    4242    variable bootstrap_options "\
    4343        portdbpath libpath binpath auto_path extra_env sources_conf prefix portdbformat \
    44         portinstalltype portarchivemode portarchivepath portarchivetype portautoclean \
     44        portarchivetype portautoclean \
    4545        porttrace portverbose keeplogs destroot_umask variants_conf rsync_server rsync_options \
    4646        rsync_dir startupitem_type place_worksymlink xcodeversion xcodebuildcmd \
     
    5252    variable portinterp_options "\
    5353        portdbpath porturl portpath portbuildpath auto_path prefix prefix_frozen portsharepath \
    54         registry.path registry.format registry.installtype portarchivemode portarchivepath \
     54        registry.path registry.format \
    5555        portarchivetype archivefetch_pubkeys portautoclean porttrace keeplogs portverbose destroot_umask \
    5656        rsync_server rsync_options rsync_dir startupitem_type place_worksymlink macportsuser \
     
    451451    global macports::macportsuser
    452452    global macports::prefix_frozen
    453     global macports::registry.installtype
    454453    global macports::rsync_dir
    455454    global macports::rsync_options
     
    654653    }
    655654
    656     # Installation type, whether to use port "images" or install "direct"
    657     if {[info exists portinstalltype]} {
    658         set registry.installtype $portinstalltype
    659     } else {
    660         set registry.installtype image
    661     }
    662 
    663655    # Autoclean mode, whether to automatically call clean after "install"
    664656    if {![info exists portautoclean]} {
     
    705697    }
    706698
    707     # Archive mode, whether to create/use binary archive packages
    708     if {![info exists portarchivemode]} {
    709         set macports::portarchivemode "no"
    710         global macports::portarchivemode
    711     }
    712 
    713     # Archive path, where to store/retrieve binary archive packages
    714     if {![info exists portarchivepath]} {
    715         set macports::portarchivepath [file join $portdbpath packages]
    716         global macports::portarchivepath
    717     }
    718     if {$portarchivemode == "yes"} {
    719         if {![file exists $portarchivepath] && [catch {file mkdir $portarchivepath} result]} {
    720             ui_warn "portarchivepath $portarchivepath does not exist and could not be created; disabling archive mode"
    721             set portarchivemode no
    722         } elseif {![file isdirectory $portarchivepath]} {
    723             return -code error "Archive dir $portarchivepath is not a directory. Please create the directory or reconfigure portarchivepath"
    724         }
    725     }
    726 
    727699    # Archive type, what type of binary archive to use (CPIO, gzipped
    728700    # CPIO, XAR, etc.)
     701    global macports::portarchivetype
    729702    if {![info exists portarchivetype]} {
    730         set macports::portarchivetype "tgz"
    731         global macports::portarchivetype
    732     }
    733     # Convert archive type to a list for multi-archive support, colon or
    734     # comma separators indicates to use multiple archive formats
    735     # (reading and writing)
    736     set macports::portarchivetype [split $portarchivetype {:,}]
     703        set macports::portarchivetype "tbz2"
     704    } else {
     705        set macports::portarchivetype [lindex $portarchivetype 0]
     706    }
    737707
    738708    # Set rync options
     
    1004974
    1005975proc macports::worker_init {workername portpath porturl portbuildpath options variations} {
    1006     global macports::portinterp_options macports::portinterp_deferred_options registry.installtype
     976    global macports::portinterp_options macports::portinterp_deferred_options
    1007977
    1008978    # Hide any Tcl commands that should be inaccessible to port1.0 and Portfiles
     
    10751045    $workername alias registry_register_deps registry::register_dependencies
    10761046    $workername alias registry_fileinfo_for_index registry::fileinfo_for_index
     1047    $workername alias registry_fileinfo_for_file registry::fileinfo_for_file
    10771048    $workername alias registry_bulk_register_files registry::register_bulk_files
    10781049    $workername alias registry_active registry::active
     
    11161087        $workername eval set variations($var) $val
    11171088    }
    1118 
    1119     if { [info exists registry.installtype] } {
    1120         $workername eval set installtype ${registry.installtype}
    1121     }
    11221089}
    11231090
     
    11591126
    11601127proc macports::fetch_port {url} {
    1161     global macports::portdbpath tcl_platform
     1128    global macports::portdbpath
    11621129    set fetchdir [file join $portdbpath portdirs]
    11631130    set fetchfile [file tail $url]
     
    14721439}
    14731440
    1474 # Determine if a port is active (only for image mode)
     1441# Determine if a port is active
    14751442proc _mportactive {mport} {
    14761443    set workername [ditem_key $mport workername]
     
    14901457}
    14911458
    1492 # Determine if the named port is active (only for image mode)
     1459# Determine if the named port is active
    14931460proc _portnameactive {portname} {
    14941461    if {[catch {set reslist [registry::active $portname]}]} {
     
    15021469
    15031470# Determine if some depspec is satisfied or if the given port is installed
    1504 # (and active, if we're in image mode).
     1471# and active.
    15051472# We actually start with the registry (faster?)
    15061473#
     
    15101477    set portname [lindex [split $depspec :] end]
    15111478    ui_debug "Searching for dependency: $portname"
    1512     if {[string equal ${macports::registry.installtype} "image"]} {
    1513         set res [_portnameactive $portname]
    1514     } else {
    1515         set res [registry::entry_exists_for_name $portname]
    1516     }
     1479    set res [_portnameactive $portname]
    15171480    if {$res != 0} {
    15181481        ui_debug "Found Dependency: receipt exists for $portname"
     
    15981561# Execute the specified target of the given mport.
    15991562proc mportexec {mport target} {
    1600     global macports::registry.installtype
    1601 
    16021563    set workername [ditem_key $mport workername]
    16031564
     
    16611622
    16621623        # install them
    1663         # xxx: as with below, this is ugly.  and deps need to be fixed to
    1664         # understand Port Images before this can get prettier
    1665         if { [string equal ${macports::registry.installtype} "image"] } {
    1666             set result [dlist_eval $dlist _mportactive [list _mportexec "activate"]]
    1667         } else {
    1668             set result [dlist_eval $dlist _mportinstalled [list _mportexec "activate"]]
    1669         }
     1624        set result [dlist_eval $dlist _mportactive [list _mportexec "activate"]]
     1625
    16701626        registry::exclusive_unlock
    16711627
     
    17271683    set depends_skip_archcheck [_mportkey $mport depends_skip_archcheck]
    17281684
    1729     if {[string equal ${macports::registry.installtype} "image"]} {
    1730         set test _portnameactive
    1731     } else {
    1732         set test registry::entry_exists_for_name
    1733     }
     1685    set test _portnameactive
    17341686
    17351687    foreach deptype $deptypes {
     
    18051757# get the archs with which the active version of portname is installed
    18061758proc macports::_get_registry_archs {portname} {
    1807     if {[string equal ${macports::registry.installtype} "image"]} {
    1808         set ilist [registry::active $portname]
    1809     } else {
    1810         set ilist [registry::installed $portname]
    1811     }
     1759    set ilist [registry::active $portname]
    18121760    set i [lindex $ilist 0]
    18131761    set regref [registry::open_entry [lindex $i 0] [lindex $i 1] [lindex $i 2] [lindex $i 3] [lindex $i 5]]
     
    27092657        destroot -
    27102658        install -
    2711         archive -
    27122659        activate -
    27132660        dmg -
     
    27342681        srpm        -
    27352682        destroot    { return "depends_fetch depends_extract depends_build depends_lib depends_run" }
    2736         archive     -
    27372683        dmg         -
    27382684        pkg         -
     
    29222868# main internal upgrade procedure
    29232869proc macports::_upgrade {portname dspec variationslist optionslist {depscachename ""}} {
    2924     global macports::registry.installtype
    2925     global macports::portarchivemode
    29262870    global macports::global_variations
    29272871    array set options $optionslist
     
    32533197
    32543198    if {$will_build} {
    3255         # build or unarchive version_in_tree
    3256         if {0 == [string compare "yes" ${macports::portarchivemode}]} {
    3257             set upgrade_action "archive"
    3258         } else {
    3259             set upgrade_action "destroot"
    3260         }
    3261         if {[catch {set result [mportexec $workername $upgrade_action]} result] || $result != 0} {
     3199        # install version_in_tree (but don't activate yet)
     3200        if {[catch {set result [mportexec $workername install]} result] || $result != 0} {
    32623201            if {[info exists ::errorInfo]} {
    32633202                ui_debug "$::errorInfo"
     
    32693208    }
    32703209
    3271     # always uninstall old port in direct mode
    32723210    global macports::registry.format
    3273     if { 0 != [string compare "image" ${macports::registry.installtype}] } {
    3274         # uninstall old
    3275         ui_debug "Uninstalling $portname ${version_installed}_${revision_installed}${variant_installed}"
     3211    # are we installing an existing version due to force or epoch override?
     3212    if {[registry::entry_exists $newname $version_in_tree $revision_in_tree $portinfo(canonical_active_variants)]
     3213        && ([info exists options(ports_upgrade_force)] || $build_override == 1)} {
     3214         ui_debug "Uninstalling $newname ${version_in_tree}_${revision_in_tree}$portinfo(canonical_active_variants)"
    32763215        # we have to force the uninstall in case of dependents
    32773216        set force_cur [info exists options(ports_force)]
    32783217        set options(ports_force) yes
     3218        set existing_epoch [lindex [lindex [registry::installed $newname ${version_in_tree}_${revision_in_tree}$portinfo(canonical_active_variants)] 0] 5]
     3219        set newregref [registry::open_entry $newname $version_in_tree $revision_in_tree $portinfo(canonical_active_variants) $existing_epoch]
    32793220        if {$is_dryrun eq "yes"} {
    3280             ui_msg "Skipping uninstall $portname @${version_installed}_${revision_installed}${variant_installed} (dry run)"
    3281         } elseif {(${registry.format} != "receipt_sqlite" || ![registry::run_target $regref uninstall [array get options]])
    3282                   && [catch {registry_uninstall::uninstall $portname ${version_installed}_${revision_installed}${variant_installed} [array get options]} result]} {
     3221            ui_msg "Skipping uninstall $newname @${version_in_tree}_${revision_in_tree}$portinfo(canonical_active_variants) (dry run)"
     3222        } elseif {!(${registry.format} == "receipt_sqlite" && [registry::run_target $newregref uninstall [array get options]])
     3223                  && [catch {registry_uninstall::uninstall $newname ${version_in_tree}_${revision_in_tree}$portinfo(canonical_active_variants) [array get options]} result]} {
    32833224            global errorInfo
    32843225            ui_debug "$errorInfo"
    3285             ui_error "Uninstall $portname ${version_installed}_${revision_installed}${variant_installed} failed: $result"
     3226            ui_error "Uninstall $newname ${version_in_tree}_${revision_in_tree}$portinfo(canonical_active_variants) failed: $result"
    32863227            catch {mportclose $workername}
    32873228            return 1
     
    32903231            unset options(ports_force)
    32913232        }
    3292     } else {
    3293         # are we installing an existing version due to force or epoch override?
    3294         if {[registry::entry_exists $newname $version_in_tree $revision_in_tree $portinfo(canonical_active_variants)]
    3295             && ([info exists options(ports_upgrade_force)] || $build_override == 1)} {
    3296              ui_debug "Uninstalling $newname ${version_in_tree}_${revision_in_tree}$portinfo(canonical_active_variants)"
    3297             # we have to force the uninstall in case of dependents
    3298             set force_cur [info exists options(ports_force)]
    3299             set options(ports_force) yes
    3300             set existing_epoch [lindex [lindex [registry::installed $newname ${version_in_tree}_${revision_in_tree}$portinfo(canonical_active_variants)] 0] 5]
    3301             set newregref [registry::open_entry $newname $version_in_tree $revision_in_tree $portinfo(canonical_active_variants) $existing_epoch]
    3302             if {$is_dryrun eq "yes"} {
    3303                 ui_msg "Skipping uninstall $newname @${version_in_tree}_${revision_in_tree}$portinfo(canonical_active_variants) (dry run)"
    3304             } elseif {!(${registry.format} == "receipt_sqlite" && [registry::run_target $newregref uninstall [array get options]])
    3305                       && [catch {registry_uninstall::uninstall $newname ${version_in_tree}_${revision_in_tree}$portinfo(canonical_active_variants) [array get options]} result]} {
    3306                 global errorInfo
    3307                 ui_debug "$errorInfo"
    3308                 ui_error "Uninstall $newname ${version_in_tree}_${revision_in_tree}$portinfo(canonical_active_variants) failed: $result"
    3309                 catch {mportclose $workername}
    3310                 return 1
    3311             }
    3312             if {!$force_cur} {
    3313                 unset options(ports_force)
    3314             }
    3315             if {$anyactive && $version_in_tree == $version_active && $revision_in_tree == $revision_active
    3316                 && $portinfo(canonical_active_variants) == $variant_active && $portname == $newname} {
    3317                 set anyactive no
    3318             }
    3319         }
    3320         if {$anyactive && $portname != $newname} {
    3321             # replaced_by in effect, deactivate the old port
    3322             # we have to force the deactivate in case of dependents
    3323             set force_cur [info exists options(ports_force)]
    3324             set options(ports_force) yes
    3325             if {$is_dryrun eq "yes"} {
    3326                 ui_msg "Skipping deactivate $portname @${version_active}_${revision_active}${variant_active} (dry run)"
    3327             } elseif {![catch {registry::active $portname}] &&
    3328                       !(${registry.format} == "receipt_sqlite" && [registry::run_target $regref deactivate [array get options]])
    3329                       && [catch {portimage::deactivate $portname ${version_active}_${revision_active}${variant_active} [array get options]} result]} {
    3330                 global errorInfo
    3331                 ui_debug "$errorInfo"
    3332                 ui_error "Deactivating $portname @${version_active}_${revision_active}${variant_active} failed: $result"
    3333                 catch {mportclose $workername}
    3334                 return 1
    3335             }
    3336             if {!$force_cur} {
    3337                 unset options(ports_force)
    3338             }
     3233        if {$anyactive && $version_in_tree == $version_active && $revision_in_tree == $revision_active
     3234            && $portinfo(canonical_active_variants) == $variant_active && $portname == $newname} {
    33393235            set anyactive no
    33403236        }
    3341         if {[info exists options(port_uninstall_old)] && $portname == $newname} {
    3342             # uninstalling now could fail due to dependents when not forced,
    3343             # because the new version is not installed
    3344             set uninstall_later yes
    3345         }
     3237    }
     3238    if {$anyactive && $portname != $newname} {
     3239        # replaced_by in effect, deactivate the old port
     3240        # we have to force the deactivate in case of dependents
     3241        set force_cur [info exists options(ports_force)]
     3242        set options(ports_force) yes
     3243        if {$is_dryrun eq "yes"} {
     3244            ui_msg "Skipping deactivate $portname @${version_active}_${revision_active}${variant_active} (dry run)"
     3245        } elseif {![catch {registry::active $portname}] &&
     3246                  !(${registry.format} == "receipt_sqlite" && [registry::run_target $regref deactivate [array get options]])
     3247                  && [catch {portimage::deactivate $portname ${version_active}_${revision_active}${variant_active} [array get options]} result]} {
     3248            global errorInfo
     3249            ui_debug "$errorInfo"
     3250            ui_error "Deactivating $portname @${version_active}_${revision_active}${variant_active} failed: $result"
     3251            catch {mportclose $workername}
     3252            return 1
     3253        }
     3254        if {!$force_cur} {
     3255            unset options(ports_force)
     3256        }
     3257        set anyactive no
     3258    }
     3259    if {[info exists options(port_uninstall_old)] && $portname == $newname} {
     3260        # uninstalling now could fail due to dependents when not forced,
     3261        # because the new version is not installed
     3262        set uninstall_later yes
    33463263    }
    33473264
     
    35853502    return
    35863503}
     3504
     3505# Return a good temporary directory to use; /tmp if TMPDIR is not set
     3506# in the environment
     3507proc macports::gettmpdir {args} {
     3508    global env
     3509
     3510    if {[info exists env(TMPDIR)]} {
     3511        return $env(TMPDIR)
     3512    } else {
     3513        return "/tmp"
     3514    }
     3515}
  • trunk/base/src/macports1.0/macports_autoconf.tcl.in

    r61313 r77511  
    3333
    3434namespace eval macports::autoconf {
     35    variable bzip2_path "@BZIP2@"
    3536    variable chown_path "@CHOWN@"
    3637    variable gzip_path "@GZIP@"
     
    4041    variable macportsuser "@RUNUSR@"
    4142    variable open_path "@OPEN@"
     43    variable pax_path "@PAX@"
    4244    variable rsync_path "@RSYNC@"
    4345    variable tar_command "@TAR_CMD@"
    4446    variable tar_path "@TAR@"
     47    variable unzip_path "@UNZIP@"
     48    variable xar_path "@XAR@"
    4549}
  • trunk/base/src/package1.0/Makefile

    r66844 r77511  
    22
    33SRCS=   package.tcl portdmg.tcl portmdmg.tcl portmpkg.tcl portpkg.tcl portportpkg.tcl \
    4         portrpm.tcl portsrpm.tcl portdpkg.tcl portunarchive.tcl portarchive.tcl \
     4        portrpm.tcl portsrpm.tcl portdpkg.tcl portunarchive.tcl \
    55        portarchivefetch.tcl
    66
  • trunk/base/src/package1.0/package.tcl

    r64816 r77511  
    4343package require portarchivefetch 1.0
    4444package require portunarchive 1.0
    45 package require portarchive 1.0
  • trunk/base/src/package1.0/portarchivefetch.tcl

    r69043 r77511  
    6363default archive_sites.listfile {"archive_sites.tcl"}
    6464default archive_sites.listpath {"port1.0/fetch"}
    65 default archive.subdir {[portarchivefetch::get_archive_subdir]}
    6665
    6766set_ui_prefix
    68 
    69 proc portarchivefetch::get_archive_subdir {} {
    70     set archs [get_canonical_archs]
    71     if {[llength $archs] > 1} {
    72         return [file join [option os.platform]_[option os.major] "universal" [option name]]
    73     } else {
    74         return [file join [option os.platform]_[option os.major] $archs [option name]]
    75     }
    76 }
    7767
    7868# Checks possible archive files to assemble url lists for later fetching
    7969proc portarchivefetch::checkarchivefiles {urls} {
    80     global all_archive_files archivefetch.fulldestpath \
    81            portarchivepath name version revision portvariants archive_sites
     70    global all_archive_files archivefetch.fulldestpath portarchivetype \
     71           name version revision portvariants archive_sites
    8272    upvar $urls fetch_urls
    8373
    84     # Define archive directory, file, and path
    85     set archivefetch.fulldestpath [file join ${portarchivepath} [option archive.subdir]]
    86 
    87     set unsupported 0
    88     set found 0
    89     foreach archive.type [option portarchivetype] {
    90         if {[catch {archiveTypeIsSupported ${archive.type}} errmsg] == 0} {
    91             set archstring [join [get_canonical_archs] -]
    92             set archive.file "${name}-${version}_${revision}${portvariants}.${archstring}.${archive.type}"
    93             set archive.path [file join ${archivefetch.fulldestpath} ${archive.file}]
    94             if {[file exists ${archive.path}]} {
    95                 set found 1
    96                 break
    97             } else {
    98                 lappend all_archive_files ${archive.file}
    99                 if {[info exists archive_sites]} {
    100                     lappend fetch_urls archive_sites ${archive.file}
    101                 }
    102             }
    103         } else {
    104             ui_debug "Skipping [string toupper ${archive.type}] archive: $errmsg"
    105             incr unsupported
    106         }
    107     }
    108     if {$found} {
    109         ui_debug "Found [string toupper ${archive.type}] archive: ${archive.path}"
     74    # Define archive directory path
     75    set archive.path [get_portimage_path]
     76    set archivefetch.fulldestpath [file dirname ${archive.path}]
     77
     78    # throws an error if unsupported
     79    archiveTypeIsSupported $portarchivetype
     80
     81    if {[file isfile ${archive.path}]} {
     82        ui_debug "Found archive: ${archive.path}"
    11083        set all_archive_files {}
    11184        set fetch_urls {}
    112     } elseif {[llength [option portarchivetype]] == $unsupported} {
    113         return -code error "Unable to fetch archive ($name) since specified archive types not supported"
     85    } else {
     86        set archive.file [file tail ${archive.path}]
     87        lappend all_archive_files ${archive.file}
     88        if {[info exists archive_sites]} {
     89            lappend fetch_urls archive_sites ${archive.file}
     90        }
    11491    }
    11592}
     
    134111# the listed url variable and associated archive file
    135112proc portarchivefetch::fetchfiles {args} {
    136     global portarchivepath archivefetch.fulldestpath UI_PREFIX
     113    global archivefetch.fulldestpath UI_PREFIX
    137114    global archivefetch.user archivefetch.password archivefetch.use_epsv \
    138115           archivefetch.ignore_sslcert
     
    150127        }
    151128    }
    152     set incoming_path [file join ${portarchivepath} incoming]
     129    set incoming_path [file join [option portdbpath] incoming]
    153130    if {![file isdirectory $incoming_path]} {
    154131        if {[catch {file mkdir $incoming_path} result]} {
     
    246223                }
    247224                file delete -force $signature
    248                 return 0
     225                set archive_exists 1
    249226            }
    250227        } else {
    251             return 0
    252         }
     228            set archive_exists 1
     229        }
     230    }
     231    if {[info exists archive_exists]} {
     232        # modify state file to skip remaining phases up to destroot
     233        global target_state_fd
     234        foreach target {fetch checksum extract patch configure build destroot} {
     235            write_statefile target "org.macports.${target}" $target_state_fd
     236        }
     237        return 0
    253238    }
    254239    if {[info exists ports_binary_only] && $ports_binary_only == "yes"} {
     
    261246# Initialize archivefetch target and call checkfiles.
    262247proc portarchivefetch::archivefetch_init {args} {
    263     if {[option portarchivemode] != "yes"} {
    264         return -code error "Archive mode is not enabled!"
    265     }
     248    return 0
    266249}
    267250
     
    283266    if {[info exists all_archive_files] && [llength $all_archive_files] > 0} {
    284267        # Fetch the files
    285         return [portarchivefetch::fetchfiles]
    286     } else {
    287         return 0
    288     }
    289 }
     268        portarchivefetch::fetchfiles
     269    }
     270    return 0
     271}
  • trunk/base/src/package1.0/portdpkg.tcl

    r51521 r77511  
    3838target_runtype ${org.macports.dpkg} always
    3939target_provides ${org.macports.dpkg} dpkg
    40 target_requires ${org.macports.dpkg} destroot
     40target_requires ${org.macports.dpkg} archivefetch unarchive destroot
    4141
    4242namespace eval portdpkg {
  • trunk/base/src/package1.0/portpkg.tcl

    r64816 r77511  
    3737target_runtype ${org.macports.pkg} always
    3838target_provides ${org.macports.pkg} pkg
    39 if {[option portarchivemode] == "yes"} {
    40     target_requires ${org.macports.pkg} archivefetch unarchive destroot
    41 } else {
    42     target_requires ${org.macports.pkg} destroot
    43 }
     39target_requires ${org.macports.pkg} archivefetch unarchive destroot
    4440
    4541namespace eval portpkg {
  • trunk/base/src/package1.0/portrpm.tcl

    r64531 r77511  
    3737target_runtype ${org.macports.rpm} always
    3838target_provides ${org.macports.rpm} rpm
    39 target_requires ${org.macports.rpm} destroot
     39target_requires ${org.macports.rpm} archivefetch unarchive destroot
    4040
    4141namespace eval portrpm {
  • trunk/base/src/package1.0/portunarchive.tcl

    r72236 r77511  
    5454default unarchive.post_args {}
    5555
    56 default unarchive.srcpath {${portarchivepath}}
    5756default unarchive.type {}
    5857default unarchive.file {}
    5958default unarchive.path {}
     59default unarchive.skip 0
    6060
    6161set_ui_prefix
    6262
    6363proc portunarchive::unarchive_init {args} {
    64     global UI_PREFIX target_state_fd workpath
    65     global ports_force ports_source_only ports_binary_only
    66     global name version revision portvariants portpath
    67     global unarchive.srcpath unarchive.type unarchive.file unarchive.path unarchive.fullsrcpath
    68 
    69     # Check mode in case archive called directly by user
    70     if {[option portarchivemode] != "yes"} {
    71         return -code error "Archive mode is not enabled!"
    72     }
    73 
    74     # Define archive directory, file, and path
    75     if {![string equal ${unarchive.srcpath} ${workpath}] && ![string equal ${unarchive.srcpath} ""]} {
    76         set unarchive.fullsrcpath [file join ${unarchive.srcpath} [option archive.subdir]]
    77     } else {
    78         set unarchive.fullsrcpath ${unarchive.srcpath}
    79     }
     64    global target_state_fd unarchive.skip \
     65           ports_force ports_source_only ports_binary_only \
     66           name version revision portvariants \
     67           unarchive.type unarchive.file unarchive.path
    8068
    8169    # Determine if unarchive should be skipped
     
    9482    } else {
    9583        set found 0
    96         set unsupported 0
    97         foreach unarchive.type [option portarchivetype] {
    98             if {[catch {archiveTypeIsSupported ${unarchive.type}} errmsg] == 0} {
    99                 set archstring [join [get_canonical_archs] -]
    100                 set unarchive.file "${name}-${version}_${revision}${portvariants}.${archstring}.${unarchive.type}"
    101                 set unarchive.path "[file join ${unarchive.fullsrcpath} ${unarchive.file}]"
    102                 if {[file isfile ${unarchive.path}]} {
    103                     set found 1
    104                     break
    105                 } else {
    106                     ui_debug "No [string toupper ${unarchive.type}] archive: ${unarchive.path}"
    107                 }
    108             } else {
    109                 ui_debug "Skipping [string toupper ${unarchive.type}] archive: $errmsg"
    110                 incr unsupported
     84        set rootname [file rootname [get_portimage_path]]
     85        foreach unarchive.type [supportedArchiveTypes] {
     86            set unarchive.path "${rootname}.${unarchive.type}"
     87            set unarchive.file [file tail ${unarchive.path}]
     88            if {[file isfile ${unarchive.path}]} {
     89                set found 1
     90                break
     91            } else {
     92                ui_debug "No [string toupper ${unarchive.type}] archive: ${unarchive.path}"
    11193            }
    11294        }
     
    11799                return -code error "Archive for ${name} ${version}_${revision}${portvariants} not found, required when binary-only is set!"
    118100            } else {
    119                 if {[llength [option portarchivetype]] == $unsupported} {
    120                     ui_debug "Skipping unarchive ($name) since specified archive types not supported"
    121                 } else {
    122                     ui_debug "Skipping unarchive ($name) since no archive found"
    123                 }
     101                ui_debug "Skipping unarchive ($name) since no suitable archive found"
    124102                set skipped 1
    125103            }
    126104        }
    127105    }
    128     # Skip unarchive target by setting state
    129     if {$skipped == 1} {
    130         write_statefile target "org.macports.unarchive" $target_state_fd
    131     }
     106    # Skip running the main body of this target
     107    set unarchive.skip $skipped
    132108
    133109    return 0
     
    135111
    136112proc portunarchive::unarchive_start {args} {
    137     global UI_PREFIX name version revision portvariants
    138     global unarchive.type
     113    global UI_PREFIX name version revision portvariants \
     114           unarchive.type unarchive.skip
     115
     116    if {${unarchive.skip}} {
     117        return 0
     118    }
    139119
    140120    if {[getuid] == 0 && [geteuid] != 0} {
     
    149129
    150130proc portunarchive::unarchive_command_setup {args} {
    151     global unarchive.env unarchive.cmd
    152     global unarchive.pre_args unarchive.args unarchive.post_args
    153     global unarchive.type unarchive.path
    154     global unarchive.pipe_cmd
    155     global os.platform os.version env
     131    global unarchive.env unarchive.cmd unarchive.pre_args unarchive.args \
     132           unarchive.post_args unarchive.type unarchive.path \
     133           unarchive.pipe_cmd os.platform os.version env
    156134
    157135    # Define appropriate unarchive command and options
     
    228206            }
    229207        }
    230         xar {
     208        xar|xpkg {
    231209            set xar "xar"
    232210            if {[catch {set xar [findBinary $xar ${portutil::autoconf::xar_path}]} errmsg] == 0} {
     
    265243
    266244proc portunarchive::unarchive_main {args} {
    267     global UI_PREFIX
    268     global unarchive.dir unarchive.file unarchive.pipe_cmd
     245    global UI_PREFIX unarchive.dir unarchive.file unarchive.pipe_cmd unarchive.skip
     246
     247    if {${unarchive.skip}} {
     248        return 0
     249    }
    269250
    270251    # Setup unarchive command
     
    288269
    289270proc portunarchive::unarchive_finish {args} {
    290     global UI_PREFIX target_state_fd unarchive.file name workpath destpath
     271    global UI_PREFIX target_state_fd unarchive.file name workpath destpath unarchive.skip
     272
     273    if {${unarchive.skip}} {
     274        return 0
     275    }
    291276
    292277    # Reset state file with archive version
  • trunk/base/src/port/port-help.tcl

    r70010 r77511  
    1414}
    1515
    16 set porthelp(archive) {
    17 Archive the given ports
    18 }
    19 
    2016set porthelp(archivefetch) {
    2117Fetch archive for the given ports
     
    4339Removes files associated with the given ports
    4440
    45 --archive     Removes created archives
    4641--dist        Removes downloaded distfiles
    4742--logs        Removes log files
     
    320315
    321316set porthelp(unarchive) {
    322 Unarchive the given ports
     317Unarchive the destroot of the given ports from installed images
    323318}
    324319
  • trunk/base/src/port/port.tcl

    r76418 r77511  
    716716
    717717proc get_outdated_ports {} {
    718     global macports::registry.installtype
    719     set is_image_mode [expr 0 == [string compare "image" ${macports::registry.installtype}]]
    720 
    721718    # Get the list of installed ports
    722719    set ilist {}
     
    742739
    743740            set is_active           [lindex $i 4]
    744             if { $is_active == 0 && $is_image_mode } continue
     741            if {$is_active == 0} continue
    745742
    746743            set installed_epoch     [lindex $i 5]
     
    21132110
    21142111        set ref [registry::open_entry $portname $version $revision $variants $epoch]
    2115         if { [string equal [registry::property_retrieve $ref installtype] "image"] } {
    2116             set imagedir [registry::property_retrieve $ref imagedir]
    2117             ui_notice "Port $portname ${version}_${revision}${variants} is installed as an image in:"
    2118             puts $imagedir
    2119         } else {
    2120             break_softcontinue "Port $portname is not installed as an image." 1 status
    2121         }
     2112        set imagedir [registry::property_retrieve $ref location]
     2113        ui_notice "Port $portname ${version}_${revision}${variants} is installed as an image in:"
     2114        puts $imagedir
    21222115    }
    21232116   
     
    29332926
    29342927proc action_outdated { action portlist opts } {
    2935     global macports::registry.installtype private_options
    2936     set is_image_mode [expr 0 == [string compare "image" ${macports::registry.installtype}]]
    2937 
     2928    global private_options
    29382929    set status 0
    29392930
     
    29772968
    29782969            set is_active [lindex $i 4]
    2979             if { $is_active == 0 && $is_image_mode } {
     2970            if {$is_active == 0} {
    29802971                continue
    29812972            }
     
    38283819    distfiles   [list action_target         [ACTION_ARGS_PORTS]] \
    38293820    \
    3830     archive     [list action_target         [ACTION_ARGS_PORTS]] \
    38313821    archivefetch [list action_target         [ACTION_ARGS_PORTS]] \
    38323822    unarchive   [list action_target         [ACTION_ARGS_PORTS]] \
     
    39003890    uninstall   {follow-dependents follow-dependencies no-exec}
    39013891    variants    {index}
    3902     clean       {all archive dist work logs}
     3892    clean       {all dist work logs}
    39033893    mirror      {new}
    39043894    lint        {nitpick}
  • trunk/base/src/port1.0/portactivate.tcl

    r70974 r77511  
    4141target_state ${org.macports.activate} no
    4242target_provides ${org.macports.activate} activate
    43 if {[option portarchivemode] == "yes"} {
    44     target_requires ${org.macports.activate} main archivefetch unarchive fetch checksum extract patch configure build destroot archive install
    45 } else {
    46     target_requires ${org.macports.activate} main fetch checksum extract patch configure build destroot install
    47 }
     43target_requires ${org.macports.activate} main archivefetch fetch checksum extract patch configure build destroot install
    4844target_prerun ${org.macports.activate} portactivate::activate_start
    4945
     
    5551
    5652proc portactivate::activate_start {args} {
    57     global prefix registry.installtype
    58     if { (![file writable $prefix] || ([getuid] == 0 && [geteuid] != 0)) && ${registry.installtype} == "image"} {
     53    global prefix
     54    if {![file writable $prefix] || ([getuid] == 0 && [geteuid] != 0)} {
    5955        # if install location is not writable, need root privileges
    6056        elevateToRoot "activate"
     
    6359
    6460proc portactivate::activate_main {args} {
    65     global env name version revision portvariants user_options PortInfo registry.installtype
     61    global env name version revision portvariants user_options PortInfo
    6662
    67     # skip the actual activation in direct mode (we still want the notes and the pre/post procs)
    68     if {${registry.installtype} == "image"} {
    69         registry_activate $name "${version}_${revision}${portvariants}" [array get user_options]
    70     }
     63    registry_activate $name "${version}_${revision}${portvariants}" [array get user_options]
    7164
    7265    # Display notes at the end of the activation phase.
  • trunk/base/src/port1.0/portclean.tcl

    r70974 r77511  
    5858proc portclean::clean_main {args} {
    5959    global UI_PREFIX
    60     global ports_clean_dist ports_clean_work ports_clean_archive ports_clean_logs
     60    global ports_clean_dist ports_clean_work ports_clean_logs
    6161    global ports_clean_all keeplogs usealtworkpath
    6262
     
    7070        clean_dist
    7171    }
    72     if {([info exists ports_clean_all] && $ports_clean_all == "yes" || \
    73         [info exists ports_clean_archive] && $ports_clean_archive == "yes")
    74         && !$usealtworkpath} {
    75         ui_info "$UI_PREFIX [format [msgcat::mc "Removing archives for %s"] [option name]]"
    76         clean_archive
    77     }
    7872    if {[info exists ports_clean_all] && $ports_clean_all == "yes" || \
    7973        [info exists ports_clean_work] && $ports_clean_work == "yes" || \
    80         (!([info exists ports_clean_archive] && $ports_clean_archive == "yes"))} {
     74        !([info exists ports_clean_logs] && $ports_clean_logs == "yes")} {
    8175         ui_info "$UI_PREFIX [format [msgcat::mc "Removing work directory for %s"] [option name]]"
    8276         clean_work
     
    256250    return 0
    257251}
    258 
    259 proc portclean::clean_archive {args} {
    260     global workpath portarchivepath name version ports_version_glob
    261 
    262     # Define archive destination directory, target filename, regex for archive name
    263     if {$portarchivepath ne $workpath && $portarchivepath ne ""} {
    264         set archivepath [file join $portarchivepath [option os.platform]_[option os.major]]
    265         set regexstring "^$name-\[\\-_a-zA-Z0-9\\.\]+_\[0-9\]*\[+\\-_a-zA-Z0-9\]*\[\\.\].*\[\\.\]\[a-z2\]+\$"
    266     }
    267 
    268     if {[info exists ports_version_glob]} {
    269         # Match all possible archive variants that match the version
    270         # glob specified by the user for this OS.
    271         set fileglob "$name-[option ports_version_glob]*.*.*"
    272     } else {
    273         # Match all possible archive variants for the current version on
    274         # this OS. If you want to delete previous versions, use the
    275         # version glob argument to clean.
    276         #
    277         # We do this because if we don't, then ports that match the
    278         # first part of the name (e.g. trying to remove foo-* will
    279         # pick up anything foo-bar-* as well, which is undesirable).
    280         set fileglob "$name-$version*.*.*"
    281     }
    282 
    283     # Remove the archive files
    284     set count 0
    285     if {![catch {set archivelist [glob [file join $archivepath * $name $fileglob]]} result]} {
    286         foreach path $archivelist {
    287             set file [file tail $path]
    288             # Make sure file is truly a port archive file, and not
    289             # an accidental match with some other file that might exist.
    290             if {[regexp $regexstring $file] && [file isfile $path]} {
    291                 ui_debug "Removing archive: $path"
    292                 if {[catch {delete $path} result]} {
    293                     ui_debug "$::errorInfo"
    294                     ui_error "$result"
    295                 }
    296                 incr count
    297             }
    298         }
    299     }
    300     if {$count > 0} {
    301         ui_debug "$count archive(s) removed."
    302     } else {
    303         ui_debug "No archives found to remove at $archivepath"
    304     }
    305 
    306     return 0
    307 }
    308 
  • trunk/base/src/port1.0/portdeactivate.tcl

    r70138 r77511  
    5050
    5151proc portdeactivate::deactivate_start {args} {
    52     global prefix registry.installtype
    53     if { (![file writable $prefix] || ([getuid] == 0 && [geteuid] != 0)) && ${registry.installtype} == "image"} {
     52    global prefix
     53    if {![file writable $prefix] || ([getuid] == 0 && [geteuid] != 0)} {
    5454        # if install location is not writable, need root privileges
    5555        elevateToRoot "deactivate"
     
    5858
    5959proc portdeactivate::deactivate_main {args} {
    60     global name version revision portvariants user_options registry.installtype
    61     # we still want to be able to run this target in direct mode for the pre/post procs
    62     if {${registry.installtype} == "image"} {
    63         registry_deactivate $name "${version}_${revision}${portvariants}" [array get user_options]
    64     }
     60    global name version revision portvariants user_options
     61    registry_deactivate $name "${version}_${revision}${portvariants}" [array get user_options]
    6562    return 0
    6663}
  • trunk/base/src/port1.0/portinstall.tcl

    r70974 r77511  
    3939target_provides ${org.macports.install} install
    4040target_runtype ${org.macports.install} always
    41 if {[option portarchivemode] == "yes"} {
    42     target_requires ${org.macports.install} main archivefetch unarchive fetch checksum extract patch configure build destroot archive
    43 } else {
    44     target_requires ${org.macports.install} main fetch checksum extract patch configure build destroot
    45 }
     41target_requires ${org.macports.install} main archivefetch fetch checksum extract patch configure build destroot
    4642target_prerun ${org.macports.install} portinstall::install_start
    4743
     
    7773}
    7874
    79 proc portinstall::install_element {src_element dst_element} {
    80     # don't recursively copy directories
    81     if {[file isdirectory $src_element] && [file type $src_element] != "link"} {
    82         file mkdir $dst_element
     75# fake some info for a list of files to match the format
     76# used for contents in the flat registry
     77# This list is a 6-tuple of the form:
     78# 0: file path
     79# 1: uid
     80# 2: gid
     81# 3: mode
     82# 4: size
     83# 5: md5 checksum information
     84proc portinstall::_fake_fileinfo_for_index {flist} {
     85    global
     86        set rval [list]
     87        foreach file $flist {
     88                lappend rval [list $file [getuid] [getgid] 0644 0 "MD5 ($fname) NONE"]
     89        }
     90        return $rval
     91}
     92
     93proc portinstall::putel { fd el data } {
     94    # Quote xml data
     95    set quoted [string map  { & &amp; < &lt; > &gt; } $data]
     96    # Write the element
     97    puts $fd "<${el}>${quoted}</${el}>"
     98}
     99
     100proc portinstall::putlist { fd listel itemel list } {
     101    puts $fd "<$listel>"
     102    foreach item $list {
     103        putel $fd $itemel $item
     104    }
     105    puts $fd "</$listel>"
     106}
     107
     108proc portinstall::create_archive {location archive.type} {
     109    global workpath destpath portpath name version revision portvariants \
     110           epoch os.platform PortInfo installPlist \
     111           archive.env archive.cmd archive.pre_args archive.args \
     112           archive.post_args archive.dir
     113    set archive.env {}
     114    set archive.cmd {}
     115    set archive.pre_args {}
     116    set archive.args {}
     117    set archive.post_args {}
     118    set archive.dir ${destpath}
     119
     120    switch -regex -- ${archive.type} {
     121        cp(io|gz) {
     122            set pax "pax"
     123            if {[catch {set pax [findBinary $pax ${portutil::autoconf::pax_path}]} errmsg] == 0} {
     124                ui_debug "Using $pax"
     125                set archive.cmd "$pax"
     126                set archive.pre_args {-w -v -x cpio}
     127                if {[regexp {z$} ${archive.type}]} {
     128                    set gzip "gzip"
     129                    if {[catch {set gzip [findBinary $gzip ${portutil::autoconf::gzip_path}]} errmsg] == 0} {
     130                        ui_debug "Using $gzip"
     131                        set archive.args {.}
     132                        set archive.post_args "| $gzip -c9 > ${location}"
     133                    } else {
     134                        ui_debug $errmsg
     135                        return -code error "No '$gzip' was found on this system!"
     136                    }
     137                } else {
     138                    set archive.args "-f ${location} ."
     139                }
     140            } else {
     141                ui_debug $errmsg
     142                return -code error "No '$pax' was found on this system!"
     143            }
     144        }
     145        t(ar|bz|lz|xz|gz) {
     146            set tar "tar"
     147            if {[catch {set tar [findBinary $tar ${portutil::autoconf::tar_path}]} errmsg] == 0} {
     148                ui_debug "Using $tar"
     149                set archive.cmd "$tar"
     150                set archive.pre_args {-cvf}
     151                if {[regexp {z2?$} ${archive.type}]} {
     152                    if {[regexp {bz2?$} ${archive.type}]} {
     153                        set gzip "bzip2"
     154                        set level 9
     155                    } elseif {[regexp {lz$} ${archive.type}]} {
     156                        set gzip "lzma"
     157                        set level ""
     158                    } elseif {[regexp {xz$} ${archive.type}]} {
     159                        set gzip "xz"
     160                        set level 6
     161                    } else {
     162                        set gzip "gzip"
     163                        set level 9
     164                    }
     165                    if {[info exists portutil::autoconf::${gzip}_path]} {
     166                        set hint [set portutil::autoconf::${gzip}_path]
     167                    } else {
     168                        set hint ""
     169                    }
     170                    if {[catch {set gzip [findBinary $gzip $hint]} errmsg] == 0} {
     171                        ui_debug "Using $gzip"
     172                        set archive.args {- .}
     173                        set archive.post_args "| $gzip -c$level > ${location}"
     174                    } else {
     175                        ui_debug $errmsg
     176                        return -code error "No '$gzip' was found on this system!"
     177                    }
     178                } else {
     179                    set archive.args "${location} ."
     180                }
     181            } else {
     182                ui_debug $errmsg
     183                return -code error "No '$tar' was found on this system!"
     184            }
     185        }
     186        xar {
     187            set xar "xar"
     188            if {[catch {set xar [findBinary $xar ${portutil::autoconf::xar_path}]} errmsg] == 0} {
     189                ui_debug "Using $xar"
     190                set archive.cmd "$xar"
     191                set archive.pre_args {-cvf}
     192                set archive.args "${location} ."
     193            } else {
     194                ui_debug $errmsg
     195                return -code error "No '$xar' was found on this system!"
     196            }
     197        }
     198        xpkg {
     199            set xar "xar"
     200            set compression "bzip2"
     201            set archive.meta yes
     202            set archive.metaname "xpkg"
     203            set archive.metapath [file join $workpath "${archive.metaname}.xml"]
     204            if {[catch {set xar [findBinary $xar ${portutil::autoconf::xar_path}]} errmsg] == 0} {
     205                ui_debug "Using $xar"
     206                set archive.cmd "$xar"
     207                set archive.pre_args "-cv --exclude='\./\+.*' --compression=${compression} -n ${archive.metaname} -s ${archive.metapath} -f"
     208                set archive.args "${location} ."
     209            } else {
     210                ui_debug $errmsg
     211                return -code error "No '$xar' was found on this system!"
     212            }
     213        }
     214        zip {
     215            set zip "zip"
     216            if {[catch {set zip [findBinary $zip ${portutil::autoconf::zip_path}]} errmsg] == 0} {
     217                ui_debug "Using $zip"
     218                set archive.cmd "$zip"
     219                set archive.pre_args {-ry9}
     220                set archive.args "${location} ."
     221            } else {
     222                ui_debug $errmsg
     223                return -code error "No '$zip' was found on this system!"
     224            }
     225        }
     226    }
     227
     228    set archive.fulldestpath [file dirname $location]
     229    # Create archive destination path (if needed)
     230    if {![file isdirectory ${archive.fulldestpath}]} {
     231        file mkdir ${archive.fulldestpath}
     232    }
     233
     234    # Create (if no files) destroot for archiving
     235    if {![file isdirectory ${destpath}]} {
     236        return -code error "no destroot found at: ${destpath}"
     237    }
     238
     239    # Copy state file into destroot for archiving
     240    # +STATE contains a copy of the MacPorts state information
     241    set statefile [file join $workpath .macports.${name}.state]
     242    file copy -force $statefile [file join $destpath "+STATE"]
     243
     244    # Copy Portfile into destroot for archiving
     245    # +PORTFILE contains a copy of the MacPorts Portfile
     246    set portfile [file join $portpath Portfile]
     247    file copy -force $portfile [file join $destpath "+PORTFILE"]
     248
     249    # Create some informational files that we don't really use just yet,
     250    # but we may in the future in order to allow port installation from
     251    # archives without a full "ports" tree of Portfiles.
     252    #
     253    # Note: These have been modeled after FreeBSD type package files to
     254    # start. We can change them however we want for actual future use if
     255    # needed.
     256    #
     257    # +COMMENT contains the port description
     258    set fd [open [file join $destpath "+COMMENT"] w]
     259    if {[exists description]} {
     260        puts $fd "[option description]"
     261    }
     262    close $fd
     263    # +DESC contains the port long_description and homepage
     264    set fd [open [file join $destpath "+DESC"] w]
     265    if {[exists long_description]} {
     266        puts $fd "[option long_description]"
     267    }
     268    if {[exists homepage]} {
     269        puts $fd "\nWWW: [option homepage]"
     270    }
     271    close $fd
     272    # +CONTENTS contains the port version/name info and all installed
     273    # files and checksums
     274    set control [list]
     275    set fd [open [file join $destpath "+CONTENTS"] w]
     276    puts $fd "@name ${name}-${version}_${revision}${portvariants}"
     277    puts $fd "@portname ${name}"
     278    puts $fd "@portepoch ${epoch}"
     279    puts $fd "@portversion ${version}"
     280    puts $fd "@portrevision ${revision}"
     281    puts $fd "@archs [get_canonical_archs]"
     282    array set ourvariations $PortInfo(active_variants)
     283    set vlist [lsort -ascii [array names ourvariations]]
     284    foreach v $vlist {
     285        if {$ourvariations($v) == "+"} {
     286            puts $fd "@portvariant +${v}"
     287        }
     288    }
     289    set res [mport_lookup $name]
     290    if {[llength $res] < 2} {
     291        ui_error "Port $name not found"
    83292    } else {
    84         file copy -force $src_element $dst_element
    85     }
    86    
    87     # if the file is a symlink, do not try to set file attributes
    88     if {[file type $src_element] != "link"} {
    89         # tclsh on 10.6 doesn't like the combination of 0444 perm and
    90         # '-creator {}' (which is returned from 'file attributes <file>'; so
    91         # instead just set the attributes which are needed
    92         set wantedattrs {owner group permissions}
    93         set file_attr_cmd {file attributes $dst_element}
    94         foreach oneattr $wantedattrs {
    95             set file_attr_cmd "$file_attr_cmd -$oneattr \[file attributes \$src_element -$oneattr\]"
    96         }
    97         eval $file_attr_cmd
    98         # set mtime on installed element
    99         file mtime $dst_element [file mtime $src_element]
    100     }
    101 }
    102 
    103 proc portinstall::directory_dig {rootdir workdir imagedir {cwd ""} {prepend 1}} {
    104     global installPlist
    105     set pwd [pwd]
    106     if {[catch {_cd $workdir} err]} {
    107         puts $err
    108         return
    109     }
    110 
    111     set root [file join [file separator] $imagedir]
    112     foreach name [readdir .] {
    113         set element [file join $cwd $name]
    114 
    115         set dst_element [file join $root $element]
    116         set src_element [file join $rootdir $element]
    117         # overwrites files but not directories
    118         if {![file exists $dst_element] || ![file isdirectory $dst_element]} {
    119             if {[file type $src_element] == "link"} {
    120                 ui_debug "installing link: $dst_element"
    121             } elseif {[file isdirectory $src_element]} {
    122                 ui_debug "installing directory: $dst_element"
    123             } else {
    124                 ui_debug "installing file: $dst_element"
    125             }
    126             install_element $src_element $dst_element
    127             # only track files/links for registry, not directories
    128             if {[file type $dst_element] != "directory"} {
    129                 if {$prepend} {
    130                     lappend installPlist $dst_element
    131                 } else {
    132                     lappend installPlist [file join [file separator] $element]
     293        array set portinfo [lindex $res 1]
     294        foreach key "depends_lib depends_run" {
     295             if {[info exists portinfo($key)]} {
     296                 foreach depspec $portinfo($key) {
     297                     set depname [lindex [split $depspec :] end]
     298                     set dep [mport_lookup $depname]
     299                     if {[llength $dep] < 2} {
     300                         ui_error "Dependency $dep not found"
     301                     } else {
     302                         array set portinfo [lindex $dep 1]
     303                         set depver $portinfo(version)
     304                         set deprev $portinfo(revision)
     305                         puts $fd "@pkgdep ${depname}-${depver}_${deprev}"
     306                     }
     307                 }
     308             }
     309        }
     310    }
     311    # also save the contents for our own use later
     312    set installPlist {}
     313    fs-traverse -depth fullpath $destpath {
     314        if {[file isdirectory $fullpath]} {
     315            continue
     316        }
     317        set relpath [strsed $fullpath "s|^$destpath/||"]
     318        if {![regexp {^[+]} $relpath]} {
     319            puts $fd "$relpath"
     320            lappend installPlist [file join [file separator] $relpath]
     321            if {[file isfile $fullpath]} {
     322                ui_debug "checksum file: $fullpath"
     323                set checksum [md5 file $fullpath]
     324                puts $fd "@comment MD5:$checksum"
     325            }
     326        } else {
     327            lappend control $relpath
     328        }
     329    }
     330    foreach relpath $control {
     331        puts $fd "@ignore"
     332        puts $fd "$relpath"
     333    }
     334    close $fd
     335
     336    # the XML package metadata, for XAR package
     337    # (doesn't contain any file list/checksums)
     338    if {[tbool archive.meta]} {
     339        set sd [open ${archive.metapath} w]
     340        puts $sd "<xpkg version='0.2'>"
     341        # TODO: split contents into <buildinfo> (new) and <package> (current)
     342        #       see existing <portpkg> for the matching source package layout
     343
     344        putel $sd name ${name}
     345        putel $sd epoch ${epoch}
     346        putel $sd version ${version}
     347        putel $sd revision ${revision}
     348        putel $sd major 0
     349        putel $sd minor 0
     350
     351        putel $sd platform ${os.platform}
     352        if {[llength [get_canonical_archs]] > 1} {
     353            putlist $sd archs arch [get_canonical_archs]
     354        } else {
     355            putel $sd arch [get_canonical_archs]
     356        }
     357        putlist $sd variants variant $vlist
     358
     359        if {[exists categories]} {
     360            set primary [lindex [split [option categories] " "] 0]
     361            putel $sd category $primary
     362        }
     363        if {[exists description]} {
     364            putel $sd comment "[option description]"
     365        }
     366        if {[exists long_description]} {
     367            putel $sd desc "[option long_description]"
     368        }
     369        if {[exists homepage]} {
     370            putel $sd homepage "[option homepage]"
     371        }
     372
     373            # Emit dependencies provided by this package
     374            puts $sd "<provides>"
     375                set name ${name}
     376                puts $sd "<item>"
     377                putel $sd name $name
     378                putel $sd major 0
     379                putel $sd minor 0
     380                puts $sd "</item>"
     381            puts $sd "</provides>"
     382           
     383    set res [mport_lookup $name]
     384    if {[llength $res] < 2} {
     385        ui_error "Dependency $name not found"
     386    } else {
     387    array set portinfo [lindex $res 1]
     388
     389            # Emit build, library, and runtime dependencies
     390            puts $sd "<requires>"
     391            foreach {key type} {
     392                depends_fetch "fetch"
     393                depends_extract "extract"
     394                depends_build "build"
     395                depends_lib "library"
     396                depends_run "runtime"
     397            } {
     398                if {[info exists portinfo($key)]} {
     399                    set name [lindex [split $portinfo($key) :] end]
     400                    puts $sd "<item type=\"$type\">"
     401                    putel $sd name $name
     402                    putel $sd major 0
     403                    putel $sd minor 0
     404                    puts $sd "</item>"
    133405                }
    134406            }
    135         }
    136         if {[file isdirectory $name] && [file type $name] != "link"} {
    137             directory_dig $rootdir $name $imagedir [file join $cwd $name] $prepend
    138         }
    139     }
    140     _cd $pwd
     407            puts $sd "</requires>"
     408    }
     409
     410        puts $sd "</xpkg>"
     411        close $sd
     412    }
     413
     414    # Now create the archive
     415    ui_debug "Creating [file tail $location]"
     416    command_exec archive
     417    ui_debug "Archive [file tail $location] packaged"
     418
     419    # Cleanup all control files when finished
     420    set control_files [glob -nocomplain -types f [file join $destpath +*]]
     421    foreach file $control_files {
     422        ui_debug "removing file: $file"
     423        file delete -force $file
     424    }
     425}
     426
     427proc portinstall::extract_contents {location type} {
     428    switch -- $type {
     429        tbz -
     430        tbz2 {
     431            set raw_contents [exec [findBinary tar ${portutil::autoconf::tar_path}] -xOjqf $location +CONTENTS]
     432        }
     433        tgz {
     434            set raw_contents [exec [findBinary tar ${portutil::autoconf::tar_path}] -xOzqf $location +CONTENTS]
     435        }
     436        tar {
     437            set raw_contents [exec [findBinary tar ${portutil::autoconf::tar_path}] -xOqf $location +CONTENTS]
     438        }
     439        txz {
     440            set raw_contents [exec [findBinary tar ${portutil::autoconf::tar_path}] -xOqf $location --use-compress-program [findBinary xz ""] +CONTENTS]
     441        }
     442        tlz {
     443            set raw_contents [exec [findBinary tar ${portutil::autoconf::tar_path}] -xOqf $location --use-compress-program [findBinary lzma ""] +CONTENTS]
     444        }
     445        xar {
     446            system "cd ${workpath} && [findBinary xar ${portutil::autoconf::xar_path}] -xf $location +CONTENTS"
     447            set twostep 1
     448        }
     449        xpkg {
     450            system "cd ${workpath} && [findBinary xar ${portutil::autoconf::xar_path}] -xf $location --compression=bzip2 +CONTENTS"
     451            set twostep 1
     452        }
     453        zip {
     454            set raw_contents [exec [findBinary unzip ${portutil::autoconf::unzip_path}] -p $location +CONTENTS]
     455        }
     456        cpgz {
     457            system "cd ${workpath} && [findBinary pax ${portutil::autoconf::pax_path}] -rzf $location +CONTENTS"
     458            set twostep 1
     459        }
     460        cpio {
     461            system "cd ${workpath} && [findBinary pax ${portutil::autoconf::pax_path}] -rf $location +CONTENTS"
     462            set twostep 1
     463        }
     464    }
     465    if {[info exists twostep]} {
     466        set fd [open "${workpath}/+CONTENTS"]
     467        set raw_contents [read $fd]
     468        close $fd
     469    }
     470    set contents {}
     471    set ignore 0
     472    foreach line [split $raw_contents \n] {
     473        if {$ignore} {
     474            set ignore 0
     475            continue
     476        }
     477        if {[string index $line 0] != "@"} {
     478            lappend contents $line
     479        } elseif {$line == "@ignore"} {
     480            set ignore 1
     481        }
     482    }
     483    return $contents
    141484}
    142485
    143486proc portinstall::install_main {args} {
    144487    global name version portpath categories description long_description \
    145     homepage depends_run installPlist package-install workdir workpath \
     488    homepage depends_run package-install workdir workpath \
    146489    worksrcdir UI_PREFIX destroot revision maintainers user_options \
    147490    portvariants negated_variants targets depends_lib PortInfo epoch license \
    148     registry.installtype registry.path registry.format \
    149     os.platform os.major
     491    registry.format os.platform os.major portarchivetype installPlist
    150492
    151493    set oldpwd [pwd]
     
    153495        set oldpwd $portpath
    154496    }
    155     _cd $workpath
     497
     498    # throws an error if an unsupported value has been configured
     499    archiveTypeIsSupported $portarchivetype
     500
     501    set location [get_portimage_path]
     502    if {![file isfile $location]} {
     503        # create archive from the destroot
     504        create_archive $location $portarchivetype
     505    }
     506
     507    if {![info exists installPlist]} {
     508        set installPlist [extract_contents $location $portarchivetype]
     509    }
    156510
    157511    if {[string equal ${registry.format} "receipt_sqlite"]} {
     
    189543            }
    190544
    191             if {${registry.installtype} == "image"} {
    192                 $regref installtype image
    193                 $regref state imaged
    194                 set imagedir [file join ${registry.path} software ${name} ${version}_${revision}${portvariants}]
    195             } else {
    196                 $regref installtype direct
    197                 $regref state installed
    198                 set imagedir ""
    199             }
    200             $regref location $imagedir
    201 
    202             # Install the files, requesting that the list not have the image dir prepended
    203             directory_dig ${destroot} ${destroot} ${imagedir} "" 0
    204            
     545            $regref installtype image
     546            $regref state imaged
     547            $regref location $location
     548
    205549            if {[info exists installPlist]} {
    206550                # register files
     
    220564        }
    221565
    222         set imagedir ""
    223         if { [registry_prop_retr $regref installtype] == "image" } {
    224             set imagedir [registry_prop_retr $regref imagedir]
    225         }
    226         # Install the files
    227         directory_dig ${destroot} ${destroot} ${imagedir}
     566        registry_prop_store $regref location $location
    228567
    229568        registry_prop_store $regref requested $user_options(ports_requested)
     
    258597        }
    259598        if {[info exists installPlist]} {
    260             registry_prop_store $regref contents [registry_fileinfo_for_index $installPlist]
    261             if { [registry_prop_retr $regref installtype] != "image" } {
    262                 registry_bulk_register_files [registry_fileinfo_for_index $installPlist] $name
    263             }
     599            registry_prop_store $regref contents [_fake_fileinfo_for_index $installPlist]
    264600        }
    265601        if {[info exists package-install]} {
  • trunk/base/src/port1.0/portutil.tcl

    r76482 r77511  
    12971297                        destroot    -
    12981298                        install     -
    1299                         archive     -
    13001299                        dmg         -
    13011300                        pkg         -
     
    21552154}
    21562155
     2156# return path where the image/archive for this port will be stored
     2157proc get_portimage_path {} {
     2158    global registry.path name version revision portvariants os.platform os.major portarchivetype
     2159    return [file join ${registry.path} software ${name} "${name}-${version}_${revision}${portvariants}.${os.platform}_${os.major}.[join [get_canonical_archs] -].${portarchivetype}"]
     2160}
     2161
     2162# return list of archive types that we can extract
     2163proc supportedArchiveTypes {} {
     2164    global supported_archive_types
     2165    if {![info exists supported_archive_types]} {
     2166        set supported_archive_types {}
     2167        foreach type {tbz2 tbz tgz tar txz tlz xar xpkg zip cpgz cpio} {
     2168            if {[catch {archiveTypeIsSupported $type}] == 0} {
     2169                lappend supported_archive_types $type
     2170            }
     2171        }
     2172    }
     2173    return $supported_archive_types
     2174}
     2175
    21572176# check if archive type is supported by current system
    21582177# returns an error code if it is not
     
    22002219            }
    22012220        }
    2202         xar {
     2221        xar|xpkg {
    22032222            set xar "xar"
    22042223            if {[catch {set xar [findBinary $xar ${portutil::autoconf::xar_path}]} errmsg] == 0} {
     
    25322551# returns the name of the port that will actually be satisfying $depspec
    25332552proc _get_dep_port {depspec} {
    2534     global registry.installtype
    25352553    set speclist [split $depspec :]
    25362554    set portname [lindex $speclist end]
    2537     if {[string equal ${registry.installtype} "image"]} {
    2538         set res [_portnameactive $portname]
    2539     } else {
    2540         set res [registry_exists_for_name $portname]
    2541     }
     2555    set res [_portnameactive $portname]
    25422556    if {$res != 0} {
    25432557        return $portname
     
    26372651# check if we can unarchive this port
    26382652proc _archive_available {} {
    2639     global name version revision portvariants ports_source_only
    2640     global unarchive.srcpath workpath
    2641 
    2642     if {[option portarchivemode] != "yes" || [tbool ports_source_only]} {
     2653    global name version revision portvariants ports_source_only workpath \
     2654           registry.path os.platform os.major
     2655
     2656    if {[tbool ports_source_only]} {
    26432657        return 0
    26442658    }
    26452659
    2646     # Define archive directory, file, and path
    2647     if {![string equal ${unarchive.srcpath} ${workpath}] && ![string equal ${unarchive.srcpath} ""]} {
    2648         set unarchive.fullsrcpath [file join ${unarchive.srcpath} [option archive.subdir]]
    2649     } else {
    2650         set unarchive.fullsrcpath ${unarchive.srcpath}
    2651     }
    2652 
    26532660    set found 0
    2654     foreach unarchive.type [option portarchivetype] {
    2655         if {[catch {archiveTypeIsSupported ${unarchive.type}} errmsg] == 0} {
    2656             set archstring [join [get_canonical_archs] -]
    2657             set unarchive.file "${name}-${version}_${revision}${portvariants}.${archstring}.${unarchive.type}"
    2658             if {[file isfile [file join ${unarchive.fullsrcpath} ${unarchive.file}]]} {
    2659                 set found 1
    2660                 break
    2661             }
    2662         }
    2663     }
     2661    foreach unarchive.type [supportedArchiveTypes] {
     2662        set fullarchivepath [file join ${registry.path} software ${name} "${name}-${version}_${revision}${portvariants}.${os.platform}_${os.major}.[join [get_canonical_archs] -].${unarchive.type}"]
     2663        if {[file isfile $fullarchivepath]} {
     2664            set found 1
     2665            break
     2666        }
     2667    }
     2668   
     2669    # TODO: also check if porturl points to an archive
     2670    # maybe check if there's an archive available on the server too - this
     2671    # is kind of useless otherwise now that archive == installed image
     2672
    26642673    return $found
    26652674}
  • trunk/base/src/registry2.0/portimage.tcl

    r68864 r77511  
    4242set UI_PREFIX "--> "
    4343
    44 #
    45 # Port Images are basically just installations of the destroot of a port into
    46 # ${macports::registry.path}/software/${name}/${version}_${revision}${variants}
     44# Port Images are installations of the destroot of a port into a compressed
     45# tarball in ${macports::registry.path}/software/${name}.
    4746# They allow the user to install multiple versions of the same port, treating
    4847# each revision and each different combination of variants as a "version".
    4948#
    50 # From there, the user can "activate" a port image.  This creates {sym,hard}links for
    51 # all files in the image into the ${prefix}.  Directories are created.
     49# From there, the user can "activate" a port image.  This extracts the port's
     50# files from the image into the ${prefix}.  Directories are created.
    5251# Activation checks the registry's file_map for any files which conflict with
    5352# other "active" ports, and will not overwrite the links to the those files.
    5453# The conflicting port must be deactivated first.
    5554#
    56 # The user can also "deactivate" an active port.  This will remove all {sym,hard}links
    57 # from ${prefix}, and if any directories are empty, remove them as well.  It
    58 # will also remove all of the references of the files from the registry's
    59 # file_map
    60 #
    61 # For the creating and removing of links during activation and deactivation,
    62 # code very similar to what is used in portinstall is used.
    63 #
     55# The user can also "deactivate" an active port.  This will remove all the
     56# port's files from ${prefix}, and if any directories are empty, remove them
     57# as well. It will also remove all of the references of the files from the
     58# registry's file_map.
     59
    6460
    6561namespace eval portimage {
     
    10298            set variants [$requested variants]
    10399            set specifier "${version}_${revision}${variants}"
     100            set location [$requested location]
    104101
    105102            # if another version of this port is active, deactivate it first
     
    115112                return -code error "Image error: ${name} @${version}_${revision}${variants} not installed as an image."
    116113            }
    117 
     114            if {![file isfile $location]} {
     115                return -code error "Image error: Can't find image file $location"
     116            }
    118117            if { [string equal [$requested state] "installed"] } {
    119118                return -code error "Image error: ${name} @${version}_${revision}${variants} is already active."
     
    153152            return -code error "Image error: ${name} @${version}_${revision}${variants} not installed as an image."
    154153        }
     154        set location [registry::property_retrieve $ref location]
     155        if {![file isfile $location]} {
     156            return -code error "Image error: Can't find image file $location"
     157        }
    155158        if { [registry::property_retrieve $ref active] != 0 } {
    156159            return -code error "Image error: ${name} @${version}_${revision}${variants} is already active."
     
    172175        $requested state installed
    173176    } else {
    174         set imagedir [registry::property_retrieve $ref imagedir]
    175 
    176177        set contents [registry::property_retrieve $ref contents]
    177178
    178         set imagefiles [_check_contents $name $contents $imagedir]
     179        set imagefiles {}
     180        foreach content_element $contents {
     181            lappend imagefiles [lindex $content_element 0]
     182        }
    179183
    180184        registry::open_file_map
    181         _activate_contents $name $imagefiles $imagedir
     185        _activate_contents $name $imagefiles $location
    182186
    183187        registry::property_store $ref active 1
     
    298302
    299303proc _check_registry {name v} {
    300     global UI_PREFIX macports::registry.installtype
     304    global UI_PREFIX
    301305    variable use_reg2
    302306
     
    359363}
    360364
    361 proc _check_contents {name contents imagedir} {
    362 
    363     set imagefiles [list]
    364     set idlen [string length $imagedir]
    365 
    366     # generate list of activated file paths from list of paths in the image dir
    367     foreach fe $contents {
    368         set srcfile [lindex $fe 0]
    369         if { ![string equal $srcfile ""] && [file type $srcfile] != "directory" } {
    370             set file [string range $srcfile $idlen [string length $srcfile]]
    371 
    372             lappend imagefiles $file
    373         }
    374     }
    375 
    376     return $imagefiles
    377 }
    378 
    379365## Activates a file from an image into the filesystem. Deals with symlinks,
    380366## directories and files.
     
    385371proc _activate_file {srcfile dstfile} {
    386372    switch [file type $srcfile] {
    387         link {
    388             ui_debug "activating link: $dstfile"
    389             file copy -force -- $srcfile $dstfile
    390             return 1
    391         }
    392373        directory {
    393374            # Don't recursively copy directories
     
    405386        default {
    406387            ui_debug "activating file: $dstfile"
    407             # Try a hard link first and if that fails, a symlink
    408             if {[catch {file link -hard $dstfile $srcfile}]} {
    409                 ui_debug "hardlinking $srcfile to $dstfile failed, symlinking instead"
    410                 file link -symbolic $dstfile $srcfile
    411             }
     388            file rename $srcfile $dstfile
    412389            return 1
    413390        }
     
    415392}
    416393
     394# extract an archive to a temporary location
     395# returns: path to the extracted directory
     396proc extract_archive_to_tmpdir {location} {
     397    set extractdir [mkdtemp [file join [macports::gettmpdir] mpextractXXXXXXXX]]
     398
     399    try {
     400        set startpwd [pwd]
     401        if {[catch {cd $extractdir} err]} {
     402            throw MACPORTS $err
     403        }
     404   
     405        # clagged straight from unarchive... this really needs to be factored
     406        # out, but it's a little tricky as the places where it's used run in
     407        # different interpreter contexts with access to different packages.
     408        set unarchive.cmd {}
     409        set unarchive.pre_args {}
     410        set unarchive.args {}
     411        set unarchive.pipe_cmd ""
     412        set unarchive.type [file tail $location]
     413        switch -regex ${unarchive.type} {
     414            cp(io|gz) {
     415                set pax "pax"
     416                if {[catch {set pax [macports::findBinary $pax ${macports::autoconf::pax_path}]} errmsg] == 0} {
     417                    ui_debug "Using $pax"
     418                    set unarchive.cmd "$pax"
     419                    if {[geteuid] == 0} {
     420                        set unarchive.pre_args {-r -v -p e}
     421                    } else {
     422                        set unarchive.pre_args {-r -v -p p}
     423                    }
     424                    if {[regexp {z$} ${unarchive.type}]} {
     425                        set unarchive.args {.}
     426                        set gzip "gzip"
     427                        if {[catch {set gzip [macports::findBinary $gzip ${macports::autoconf::gzip_path}]} errmsg] == 0} {
     428                            ui_debug "Using $gzip"
     429                            set unarchive.pipe_cmd "$gzip -d -c ${location} |"
     430                        } else {
     431                            ui_debug $errmsg
     432                            throw MACPORTS "No '$gzip' was found on this system!"
     433                        }
     434                    } else {
     435                        set unarchive.args "-f ${location} ."
     436                    }
     437                } else {
     438                    ui_debug $errmsg
     439                    throw MACPORTS "No '$pax' was found on this system!"
     440                }
     441            }
     442            t(ar|bz|lz|xz|gz) {
     443                set tar "tar"
     444                if {[catch {set tar [macports::findBinary $tar ${macports::autoconf::tar_path}]} errmsg] == 0} {
     445                    ui_debug "Using $tar"
     446                    set unarchive.cmd "$tar"
     447                    set unarchive.pre_args {-xvpf}
     448                    if {[regexp {z2?$} ${unarchive.type}]} {
     449                        set unarchive.args {-}
     450                        if {[regexp {bz2?$} ${unarchive.type}]} {
     451                            set gzip "bzip2"
     452                        } elseif {[regexp {lz$} ${unarchive.type}]} {
     453                            set gzip "lzma"
     454                        } elseif {[regexp {xz$} ${unarchive.type}]} {
     455                            set gzip "xz"
     456                        } else {
     457                            set gzip "gzip"
     458                        }
     459                        if {[info exists macports::autoconf::${gzip}_path]} {
     460                            set hint [set macports::autoconf::${gzip}_path]
     461                        } else {
     462                            set hint ""
     463                        }
     464                        if {[catch {set gzip [macports::findBinary $gzip $hint]} errmsg] == 0} {
     465                            ui_debug "Using $gzip"
     466                            set unarchive.pipe_cmd "$gzip -d -c ${location} |"
     467                        } else {
     468                            ui_debug $errmsg
     469                            throw MACPORTS "No '$gzip' was found on this system!"
     470                        }
     471                    } else {
     472                        set unarchive.args "${location}"
     473                    }
     474                } else {
     475                    ui_debug $errmsg
     476                    throw MACPORTS "No '$tar' was found on this system!"
     477                }
     478            }
     479            xar|xpkg {
     480                set xar "xar"
     481                if {[catch {set xar [macports::findBinary $xar ${macports::autoconf::xar_path}]} errmsg] == 0} {
     482                    ui_debug "Using $xar"
     483                    set unarchive.cmd "$xar"
     484                    set unarchive.pre_args {-xvpf}
     485                    set unarchive.args "${location}"
     486                } else {
     487                    ui_debug $errmsg
     488                    throw MACPORTS "No '$xar' was found on this system!"
     489                }
     490            }
     491            zip {
     492                set unzip "unzip"
     493                if {[catch {set unzip [macports::findBinary $unzip ${macports::autoconf::unzip_path}]} errmsg] == 0} {
     494                    ui_debug "Using $unzip"
     495                    set unarchive.cmd "$unzip"
     496                    if {[geteuid] == 0} {
     497                        set unarchive.pre_args {-oX}
     498                    } else {
     499                        set unarchive.pre_args {-o}
     500                    }
     501                    set unarchive.args "${location} -d ."
     502                } else {
     503                    ui_debug $errmsg
     504                    throw MACPORTS "No '$unzip' was found on this system!"
     505                }
     506            }
     507            default {
     508                throw MACPORTS "Unsupported port archive type '${unarchive.type}'!"
     509            }
     510        }
     511       
     512        # and finally, reinvent command_exec
     513        if {${unarchive.pipe_cmd} == ""} {
     514            set cmdstring "${unarchive.cmd} ${unarchive.pre_args} ${unarchive.args}"
     515        } else {
     516            set cmdstring "${unarchive.pipe_cmd} ( ${unarchive.cmd} ${unarchive.pre_args} ${unarchive.args} )"
     517        }
     518        system $cmdstring
     519    } catch {*} {
     520        file delete -force $extractdir
     521        throw
     522    } finally {
     523        cd $startpwd
     524    }
     525
     526    return $extractdir
     527}
     528
    417529## Activates the contents of a port
    418 proc _activate_contents {port {imagefiles {}} {imagedir {}}} {
     530proc _activate_contents {port {imagefiles {}} {location {}}} {
    419531    variable force
    420532    variable use_reg2
     
    425537    set baksuffix .mp_[clock seconds]
    426538    if {$use_reg2} {
    427         set imagedir [$port location]
     539        set location [$port location]
    428540        set imagefiles [$port imagefiles]
    429541    } else {
    430542        set name $port
    431543    }
     544    set extracted_dir [extract_archive_to_tmpdir $location]
    432545
    433546    set backups [list]
    434547    # This is big and hairy and probably could be done better.
    435548    # First, we need to check the source file, make sure it exists
    436     # Then we remove the $imagedir from the path of the file in the contents
     549    # Then we remove the $location from the path of the file in the contents
    437550    #  list  and check to see if that file exists
    438551    # Last, if the file exists, and belongs to another port, and force is set
     
    444557            registry::write {
    445558                foreach file $imagefiles {
    446                     set srcfile "${imagedir}${file}"
     559                    set srcfile "${extracted_dir}${file}"
    447560
    448561                    # To be able to install links, we test if we can lstat the file to
     
    533646                    $port activate $imagefiles
    534647                    foreach file $files {
    535                         if {[_activate_file "${imagedir}${file}" $file] == 1} {
     648                        if {[_activate_file "${extracted_dir}${file}" $file] == 1} {
    536649                            lappend rollback_filelist $file
    537650                        }
     
    562675                }
    563676            }
     677            # remove temp image dir
     678            file delete -force $extracted_dir
    564679            throw
    565680        }
     
    568683        set deactivated [list]
    569684        foreach file $imagefiles {
    570             set srcfile "${imagedir}${file}"
     685            set srcfile "${extracted_dir}${file}"
    571686
    572687            # To be able to install links, we test if we can lstat the file to
     
    574689            # false for symlinks on files that do not exist)
    575690            if { [catch {file lstat $srcfile dummystatvar}] } {
     691                file delete -force $extracted_dir
    576692                return -code error "Image error: Source file $srcfile does not appear to exist (cannot lstat it).  Unable to activate port $name."
    577693            }
     
    584700                    global errorInfo
    585701                    ui_debug "$errorInfo"
     702                    file delete -force $extracted_dir
    586703                    return -code error "port lookup failed: $result"
    587704                }
     
    596713   
    597714            if { $port != 0  && $force != 1 && $port != $name } {
     715                file delete -force $extracted_dir
    598716                return -code error "Image error: $file is being used by the active $port port.  Please deactivate this port first, or use 'port -f activate $name' to force the activation."
    599717            } elseif { [file exists $file] && $force != 1 } {
     718                file delete -force $extracted_dir
    600719                return -code error "Image error: $file already exists and does not belong to a registered port.  Unable to activate port $name. Use 'port -f activate $name' to force the activation."
    601720            } elseif { $force == 1 && [file exists $file] || $port != 0 } {
     
    644763        # Activate it, and catch errors so we can roll-back
    645764        if { [catch { foreach file $files {
    646                         if {[_activate_file "${imagedir}${file}" $file] == 1} {
     765                        if {[_activate_file "${extracted_dir}${file}" $file] == 1} {
    647766                            lappend rollback_filelist $file
    648767                        }
     
    668787            registry::write_file_map
    669788
     789            file delete -force $extracted_dir
    670790            return -code error $result
    671791        }
    672792    }
     793    file delete -force $extracted_dir
    673794}
    674795
  • trunk/base/src/registry2.0/portuninstall.tcl

    r73640 r77511  
    4343proc uninstall {portname {v ""} optionslist} {
    4444    global uninstall.force uninstall.nochecksum UI_PREFIX \
    45            macports::registry.format macports::registry.installtype
     45           macports::registry.format macports::portimagefilepath
    4646    array set options $optionslist
    4747
     
    142142            registry::check_dependents $port ${uninstall.force}
    143143        }
    144         # if it's an image, deactivate it
     144        # if it's active, deactivate it
    145145        if { [string equal [$port state] installed] } {
    146146            if {[info exists options(ports_dryrun)] && [string is true -strict $options(ports_dryrun)]} {
     
    148148            } else {
    149149                if {[info exists options(ports_uninstall_no-exec)] || ![registry::run_target $port deactivate $optionslist]} {
    150                     if {[$port installtype] == "image"} {
    151                         portimage::deactivate $portname $v [array get options]
    152                     }
     150                    portimage::deactivate $portname $v [array get options]
    153151                }
    154152            }
     
    206204        }
    207205   
    208         set installtype [registry::property_retrieve $ref installtype]
    209         if { $installtype == "image" && [registry::property_retrieve $ref active] == 1} {
     206        if { [registry::property_retrieve $ref active] == 1} {
    210207            if {[info exists options(ports_dryrun)] && [string is true -strict $options(ports_dryrun)]} {
    211208                ui_msg "For $portname @${version}_${revision}${variants}: skipping deactivate (dry run)"
     
    215212        }
    216213    }
    217    
     214
     215    if {$use_reg2} {
     216        set ref $port
     217    }
     218
    218219    # note deps before we uninstall if we're going to uninstall them too
    219220    if {[info exists options(ports_uninstall_follow-dependencies)] && [string is true -strict $options(ports_uninstall_follow-dependencies)]} {
     
    246247                set porturl $depportinfo(porturl)
    247248                set variations {}
    248                 if {$use_reg2} {
    249                     set ref $port
    250                 }
    251249                set minusvariant [lrange [split [registry::property_retrieve $ref negated_variants] -] 1 end]
    252250                set plusvariant [lrange [split $variants +] 1 end]
     
    305303        }
    306304   
    307         # Now look for a contents list
    308         if {$use_reg2} {
    309             # imagefiles gives the actual installed files in direct mode
    310             set contents [$port imagefiles]
    311             set imagedir [$port location]
    312         } else {
    313             set contents [registry::property_retrieve $ref contents]
    314             if { $contents == "" } {
    315                 return -code error [msgcat::mc "Uninstall failed: Port has no contents entry"]
    316             }
    317         }
    318         set bak_suffix ".mp_[clock seconds]"
    319         set files [list]
    320         foreach f $contents {
    321             if {$use_reg2} {
    322                 set fname "${imagedir}${f}"
    323                 #set sum1 [$port md5sum $f]
    324                 # there's an md5 column in registry.files in the db, but
    325                 # no way to get or set it seems to be implemented
    326                 set sum1 NONE
    327             } else {
    328                 set fname [lindex $f 0]
    329                 set md5index [lsearch -regex [lrange $f 1 end] MD5]
    330                 if {$md5index != -1} {
    331                     set sumx [lindex $f [expr $md5index + 1]]
    332                 } else {
    333                     # XXX There is no MD5 listed, set sumx to an
    334                     # empty list, causing the next conditional to
    335                     # return a checksum error
    336                     set sumx {}
    337                 }
    338                 set sum1 [lindex $sumx [expr [llength $sumx] - 1]]
    339             }
    340             if {![string match $sum1 NONE] && !([info exists uninstall.nochecksum] && [string is true -strict ${uninstall.nochecksum}]) } {
    341                 if {![catch {set sum2 [md5 $fname]}] && ![string match $sum1 $sum2]} {
    342                     ui_warn "$UI_PREFIX  [format [msgcat::mc "Original checksum does not match for %s, saving a copy to %s"] $fname ${fname}${bak_suffix}]"
    343                     catch {file copy $fname "${fname}${bak_suffix}"}
    344                 }
    345             }
    346 
    347             if { [file exists $fname] || (![catch {file type $fname}] && [file type $fname] == "link") } {
    348                 # Normalize the file path to avoid removing the intermediate
    349                 # symlinks (remove the empty directories instead)
    350                 # The custom realpath proc is necessary because file normalize
    351                 # does not resolve symlinks on OS X < 10.6
    352                 set directory [realpath [file dirname $fname]]
    353                 lappend files [file join $directory [file tail $fname]]
    354    
    355                 # Split out the filename's subpaths and add them to the
    356                 # list as well.
    357                 while { [lsearch -exact $files $directory] == -1 } {
    358                     lappend files $directory
    359                     set directory [file dirname $directory]
    360                 }
    361             }
    362         }
    363    
    364         # Sort the list in reverse order, removing duplicates.
    365         # Since the list is sorted in reverse order, we're sure that directories
    366         # are after their elements.
    367         set files [lsort -decreasing -unique $files]
    368    
    369         # Remove all elements.
    370         _uninstall_list $files
    371    
     305        # Get the full path to the image file
     306        set imagefile [registry::property_retrieve $ref location]
     307        file delete $imagefile
     308        # Try to delete the port's image dir; will fail if there are more image
     309        # files so just ignore the failure
     310        catch {file delete [file dirname $imagefile]}
     311
    372312        if {$use_reg2} {
    373313            registry::entry delete $port
     
    414354}
    415355
    416 proc _uninstall_file {dstfile} {
    417     if { ![catch {set type [file type $dstfile]}] } {
    418         if { $type == "link" } {
    419             ui_debug "uninstalling link: $dstfile"
    420             file delete -- $dstfile
    421         } elseif { [file isdirectory $dstfile] } {
    422             # 0 item means empty.
    423             if { [llength [readdir $dstfile]] == 0 } {
    424                 ui_debug "uninstalling directory: $dstfile"
    425                 file delete -- $dstfile
    426             } else {
    427                 ui_debug "$dstfile is not empty"
    428             }
    429         } else {
    430             ui_debug "uninstalling file: $dstfile"
    431             file delete -- $dstfile
    432         }
    433     } else {
    434         ui_debug "skip missing file: $dstfile"
    435     }
    436 }
    437 
    438 proc _uninstall_list {filelist} {
    439     foreach file $filelist {
    440         _uninstall_file $file
    441     }
    442 }
    443 
    444356# End of registry_uninstall namespace
    445357}
  • trunk/base/src/registry2.0/receipt_flat.tcl

    r66842 r77511  
    102102# Open an existing entry and return its reference number.
    103103proc open_entry {name {version ""} {revision 0} {variants ""} {epoch ""}} {
    104         global macports::registry.installtype
    105104        global macports::registry.path
    106105        variable ref_index
     
    132131                }
    133132        } else {
    134                 # If version wasn't specified, find out the version number.  This will
    135                 # depend on which installtype mode we're in, "direct" or "image"       
     133                # If version wasn't specified, find out the version number.
    136134                if { $version == "" } {
    137                         # xxx: If we're in image mode, we really should have had the
     135                        # xxx: We really should have had the
    138136                        # version given to us.  How should we handle this?
    139137                        set x [glob -nocomplain -directory ${receipt_path} *]
     
    312310# variants                      the variants of the port.
    313311proc write_entry {ref name version {revision 0} {variants ""}} {
    314         global macports::registry.installtype
    315312        variable receipt_$ref
    316313
  • trunk/base/src/registry2.0/receipt_sqlite.tcl

    r67595 r77511  
    125125            set ret [string equal [$ref state] "installed"]
    126126        }
    127         imagedir {
    128             set ret [$ref location]
    129         }
    130127        default {
    131128            if {[catch {set ret [$ref $property]}]} {
     
    153150            }
    154151        }
    155         imagedir {
    156             $ref location $value
    157         }
    158152        default {
    159153            $ref $property $value
     
    168162# What we call version here is version_revision+variants.
    169163proc installed {{name ""} {version ""}} {
    170     global macports::registry.installtype
    171 
    172164        if { $name == "" && $version == "" } {
    173165            set ports [registry::entry imaged]
  • trunk/base/src/registry2.0/registry.tcl

    r70269 r77511  
    4646# This process assembles the directory name and creates a receipt dlist
    4747proc new_entry {name version {revision 0} {variants ""} {epoch 0} } {
    48         global macports::registry.path macports::registry.format macports::registry.installtype macports::prefix
     48        global macports::registry.path macports::registry.format macports::prefix
    4949
    5050       
     
    6161                property_store $ref epoch $epoch
    6262                property_store $ref date [clock seconds]
    63                 property_store $ref installtype ${macports::registry.installtype}
     63                property_store $ref installtype image
    6464                property_store $ref receipt_f ${macports::registry.format}
    65                 if { ${macports::registry.installtype} == "image" } {
    66                         set imagedir [file join ${macports::registry.path} software ${name} ${version}_${revision}${variants}]
    67                         property_store $ref imagedir $imagedir
    68                         property_store $ref active 0
    69                 }
     65        property_store $ref active 0
    7066
    7167                return $ref
     
    460456        set installtype [receipt_flat::property_retrieve $iref installtype]
    461457        lappend proplist installtype $installtype
    462         if { $installtype == "image" } {
    463             set imagedir [receipt_flat::property_retrieve $iref imagedir]
    464             set contents [receipt_flat::property_retrieve $iref contents]
    465             set imagefiles [list]
    466             set idlen [string length $imagedir]
    467             foreach f $contents {
    468                 set fullpath [lindex $f 0]
    469                 # strip image dir from start
     458        set location [receipt_flat::property_retrieve $iref location]
     459        if {$location == "0"} {
     460            set location [receipt_flat::property_retrieve $iref imagedir]
     461        }
     462        set contents [receipt_flat::property_retrieve $iref contents]
     463        set imagefiles [list]
     464        set idlen [string length $location]
     465        foreach f $contents {
     466            set fullpath [lindex $f 0]
     467            # strip image dir from start
     468            if {[string range $fullpath 0 [expr $idlen - 1]] == $location} {
    470469                set path [string range $fullpath $idlen [string length $fullpath]]
    471                 lappend imagefiles $path
     470            } else {
     471                set path $fullpath
    472472            }
    473             lappend proplist imagefiles $imagefiles
    474             set active [receipt_flat::property_retrieve $iref active]
    475             if {$active} {
    476                 set state installed
    477                 lappend proplist files [receipt_flat::port_registered $iname]
    478             } else {
    479                 set state imaged
    480             }
    481         } else {
    482             set imagedir ""
     473            lappend imagefiles $path
     474        }
     475        lappend proplist imagefiles $imagefiles
     476        set active [receipt_flat::property_retrieve $iref active]
     477        if {$active} {
    483478            set state installed
    484479            lappend proplist files [receipt_flat::port_registered $iname]
    485         }
    486         lappend proplist location $imagedir
     480        } else {
     481            set state imaged
     482        }
     483        lappend proplist location $location
    487484        lappend proplist state $state
    488485       
  • trunk/base/tests/test-macports.conf

    r77439 r77511  
    1111portdbformat            sqlite
    1212
    13 # Type of installation to do for ports, "direct" or "image".  See macports.conf(5) and online documentation.
    14 portinstalltype         image
    15 
    1613# Where to find the sources list.
    1714sources_conf            /tmp/macports-tests/opt/local/etc/macports/sources.conf
     
    1916# Where to find global variants definition file (optional)
    2017#variants_conf          /opt/local/etc/macports/variants.conf
    21 
    22 # Create and use binary archive packages for installation/reinstallation ease
    23 portarchivemode         no
    24 
    25 # Where to store/retrieve ports binary archive files
    26 portarchivepath         /tmp/macports-tests/opt/local/var/macports/packages
    2718
    2819# Type of binary archive packages to create when using archive mode
Note: See TracChangeset for help on using the changeset viewer.