Split package1.0 targets

See 06ff92e
This commit is contained in:
Joshua Root
2026-06-30 16:59:18 +10:00
parent 113d9b4236
commit cc211b28c7
25 changed files with 2107 additions and 2083 deletions
+4 -1
View File
@@ -6,7 +6,10 @@ include ../../Mk/macports.autoconf.mk
INSTALLDIR= ${TCL_PACKAGE_PATH}/package1.0
SRCS= package.tcl portdmg.tcl portmdmg.tcl portmpkg.tcl portpkg.tcl \
portarchive.tcl portunarchive.tcl portarchivefetch.tcl
portarchive.tcl portunarchive.tcl portarchivefetch.tcl \
portarchive_run.tcl portarchivefetch_run.tcl portdmg_run.tcl \
portmdmg_run.tcl portmpkg_run.tcl portpkg_run.tcl \
portunarchive_run.tcl
all:: pkgIndex.tcl
+3 -216
View File
@@ -1,225 +1,12 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
# portarchive.tcl
#
# Copyright (c) 2004 Robert Shaw <rshaw@opendarwin.org>
# Copyright (c) 2002 - 2003 Apple Computer, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Computer, Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# # License: see portarchive_run.tcl
package provide portarchive 1.0
package require portutil 1.0
set org.macports.archive [target_new org.macports.archive portarchive::archive_main]
target_provides ${org.macports.archive} archive
target_runtype ${org.macports.archive} always
target_state ${org.macports.archive} no
target_requires ${org.macports.archive} main archivefetch fetch checksum extract patch configure build destroot install
namespace eval portarchive {
}
set_ui_prefix
proc portarchive::archive_command_setup {location archive.type} {
global archive.env archive.cmd archive.pre_args archive.args \
archive.post_args portarchive_hfscompression
set archive.env {}
set archive.cmd {}
set archive.pre_args {}
set archive.args {}
set archive.post_args {}
switch -regex -- ${archive.type} {
aar {
set aa "aa"
if {[catch {set aa [findBinary $aa ${::portutil::autoconf::aa_path}]} errmsg] == 0} {
ui_debug "Using $aa"
set archive.cmd "$aa"
set archive.pre_args "archive -v"
set archive.args "-o [shellescape ${location}] -d ."
} else {
ui_debug $errmsg
return -code error "No '$aa' was found on this system!"
}
}
cp(io|gz) {
set pax "pax"
if {[catch {set pax [findBinary $pax ${::portutil::autoconf::pax_path}]} errmsg] == 0} {
ui_debug "Using $pax"
set archive.cmd "$pax"
set archive.pre_args {-w -v -x cpio}
if {[regexp {z$} ${archive.type}]} {
set gzip "gzip"
if {[catch {set gzip [findBinary $gzip ${::portutil::autoconf::gzip_path}]} errmsg] == 0} {
ui_debug "Using $gzip"
set archive.args {.}
set archive.post_args "| $gzip -c9 > [shellescape ${location}]"
} else {
ui_debug $errmsg
return -code error "No '$gzip' was found on this system!"
}
} else {
set archive.args "-f [shellescape ${location}] ."
}
} else {
ui_debug $errmsg
return -code error "No '$pax' was found on this system!"
}
}
t(ar|bz|lz|xz|gz|mptar) {
set tar "tar"
if {[catch {set tar [findBinary $tar ${::portutil::autoconf::tar_path}]} errmsg] == 0} {
ui_debug "Using $tar"
set archive.cmd "$tar"
set archive.pre_args {-cvf}
if {[regexp {z2?$} ${archive.type}]} {
if {[regexp {bz2?$} ${archive.type}]} {
if {![catch {binaryInPath lbzip2}]} {
set gzip "lbzip2"
} elseif {![catch {binaryInPath pbzip2}]} {
set gzip "pbzip2"
} else {
set gzip "bzip2"
}
set level 9
} elseif {[regexp {lz$} ${archive.type}]} {
set gzip "lzma"
set level ""
} elseif {[regexp {xz$} ${archive.type}]} {
set gzip "xz"
set level 6
} else {
set gzip "gzip"
set level 9
}
if {[info exists ::portutil::autoconf::${gzip}_path]} {
set hint [set ::portutil::autoconf::${gzip}_path]
} else {
set hint ""
}
if {[catch {set gzip [findBinary $gzip $hint]} errmsg] == 0} {
ui_debug "Using $gzip"
set archive.args {- .}
set archive.post_args "| $gzip -c$level > [shellescape ${location}]"
} else {
ui_debug $errmsg
return -code error "No '$gzip' was found on this system!"
}
} else {
if {${archive.type} eq "tmptar"} {
# Pass through tar for hardlink detection and HFS compression,
# but extract without saving the tar file.
set extract_tar {}
if {${portarchive_hfscompression} && [getuid] == 0} {
set extract_tar [find_tar_with_hfscompression]
}
if {$extract_tar ne {}} {
set extract_tar_args {-xvp --hfsCompression -f}
} else {
set extract_tar $tar
set extract_tar_args {-xvpf}
}
set archive.args {- .}
set archive.post_args "| $extract_tar -C $location $extract_tar_args -"
file mkdir $location
} else {
set archive.args "[shellescape ${location}] ."
}
}
} else {
ui_debug $errmsg
return -code error "No '$tar' was found on this system!"
}
}
xar {
set xar "xar"
if {[catch {set xar [findBinary $xar ${::portutil::autoconf::xar_path}]} errmsg] == 0} {
ui_debug "Using $xar"
set archive.cmd "$xar"
set archive.pre_args {-cvf}
set archive.args "[shellescape ${location}] ."
} else {
ui_debug $errmsg
return -code error "No '$xar' was found on this system!"
}
}
zip {
set zip "zip"
if {[catch {set zip [findBinary $zip ${::portutil::autoconf::zip_path}]} errmsg] == 0} {
ui_debug "Using $zip"
set archive.cmd "$zip"
set archive.pre_args {-ry9}
set archive.args "[shellescape ${location}] ."
} else {
ui_debug $errmsg
return -code error "No '$zip' was found on this system!"
}
}
}
return 0
}
proc portarchive::archive_main {args} {
set location [get_portimage_path]
if {[file isfile $location]} {
ui_debug "Archive already exists at $location"
return 0
}
set imagedir [file rootname $location]
if {![file isdirectory $imagedir]} {
# Query the registry for the definitive location
global subport version revision portvariants
set regref [registry_open $subport $version $revision $portvariants ""]
set imagedir [registry_prop_retr $regref location]
if {[file isfile $imagedir]} {
ui_debug "Archive already exists at $imagedir"
return 0
}
if {![file isdirectory $imagedir]} {
ui_error "No port image found at: $imagedir"
return -code error "Port image missing"
}
}
global UI_PREFIX portarchivetype archive.dir
# Now create the archive
archiveTypeIsSupported $portarchivetype
archive_command_setup $location $portarchivetype
set archive.dir $imagedir
ui_info "$UI_PREFIX [format [msgcat::mc "Creating %s"] $location]"
if {[getuid] == 0 && [geteuid] != 0} {
elevateToRoot "archive"
}
command_exec archive
ui_info "$UI_PREFIX [format [msgcat::mc "Archive %s packaged"] $location]"
return 0
}
target_runpkg ${org.macports.archive} portarchive_run
+215
View File
@@ -0,0 +1,215 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
#
# Copyright (c) 2004 Robert Shaw <rshaw@opendarwin.org>
# Copyright (c) 2002 - 2003 Apple Computer, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Computer, Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
package provide portarchive_run 1.0
namespace eval portarchive {
proc archive_command_setup {location archive.type} {
global archive.env archive.cmd archive.pre_args archive.args \
archive.post_args portarchive_hfscompression
set archive.env {}
set archive.cmd {}
set archive.pre_args {}
set archive.args {}
set archive.post_args {}
switch -regex -- ${archive.type} {
aar {
set aa "aa"
if {[catch {set aa [findBinary $aa ${::portutil::autoconf::aa_path}]} errmsg] == 0} {
ui_debug "Using $aa"
set archive.cmd "$aa"
set archive.pre_args "archive -v"
set archive.args "-o [shellescape ${location}] -d ."
} else {
ui_debug $errmsg
return -code error "No '$aa' was found on this system!"
}
}
cp(io|gz) {
set pax "pax"
if {[catch {set pax [findBinary $pax ${::portutil::autoconf::pax_path}]} errmsg] == 0} {
ui_debug "Using $pax"
set archive.cmd "$pax"
set archive.pre_args {-w -v -x cpio}
if {[regexp {z$} ${archive.type}]} {
set gzip "gzip"
if {[catch {set gzip [findBinary $gzip ${::portutil::autoconf::gzip_path}]} errmsg] == 0} {
ui_debug "Using $gzip"
set archive.args {.}
set archive.post_args "| $gzip -c9 > [shellescape ${location}]"
} else {
ui_debug $errmsg
return -code error "No '$gzip' was found on this system!"
}
} else {
set archive.args "-f [shellescape ${location}] ."
}
} else {
ui_debug $errmsg
return -code error "No '$pax' was found on this system!"
}
}
t(ar|bz|lz|xz|gz|mptar) {
set tar "tar"
if {[catch {set tar [findBinary $tar ${::portutil::autoconf::tar_path}]} errmsg] == 0} {
ui_debug "Using $tar"
set archive.cmd "$tar"
set archive.pre_args {-cvf}
if {[regexp {z2?$} ${archive.type}]} {
if {[regexp {bz2?$} ${archive.type}]} {
if {![catch {binaryInPath lbzip2}]} {
set gzip "lbzip2"
} elseif {![catch {binaryInPath pbzip2}]} {
set gzip "pbzip2"
} else {
set gzip "bzip2"
}
set level 9
} elseif {[regexp {lz$} ${archive.type}]} {
set gzip "lzma"
set level ""
} elseif {[regexp {xz$} ${archive.type}]} {
set gzip "xz"
set level 6
} else {
set gzip "gzip"
set level 9
}
if {[info exists ::portutil::autoconf::${gzip}_path]} {
set hint [set ::portutil::autoconf::${gzip}_path]
} else {
set hint ""
}
if {[catch {set gzip [findBinary $gzip $hint]} errmsg] == 0} {
ui_debug "Using $gzip"
set archive.args {- .}
set archive.post_args "| $gzip -c$level > [shellescape ${location}]"
} else {
ui_debug $errmsg
return -code error "No '$gzip' was found on this system!"
}
} else {
if {${archive.type} eq "tmptar"} {
# Pass through tar for hardlink detection and HFS compression,
# but extract without saving the tar file.
set extract_tar {}
if {${portarchive_hfscompression} && [getuid] == 0} {
set extract_tar [find_tar_with_hfscompression]
}
if {$extract_tar ne {}} {
set extract_tar_args {-xvp --hfsCompression -f}
} else {
set extract_tar $tar
set extract_tar_args {-xvpf}
}
set archive.args {- .}
set archive.post_args "| $extract_tar -C $location $extract_tar_args -"
file mkdir $location
} else {
set archive.args "[shellescape ${location}] ."
}
}
} else {
ui_debug $errmsg
return -code error "No '$tar' was found on this system!"
}
}
xar {
set xar "xar"
if {[catch {set xar [findBinary $xar ${::portutil::autoconf::xar_path}]} errmsg] == 0} {
ui_debug "Using $xar"
set archive.cmd "$xar"
set archive.pre_args {-cvf}
set archive.args "[shellescape ${location}] ."
} else {
ui_debug $errmsg
return -code error "No '$xar' was found on this system!"
}
}
zip {
set zip "zip"
if {[catch {set zip [findBinary $zip ${::portutil::autoconf::zip_path}]} errmsg] == 0} {
ui_debug "Using $zip"
set archive.cmd "$zip"
set archive.pre_args {-ry9}
set archive.args "[shellescape ${location}] ."
} else {
ui_debug $errmsg
return -code error "No '$zip' was found on this system!"
}
}
}
return 0
}
proc archive_main {args} {
set location [get_portimage_path]
if {[file isfile $location]} {
ui_debug "Archive already exists at $location"
return 0
}
set imagedir [file rootname $location]
if {![file isdirectory $imagedir]} {
# Query the registry for the definitive location
global subport version revision portvariants
set regref [registry_open $subport $version $revision $portvariants ""]
set imagedir [registry_prop_retr $regref location]
if {[file isfile $imagedir]} {
ui_debug "Archive already exists at $imagedir"
return 0
}
if {![file isdirectory $imagedir]} {
ui_error "No port image found at: $imagedir"
return -code error "Port image missing"
}
}
global UI_PREFIX portarchivetype archive.dir
# Now create the archive
archiveTypeIsSupported $portarchivetype
archive_command_setup $location $portarchivetype
set archive.dir $imagedir
ui_info "$UI_PREFIX [format [msgcat::mc "Creating %s"] $location]"
if {[getuid] == 0 && [geteuid] != 0} {
elevateToRoot "archive"
}
command_exec archive
ui_info "$UI_PREFIX [format [msgcat::mc "Archive %s packaged"] $location]"
return 0
}
}
File diff suppressed because it is too large Load Diff
+486
View File
@@ -0,0 +1,486 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
#
# Copyright (c) 2002 - 2003 Apple Inc.
# Copyright (c) 2004 - 2016, 2018 The MacPorts Project
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
package provide portarchivefetch_run 1.0
package require fetch_common 1.0
namespace eval portarchivefetch {
# Checks possible archive files to assemble url lists for later fetching
proc checkarchivefiles {urls} {
global all_archive_files archivefetch.fulldestpath archive_sites portdbpath
upvar $urls fetch_urls
# Define archive directory path
set archivefetch.fulldestpath [file join ${portdbpath} incoming/verified]
set archive.rootname [file rootname [get_portimage_name]]
foreach entry ${archive_sites} {
# the archive type is used as a tag
set type [lindex [split $entry :] end]
if {![info exists seen($type)]} {
set archive.file "${archive.rootname}.${type}"
lappend all_archive_files ${archive.file}
lappend fetch_urls $type ${archive.file}
set seen($type) 1
}
}
}
# Perform the full checksites/checkarchivefiles sequence.
proc checkfiles {urls} {
upvar $urls fetch_urls
portfetch::checksites [list archive_sites [list {} ARCHIVE_SITE_LOCAL]] \
[get_full_archive_sites_path]
checkarchivefiles fetch_urls
}
# Return all signature types that may be used with the configured sites
proc get_all_sigtypes {} {
global archive_sites portfetch::mirror_sites::archive_sigtype
set sigtypes [dict create]
foreach site $archive_sites {
# If the entry is a URL rather than a mirror site name then
# this will actually extract the URL scheme, but that's OK
# since it won't exist in the array and will be skipped.
set site [lindex [split $site :] 0]
if {[info exists archive_sigtype($site)]} {
dict set sigtypes $archive_sigtype($site) 1
}
}
if {[dict size $sigtypes] > 0} {
return [dict keys $sigtypes]
} else {
# Legacy default
return rmd160
}
}
# Verify signature for a fetched archive using any of the public keys
# set for each archive site or in pubkeys.conf.
proc verify_signature {archive_path sig_path} {
global archive_sites archivefetch.pubkeys \
portfetch::mirror_sites::archive_sigtype \
portfetch::mirror_sites::archive_pubkey
# Chop off the .TMP before getting extension
set archivetype [file extension [file rootname $archive_path]]
set sigtype [file extension $sig_path]
set pubkeys [dict create]
foreach site $archive_sites {
set site_split [split $site :]
set site [lindex $site_split 0]
set tag [lindex $site_split end]
if {".$tag" eq $archivetype && [info exists archive_sigtype($site)]
&& [info exists archive_pubkey($site)]
&& ".$archive_sigtype($site)" eq $sigtype
} then {
# Use dict to avoid duplicates if a key is added in both
# the archive site definition and pubkeys.conf.
dict set pubkeys $archive_pubkey($site) 1
}
}
foreach pubkey ${archivefetch.pubkeys} {
set keytype [file extension $pubkey]
if {($keytype eq ".pub" && $sigtype eq ".sig") || ($keytype eq ".pem" && $sigtype eq ".rmd160")} {
dict set pubkeys $pubkey 1
}
}
# Succeed if the signature can be verified with any of the keys
foreach pubkey [dict keys $pubkeys] {
if {($sigtype eq ".sig" && [verify_signature_signify $archive_path $pubkey $sig_path])
|| ($sigtype eq ".rmd160" && [verify_signature_openssl $archive_path $pubkey $sig_path])
} then {
return 1
}
}
return 0
}
# Perform a standard fetch, assembling fetch urls from
# the listed url variable and associated archive file
proc fetchfiles {{async no} args} {
global UI_PREFIX archivefetch.fulldestpath archivefetch.user \
archivefetch.password archivefetch.use_epsv \
archivefetch.ignore_sslcert archive.subdir portverbose \
ports_binary_only portdbpath force_archive_refresh
variable archivefetch_urls
variable ::portfetch::urlmap
variable async_job
variable async_logid
if {[info exists async_job]} {
if {$async} {
# Async fetch already started
return 0
}
lassign $async_job jobid tmpfiles
unset async_job
# Fetch was started asynchronously, wait for job to finish
if {![curlwrap_async_is_complete $jobid]} {
# Display progress for this fetch while waiting for it to finish
curlwrap_async_show_progress $jobid
# Loop with a reasonable timeout so we don't wait too long
# to handle events like signals.
while {![curlwrap_async_is_complete $jobid 500]} {}
}
lassign [curlwrap_async_result $jobid] status result
if {$status != 0} {
file delete {*}$tmpfiles
if {[tbool ports_binary_only] || [_archive_available]} {
error "Failed to fetch archive for [option subport]: $result"
} else {
variable attempted 1
return 0
}
}
set async_done 1
} else {
set async_done 0
}
if {![file isdirectory ${archivefetch.fulldestpath}]} {
if {[catch {file mkdir ${archivefetch.fulldestpath}} result]} {
elevateToRoot "archivefetch"
set elevated yes
if {[catch {file mkdir ${archivefetch.fulldestpath}} result]} {
return -code error [format [msgcat::mc "Unable to create archive path: %s"] $result]
}
}
}
set incoming_path [file join ${portdbpath} incoming]
chownAsRoot $incoming_path
if {[info exists elevated] && $elevated eq "yes"} {
dropPrivileges
}
set fetch_options [list]
set credentials {}
if {[string length ${archivefetch.user}] || [string length ${archivefetch.password}]} {
set credentials ${archivefetch.user}:${archivefetch.password}
}
if {${archivefetch.use_epsv} ne "yes"} {
lappend fetch_options "--disable-epsv"
}
if {${archivefetch.ignore_sslcert} ne "no"} {
lappend fetch_options "--ignore-ssl-cert"
}
if {!$async} {
if {$portverbose eq "yes"} {
lappend fetch_options "--progress"
lappend fetch_options "builtin"
} else {
lappend fetch_options "--progress"
lappend fetch_options "ui_progress_download"
}
}
set sorted no
set include_installed [expr {![tbool force_archive_refresh]}]
set existing_archive [find_portarchive_path $include_installed]
if {$existing_archive eq "" && $include_installed
&& [file isdirectory [file rootname [get_portimage_path]]]} {
set existing_archive yes
}
foreach {url_var archive} $archivefetch_urls {
if {![file isfile ${archivefetch.fulldestpath}/${archive}] && $existing_archive eq ""} {
if {$async} {
# Skip if something else is already fetching this file
if {[curlwrap_async_file_is_in_progress ${incoming_path}/${archive}]} {
return 0
}
} elseif {!$async_done} {
ui_info "$UI_PREFIX [format [msgcat::mc "%s doesn't seem to exist in %s"] $archive ${archivefetch.fulldestpath}]"
}
if {![file writable ${archivefetch.fulldestpath}]} {
return -code error [format [msgcat::mc "%s must be writable"] ${archivefetch.fulldestpath}]
}
if {![file writable $incoming_path]} {
return -code error [format [msgcat::mc "%s must be writable"] $incoming_path]
}
if {!$sorted} {
portfetch::sortsites archivefetch_urls archive_sites
set sorted yes
}
if {![info exists urlmap($url_var)]} {
ui_error [format [msgcat::mc "No defined site for tag: %s, using archive_sites"] $url_var]
set urlmap($url_var) $urlmap(archive_sites)
}
if {![info exists sigtypes]} {
set sigtypes [get_all_sigtypes]
}
set archive_tmp_path ${incoming_path}/${archive}.TMP
set failed_sites 0
set archive_fetched [expr {$async_done ? [file isfile $archive_tmp_path] : 0}]
set lastError ""
set sig_fetched 0
if {$async_done} {
foreach sigtype $sigtypes {
set signature ${incoming_path}/${archive}.${sigtype}
if {[file isfile $signature] && [file size $signature] > 0} {
set sig_fetched 1
break
}
}
}
if {$async} {
file delete -force $archive_tmp_path
touch $archive_tmp_path
chownAsRoot $archive_tmp_path
set tmpfiles [list $archive_tmp_path]
foreach sigtype $sigtypes {
set sigpath ${incoming_path}/${archive}.${sigtype}
lappend tmpfiles $sigpath
file delete -force $sigpath
touch $sigpath
chownAsRoot $sigpath
}
if {[tbool ports_binary_only] || [_archive_available]} {
set this_urlmap $urlmap($url_var)
set maxfails 0
} else {
set this_urlmap [lrange $urlmap($url_var) 0 2]
set maxfails 3
}
set jobid [curlwrap_async fetch_archive $credentials $fetch_options $this_urlmap \
[lmap site $this_urlmap {portfetch::assemble_url \
[expr {[string index $site end] eq "/" ? $site : "${site}/"}]${archive.subdir} $archive}] \
${incoming_path}/${archive} $sigtypes $maxfails $async_logid]
set async_job [list $jobid $tmpfiles]
return 0
} else {
foreach site $urlmap($url_var) {
set orig_site $site
if {[string index $site end] ne "/"} {
append site /
}
append site ${archive.subdir}
set file_url [portfetch::assemble_url $site $archive]
# fetch archive
if {!$archive_fetched} {
ui_msg "$UI_PREFIX [format [msgcat::mc "Attempting to fetch %s from %s"] $archive ${site}]"
try {
curlwrap fetch $orig_site $credentials {*}$fetch_options $file_url $archive_tmp_path
set archive_fetched 1
} trap {POSIX SIG SIGINT} {_ eOptions} {
ui_debug [msgcat::mc "Aborted fetching archive due to SIGINT"]
file delete -force $archive_tmp_path
throw [dict get $eOptions -errorcode] [dict get $eOptions -errorinfo]
} trap {POSIX SIG SIGTERM} {_ eOptions} {
ui_debug [msgcat::mc "Aborted fetching archive due to SIGTERM"]
file delete -force $archive_tmp_path
throw [dict get $eOptions -errorcode] [dict get $eOptions -errorinfo]
} on error {eMessage} {
ui_debug [msgcat::mc "Fetching archive failed: %s" $eMessage]
set lastError $eMessage
file delete -force $archive_tmp_path
incr failed_sites
if {$failed_sites > 2 && ![tbool ports_binary_only] && ![_archive_available]} {
break
}
}
}
# fetch signature
if {$archive_fetched && !$sig_fetched} {
# TODO: record signature type for each URL somehow
foreach sigtype $sigtypes {
set signature ${incoming_path}/${archive}.${sigtype}
ui_msg "$UI_PREFIX [format [msgcat::mc "Attempting to fetch %s from %s"] ${archive}.${sigtype} $site]"
try {
curlwrap fetch $orig_site $credentials {*}$fetch_options ${file_url}.${sigtype} $signature
set sig_fetched 1
break
} trap {POSIX SIG SIGINT} {_ eOptions} {
ui_debug [msgcat::mc "Aborted fetching archive due to SIGINT"]
file delete -force $archive_tmp_path $signature
throw [dict get $eOptions -errorcode] [dict get $eOptions -errorinfo]
} trap {POSIX SIG SIGTERM} {_ eOptions} {
ui_debug [msgcat::mc "Aborted fetching archive due to SIGTERM"]
file delete -force $archive_tmp_path $signature
throw [dict get $eOptions -errorcode] [dict get $eOptions -errorinfo]
} on error {eMessage} {
ui_debug [msgcat::mc "Fetching archive signature failed: %s" $eMessage]
set lastError $eMessage
file delete -force $signature
}
}
if {$sig_fetched} {
break
}
}
}
if {$archive_fetched && $sig_fetched} {
set verified [verify_signature $archive_tmp_path $signature]
file delete -force $signature
if {!$verified} {
# fall back to building from source (or error out later if binary only mode)
ui_warn "Failed to verify signature for archive!"
file delete -force $archive_tmp_path
break
} elseif {[catch {file rename -force $archive_tmp_path ${archivefetch.fulldestpath}/${archive}} result]} {
ui_debug "$::errorInfo"
return -code error "Failed to move downloaded archive into place: $result"
}
set archive_exists 1
break
}
}
} elseif {$async} {
return 0
} else {
set archive_exists 1
break
}
}
if {[info exists archive_exists]} {
# modify state file to skip remaining phases up to destroot
global target_state_fd
foreach target {archivefetch fetch checksum extract patch configure build destroot} {
write_statefile target "org.macports.${target}" $target_state_fd
}
# Cancel any async distfile fetch that may be in progress
catch {portfetch::_async_cleanup}
return 0
}
if {[tbool ports_binary_only] || [_archive_available]} {
global version revision portvariants
if {[info exists lastError] && $lastError ne ""} {
error [msgcat::mc "version @${version}_${revision}${portvariants}: %s" $lastError]
} else {
error "version @${version}_${revision}${portvariants}"
}
} else {
variable attempted 1
return 0
}
}
# Check if all archives are already present.
proc archives_present {} {
global archivefetch.fulldestpath force_archive_refresh
variable archivefetch_urls
set include_installed [expr {![tbool force_archive_refresh]}]
set existing_archive [find_portarchive_path $include_installed]
if {$existing_archive eq "" && $include_installed
&& [file isdirectory [file rootname [get_portimage_path]]]} {
set existing_archive yes
}
foreach {url_var archive} $archivefetch_urls {
if {![file isfile ${archivefetch.fulldestpath}/${archive}] && $existing_archive eq ""} {
return 0
}
}
return 1
}
proc start_pings {} {
variable archivefetch_urls
variable ::portfetch::urlmap
# ping hosts that are not in the cache yet
foreach {url_var archive} $archivefetch_urls {
if {[info exists urlmap($url_var)]} {
async_ping_start $urlmap($url_var)
}
}
# wait until we have a result for at least the main mirror
global archive_sites
if {[lsearch $archive_sites macports_archives::*] != -1} {
set mirrors macports_archives
} else {
set mirrors [lindex [split [lindex $archive_sites 0] :] 0]
}
if {[info exists ::portfetch::mirror_sites::sites($mirrors)]} {
set primary_mirror [lindex $::portfetch::mirror_sites::sites($mirrors) 0]
if {$primary_mirror ne {}} {
wait_for_pingtime $primary_mirror
}
}
}
proc check_destroot_done {} {
global destroot
set ret 0
if {[file isdirectory $destroot]} {
global target_state_fd
if {![info exists target_state_fd]} {
set target_state_fd [open_statefile]
set closefd 1
}
set ret [check_statefile target org.macports.destroot $target_state_fd]
if {[info exists closefd]} {
close $target_state_fd
unset target_state_fd
}
}
return $ret
}
proc _archivefetch_start {quiet} {
variable archivefetch_urls
global UI_PREFIX subport all_archive_files \
ports_source_only ports_binary_only
if {![tbool ports_source_only] && ([tbool ports_binary_only] ||
![check_destroot_done])} {
checkfiles archivefetch_urls
}
if {[info exists all_archive_files] && [llength $all_archive_files] > 0} {
if {![archives_present]} {
start_pings
}
if {!$quiet} {
ui_msg "$UI_PREFIX [format [msgcat::mc "Fetching archive for %s"] $subport]"
}
} elseif {[tbool ports_binary_only]} {
error "Binary-only mode requested with no usable archive sites configured"
}
portfetch::check_dns
}
proc archivefetch_start {args} {
_archivefetch_start no
}
# Main archive fetch routine
# just calls the standard fetchfiles procedure
proc archivefetch_main {args} {
global all_archive_files
if {[info exists all_archive_files] && [llength $all_archive_files] > 0} {
# Fetch the files
fetchfiles
}
return 0
}
}
+3 -94
View File
@@ -1,102 +1,11 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
# portdmg.tcl
#
# Copyright (c) 2007, 2009-2011 The MacPorts Project
# Copyright (c) 2003, 2005 Apple Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# License: see portdmg_run.tcl
package provide portdmg 1.0
package require portutil 1.0
set org.macports.dmg [target_new org.macports.dmg portdmg::dmg_main]
target_runtype ${org.macports.dmg} always
target_provides ${org.macports.dmg} dmg
target_requires ${org.macports.dmg} pkg
namespace eval portdmg {
}
set_ui_prefix
proc portdmg::dmg_main {args} {
global subport version revision UI_PREFIX
ui_msg "$UI_PREFIX [format [msgcat::mc "Creating disk image for %s-%s"] ${subport} ${version}_${revision}]"
if {[getuid] == 0 && [geteuid] != 0} {
seteuid 0; setegid 0
}
return [package_dmg $subport $version $revision]
}
proc portdmg::package_dmg {portname portversion portrevision} {
global UI_PREFIX package.destpath portpath \
os.arch os.major
set imagename [portpkg::image_name ${portname} ${portversion} ${portrevision}]
set tmp_image ${package.destpath}/${imagename}.tmp.dmg
set final_image ${package.destpath}/${imagename}.dmg
set pkgpath ${package.destpath}/${imagename}.pkg
if {[file readable $final_image] && ([file mtime ${final_image}] >= [file mtime ${portpath}/Portfile])} {
ui_msg "$UI_PREFIX [format [msgcat::mc "Disk Image for %s version %s is up-to-date"] ${portname} ${portversion}_${portrevision}]"
return 0
}
# partition for .dmg
if {${os.arch} in {arm i386}} {
# GUID_partition_scheme
set subdev 1
} else {
# Apple_partition_scheme (Apple_partition_map is at s1)
set subdev 2
}
if {![file isdirectory $pkgpath]} {
file mkdir ${package.destpath}/${imagename}
file copy $pkgpath ${package.destpath}/${imagename}
set pkgpath ${package.destpath}/${imagename}
}
set hdiutil [findBinary hdiutil $::portutil::autoconf::hdiutil_path]
if {[system "$hdiutil create -quiet -fs HFS+ -volname [shellescape ${imagename}] -srcfolder [shellescape ${pkgpath}] [shellescape ${tmp_image}]"] ne ""} {
return -code error [format [msgcat::mc "Failed to create temporary image: %s"] ${imagename}]
}
if {[system "$hdiutil convert [shellescape ${tmp_image}] -format UDCO -o [shellescape ${final_image}] -quiet"] ne ""} {
return -code error [format [msgcat::mc "Failed to convert to final image: %s"] ${final_image}]
}
# internet-enable verb removed from hdiutil in Catalina
if {${os.major} < 19 && [system "$hdiutil internet-enable -quiet -yes [shellescape ${final_image}]"] ne ""} {
return -code error [format [msgcat::mc "Failed to internet-enable: %s"] ${final_image}]
}
file delete -force "${tmp_image}"
return 0
}
target_runpkg ${org.macports.dmg} portdmg_run
+94
View File
@@ -0,0 +1,94 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
#
# Copyright (c) 2007, 2009-2011 The MacPorts Project
# Copyright (c) 2003, 2005 Apple Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
package provide portdmg_run 1.0
package require portpkg_run
namespace eval portdmg {
proc dmg_main {args} {
global subport version revision UI_PREFIX
ui_msg "$UI_PREFIX [format [msgcat::mc "Creating disk image for %s-%s"] ${subport} ${version}_${revision}]"
if {[getuid] == 0 && [geteuid] != 0} {
seteuid 0; setegid 0
}
return [package_dmg $subport $version $revision]
}
proc package_dmg {portname portversion portrevision} {
global UI_PREFIX package.destpath portpath \
os.arch os.major
set imagename [portpkg::image_name ${portname} ${portversion} ${portrevision}]
set tmp_image ${package.destpath}/${imagename}.tmp.dmg
set final_image ${package.destpath}/${imagename}.dmg
set pkgpath ${package.destpath}/${imagename}.pkg
if {[file readable $final_image] && ([file mtime ${final_image}] >= [file mtime ${portpath}/Portfile])} {
ui_msg "$UI_PREFIX [format [msgcat::mc "Disk Image for %s version %s is up-to-date"] ${portname} ${portversion}_${portrevision}]"
return 0
}
# partition for .dmg
if {${os.arch} in {arm i386}} {
# GUID_partition_scheme
set subdev 1
} else {
# Apple_partition_scheme (Apple_partition_map is at s1)
set subdev 2
}
if {![file isdirectory $pkgpath]} {
file mkdir ${package.destpath}/${imagename}
file copy $pkgpath ${package.destpath}/${imagename}
set pkgpath ${package.destpath}/${imagename}
}
set hdiutil [findBinary hdiutil $::portutil::autoconf::hdiutil_path]
if {[system "$hdiutil create -quiet -fs HFS+ -volname [shellescape ${imagename}] -srcfolder [shellescape ${pkgpath}] [shellescape ${tmp_image}]"] ne ""} {
return -code error [format [msgcat::mc "Failed to create temporary image: %s"] ${imagename}]
}
if {[system "$hdiutil convert [shellescape ${tmp_image}] -format UDCO -o [shellescape ${final_image}] -quiet"] ne ""} {
return -code error [format [msgcat::mc "Failed to convert to final image: %s"] ${final_image}]
}
# internet-enable verb removed from hdiutil in Catalina
if {${os.major} < 19 && [system "$hdiutil internet-enable -quiet -yes [shellescape ${final_image}]"] ne ""} {
return -code error [format [msgcat::mc "Failed to internet-enable: %s"] ${final_image}]
}
file delete -force "${tmp_image}"
return 0
}
}
+3 -94
View File
@@ -1,102 +1,11 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
# portmdmg.tcl
#
# Copyright (c) 2005, 2007-2013 The MacPorts Project
# Copyright (c) 2003-2004 Apple Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# License: see portmdmg_run.tcl
package provide portmdmg 1.0
package require portutil 1.0
set org.macports.mdmg [target_new org.macports.mdmg portmdmg::mdmg_main]
target_runtype ${org.macports.mdmg} always
target_provides ${org.macports.mdmg} mdmg
target_requires ${org.macports.mdmg} mpkg
namespace eval portmdmg {
}
set_ui_prefix
proc portmdmg::mdmg_main {args} {
global subport version revision UI_PREFIX
ui_msg "$UI_PREFIX [format [msgcat::mc "Creating disk image for %s-%s"] ${subport} ${version}]"
if {[getuid] == 0 && [geteuid] != 0} {
seteuid 0; setegid 0
}
return [package_mdmg $subport $version $revision]
}
proc portmdmg::package_mdmg {portname portversion portrevision} {
global UI_PREFIX package.destpath portpath \
os.arch os.major
set imagename [portpkg::image_name ${portname} ${portversion} ${portrevision}]
set tmp_image ${package.destpath}/${imagename}.tmp.dmg
set final_image ${package.destpath}/${imagename}.dmg
set mpkgpath [portmpkg::mpkg_path $portname $portversion $portrevision]
if {[file readable $final_image] && ([file mtime ${final_image}] >= [file mtime ${portpath}/Portfile])} {
ui_msg "$UI_PREFIX [format [msgcat::mc "Disk Image for %s version %s is up-to-date"] ${portname} ${portversion}]"
return 0
}
# partition for .dmg
if {${os.arch} in {arm i386}} {
# GUID_partition_scheme
set subdev 1
} else {
# Apple_partition_scheme (Apple_partition_map is at s1)
set subdev 2
}
if {![file isdirectory $mpkgpath]} {
file mkdir ${package.destpath}/${imagename}
file copy $mpkgpath ${package.destpath}/${imagename}
set mpkgpath ${package.destpath}/${imagename}
}
set hdiutil [findBinary hdiutil $::portutil::autoconf::hdiutil_path]
if {[system "$hdiutil create -quiet -fs HFS+ -volname ${imagename} -srcfolder [shellescape ${mpkgpath}] [shellescape ${tmp_image}]"] ne ""} {
return -code error [format [msgcat::mc "Failed to create temporary image: %s"] ${imagename}]
}
if {[system "$hdiutil convert [shellescape ${tmp_image}] -format UDCO -o [shellescape ${final_image}] -quiet"] ne ""} {
return -code error [format [msgcat::mc "Failed to convert to final image: %s"] ${final_image}]
}
# internet-enable verb removed from hdiutil in Catalina
if {${os.major} < 19 && [system "$hdiutil internet-enable -quiet -yes [shellescape ${final_image}]"] ne ""} {
return -code error [format [msgcat::mc "Failed to internet-enable: %s"] ${final_image}]
}
file delete -force "${tmp_image}"
return 0
}
target_runpkg ${org.macports.mdmg} portmdmg_run
+95
View File
@@ -0,0 +1,95 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
#
# Copyright (c) 2005, 2007-2013 The MacPorts Project
# Copyright (c) 2003-2004 Apple Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
package provide portmdmg_run 1.0
package require portpkg_run
package require portmpkg_run
namespace eval portmdmg {
proc mdmg_main {args} {
global subport version revision UI_PREFIX
ui_msg "$UI_PREFIX [format [msgcat::mc "Creating disk image for %s-%s"] ${subport} ${version}]"
if {[getuid] == 0 && [geteuid] != 0} {
seteuid 0; setegid 0
}
return [package_mdmg $subport $version $revision]
}
proc package_mdmg {portname portversion portrevision} {
global UI_PREFIX package.destpath portpath \
os.arch os.major
set imagename [portpkg::image_name ${portname} ${portversion} ${portrevision}]
set tmp_image ${package.destpath}/${imagename}.tmp.dmg
set final_image ${package.destpath}/${imagename}.dmg
set mpkgpath [portmpkg::mpkg_path $portname $portversion $portrevision]
if {[file readable $final_image] && ([file mtime ${final_image}] >= [file mtime ${portpath}/Portfile])} {
ui_msg "$UI_PREFIX [format [msgcat::mc "Disk Image for %s version %s is up-to-date"] ${portname} ${portversion}]"
return 0
}
# partition for .dmg
if {${os.arch} in {arm i386}} {
# GUID_partition_scheme
set subdev 1
} else {
# Apple_partition_scheme (Apple_partition_map is at s1)
set subdev 2
}
if {![file isdirectory $mpkgpath]} {
file mkdir ${package.destpath}/${imagename}
file copy $mpkgpath ${package.destpath}/${imagename}
set mpkgpath ${package.destpath}/${imagename}
}
set hdiutil [findBinary hdiutil $::portutil::autoconf::hdiutil_path]
if {[system "$hdiutil create -quiet -fs HFS+ -volname ${imagename} -srcfolder [shellescape ${mpkgpath}] [shellescape ${tmp_image}]"] ne ""} {
return -code error [format [msgcat::mc "Failed to create temporary image: %s"] ${imagename}]
}
if {[system "$hdiutil convert [shellescape ${tmp_image}] -format UDCO -o [shellescape ${final_image}] -quiet"] ne ""} {
return -code error [format [msgcat::mc "Failed to convert to final image: %s"] ${final_image}]
}
# internet-enable verb removed from hdiutil in Catalina
if {${os.major} < 19 && [system "$hdiutil internet-enable -quiet -yes [shellescape ${final_image}]"] ne ""} {
return -code error [format [msgcat::mc "Failed to internet-enable: %s"] ${final_image}]
}
file delete -force "${tmp_image}"
return 0
}
}
+4 -335
View File
@@ -1,345 +1,14 @@
# et:ts=4
# portmpkg.tcl
#
# Copyright (c) 2005, 2007 - 2013 The MacPorts Project
# Copyright (c) 2002 - 2004 Apple Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
# License: see portmpkg_run.tcl
package provide portmpkg 1.0
package require portutil 1.0
set org.macports.mpkg [target_new org.macports.mpkg portmpkg::mpkg_main]
target_runtype ${org.macports.mpkg} always
target_provides ${org.macports.mpkg} mpkg
target_requires ${org.macports.mpkg} pkg
namespace eval portmpkg {
}
target_runpkg ${org.macports.mpkg} portmpkg_run
# define options
options package.destpath package.flat
set_ui_prefix
proc portmpkg::mpkg_main {args} {
global package.flat os.major package.destpath subport epoch version revision
if {!${package.flat} || ${os.major} < 10} {
# Make sure the destination path exists.
file mkdir ${package.destpath}
}
return [package_mpkg $subport $epoch $version $revision]
}
proc portmpkg::archcheck {mport dependent_mport} {
set portinfo [mport_info $mport]
if {[dict exists $portinfo installs_libs] && ![dict get $portinfo installs_libs]} {
return 1
}
set skip_archcheck [_mportkey $dependent_mport depends_skip_archcheck]
if {[lsearch -exact -nocase $skip_archcheck [dict get $portinfo name]] >= 0} {
return 1
}
set required_archs [_mport_archs $dependent_mport]
if {[_mport_supports_archs $mport $required_archs]} {
return 1
}
# Since only depends_lib and depends_run are considered in mpkg,
# there's no need to check if the dep type needs matching archs.
return 0
}
proc portmpkg::get_dependencies {mport dep_map base_options variations} {
set portinfo [mport_info $mport]
set portname [dict get $portinfo name]
if {![dict exists $dep_map $portname]} {
# guard against infinite recursion with circular dependencies
dict set dep_map $portname {}
}
# get the union of depends_run and depends_lib
set depends [list]
if {[dict exists $portinfo depends_run]} { lappend depends {*}[dict get $portinfo depends_run] }
if {[dict exists $portinfo depends_lib]} { lappend depends {*}[dict get $portinfo depends_lib] }
foreach depspec $depends {
set dep [_get_dep_port $depspec]
if {$dep ne ""} {
# Get the dep's mport handle, opening it if needed
if {[catch {set res [mport_lookup $dep]} error]} {
ui_debug $::errorInfo
return -code error "port lookup failed: $error"
}
# depname will have canonical case and so can safely be
# used as the dict key
lassign $res depname dep_portinfo
set add_deps 0
if {[dict exists $dep_map $depname]} {
set dep_map_entry [dict get $dep_map $depname]
if {$dep_map_entry eq {}} {
ui_debug "Circular dependency involving $depname"
continue
}
set dep_mport [lindex $dep_map_entry 0]
# The dep has already been processed, so there's
# nothing to do in this case if the archs match.
} else {
set options $base_options
dict set options subport $depname
exec_with_available_privileges {
set dep_mport [mport_open [dict get $dep_portinfo porturl] $options $variations]
}
set add_deps 1
}
# Reopen with +universal if possible if the archs aren't compatible
if {![archcheck $dep_mport $mport] && ![dict exists $variations universal]} {
set check_portinfo [mport_info $dep_mport]
set dep_archs [_mport_archs $dep_mport]
if {[dict exists $check_portinfo variants] && "universal" in [dict get $check_portinfo variants]
&& [llength $dep_archs] < 2} {
mport_close $dep_mport
set uvariations $variations
dict set uvariations universal +
set options $base_options
dict set options subport $depname
exec_with_available_privileges {
set dep_mport [mport_open [dict get $dep_portinfo porturl] $options $uvariations]
}
set add_deps 1
# dep_map entry for this dep will be updated in the recursive call
}
}
if {$add_deps} {
# Add this dependency and its dependencies to the dep_map
set dep_map [get_dependencies $dep_mport $dep_map $base_options $variations]
}
}
}
# ensure this port comes after its deps in the dict
dict unset dep_map $portname
dict set dep_map $portname [list $mport [dict get $portinfo version] [dict get $portinfo revision]]
return $dep_map
}
proc portmpkg::make_dependency_list {portname destination} {
global prefix package.flat requested_variations
if {[catch {set res [mport_lookup $portname]} error]} {
ui_debug $::errorInfo
return -code error "port lookup failed: $error"
}
lassign $res portname portinfo
set base_options [dict create prefix $prefix package.destpath ${destination} package.flat ${package.flat}]
set options $base_options
dict set options subport $portname
set variations [array get requested_variations]
exec_with_available_privileges {
set mport [mport_open [dict get $portinfo porturl] $options $variations]
}
set result [get_dependencies $mport [dict create] $base_options $variations]
mport_close $mport
# don't re-package ourself
dict unset result $portname
return $result
}
proc portmpkg::make_one_package {portname mport} {
ui_debug "building dependency package: $portname"
exec_with_available_privileges {
set result [mport_exec $mport pkg]
}
mport_close $mport
if {$result} {
error "Processing of port $portname failed"
}
}
proc portmpkg::mpkg_path {portname portversion portrevision} {
global package.destpath
return ${package.destpath}/[portpkg::image_name ${portname} ${portversion} ${portrevision}].mpkg
}
proc portmpkg::package_mpkg {portname portepoch portversion portrevision} {
global os.major workpath porturl description long_description homepage \
package.flat package.destpath
set mpkgpath [portmpkg::mpkg_path $portname $portversion $portrevision]
if {${package.flat} && ${os.major} >= 10} {
set pkgpath ${package.destpath}/[portpkg::image_name ${portname} ${portversion} ${portrevision}]-component.pkg
set packages_path ${workpath}/mpkg_packages
set resources_path ${workpath}/mpkg_resources
} else {
set pkgpath ${package.destpath}/[portpkg::image_name ${portname} ${portversion} ${portrevision}].pkg
set packages_path ${mpkgpath}/Contents/Packages
set resources_path ${mpkgpath}/Contents/Resources
}
xinstall -d -m 0755 ${packages_path} ${resources_path}
set dependencies [list]
# get deplist
set deps [make_dependency_list $portname $packages_path]
dict for {name depinfo} $deps {
lassign $depinfo mport vers rev
make_one_package $name $mport
if {${package.flat} && ${os.major} >= 10} {
lappend dependencies org.macports.${name} [portpkg::image_name ${name} ${vers} ${rev}]-component.pkg
} else {
lappend dependencies [portpkg::image_name ${name} ${vers} ${rev}].pkg
}
}
if {${package.flat} && ${os.major} >= 10} {
lappend dependencies org.macports.${portname} [portpkg::image_name ${portname} ${portversion} ${portrevision}]-component.pkg
} else {
lappend dependencies [portpkg::image_name ${portname} ${portversion} ${portrevision}].pkg
}
# copy our own pkg into the mpkg
system "cp -PR [shellescape ${pkgpath}] [shellescape ${packages_path}]"
if {!${package.flat} || ${os.major} < 10} {
global prefix
portpkg::write_PkgInfo ${mpkgpath}/Contents/PkgInfo
mpkg_write_info_plist ${mpkgpath}/Contents/Info.plist $portname $portversion $portrevision $prefix $dependencies
portpkg::write_description_plist ${mpkgpath}/Contents/Resources/Description.plist $portname $portversion $description
set resources_path ${mpkgpath}/Contents/Resources
}
# long_description, description, or homepage may not exist
foreach variable {long_description description homepage} {
if {![info exists $variable]} {
set pkg_$variable ""
} else {
set pkg_$variable [set $variable]
}
}
portpkg::write_welcome_html ${resources_path}/Welcome.html $portname $portversion $portrevision $pkg_long_description $pkg_description $pkg_homepage
file copy -force -- [getportresourcepath $porturl "port1.0/package/background.tiff"] ${resources_path}/background.tiff
if {${package.flat} && ${os.major} >= 10} {
write_distribution ${workpath}/Distribution $portname $dependencies
set productbuild [findBinary productbuild]
set v [portpkg::mp_version_to_apple_version $portepoch $portversion $portrevision]
set cmdline "$productbuild --resources [shellescape ${resources_path}] --identifier org.macports.mpkg.${portname} --distribution [shellescape ${workpath}/Distribution] --package-path [shellescape ${packages_path}] --version ${v} [shellescape ${mpkgpath}]"
ui_debug "Running command line: $cmdline"
system $cmdline
}
return 0
}
proc portmpkg::write_distribution {dfile portname dependencies} {
# TODO: Set hostArchitectures. This requires calculating the intersection
# of the archs of all the component pkgs.
global macosx_deployment_target
set portname [portpkg::xml_escape $portname]
set dfd [open $dfile w+]
puts $dfd "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<installer-gui-script minSpecVersion=\"1\">
<title>${portname}</title>
<options customize=\"never\"/>
<allowed-os-versions><os-version min=\"${macosx_deployment_target}\"/></allowed-os-versions>
<background file=\"background.tiff\" mime-type=\"image/tiff\" alignment=\"bottomleft\" scaling=\"none\"/>
<welcome mime-type=\"text/html\" file=\"Welcome.html\"/>
<choices-outline>
<line choice=\"default\">
<line choice=\"org.macports.mpkg.${portname}\"/>
</line>
</choices-outline>
<choice id=\"default\"/>
<choice id=\"org.macports.mpkg.${portname}\" visible=\"false\">
"
foreach {identifier package} $dependencies {
set id [portpkg::xml_escape $identifier]
set pkg [portpkg::xml_escape $package]
puts $dfd " <pkg-ref id=\"${id}\"/>"
lappend pkgrefs "<pkg-ref id=\"${id}\">${pkg}</pkg-ref>"
}
puts $dfd " </choice>"
foreach pkgref $pkgrefs {
puts $dfd " $pkgref"
}
puts $dfd "</installer-gui-script>"
close $dfd
}
proc portmpkg::mpkg_write_info_plist {infofile portname portversion portrevision destination dependencies} {
set vers [split $portversion "."]
if {[string index $destination end] ne "/"} {
append destination /
}
set depxml ""
foreach dep $dependencies {
set dep [portpkg::xml_escape $dep]
append depxml "<dict>
<key>IFPkgFlagPackageLocation</key>
<string>${dep}</string>
<key>IFPkgFlagPackageSelection</key>
<string>selected</string>
</dict>
"
}
set portname [portpkg::xml_escape $portname]
set portversion [portpkg::xml_escape $portversion]
set portrevision [portpkg::xml_escape $portrevision]
set infofd [open ${infofile} w+]
puts $infofd {<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
}
puts $infofd "<dict>
<key>CFBundleGetInfoString</key>
<string>${portname} ${portversion}</string>
<key>CFBundleIdentifier</key>
<string>org.macports.mpkg.${portname}</string>
<key>CFBundleName</key>
<string>${portname}</string>
<key>CFBundleShortVersionString</key>
<string>${portversion}</string>
<key>IFMajorVersion</key>
<integer>${portrevision}</integer>
<key>IFMinorVersion</key>
<integer>0</integer>
<key>IFPkgFlagComponentDirectory</key>
<string>./Contents/Packages</string>
<key>IFPkgFlagPackageList</key>
<array>
${depxml}</array>
<key>IFPkgFormatVersion</key>
<real>0.10000000149011612</real>
</dict>
</plist>"
close $infofd
}
+334
View File
@@ -0,0 +1,334 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
#
# Copyright (c) 2005, 2007 - 2013 The MacPorts Project
# Copyright (c) 2002 - 2004 Apple Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
package provide portmpkg_run 1.0
package require portpkg_run
namespace eval portmpkg {
proc mpkg_main {args} {
global package.flat os.major package.destpath subport epoch version revision
if {!${package.flat} || ${os.major} < 10} {
# Make sure the destination path exists.
file mkdir ${package.destpath}
}
return [package_mpkg $subport $epoch $version $revision]
}
proc archcheck {mport dependent_mport} {
set portinfo [mport_info $mport]
if {[dict exists $portinfo installs_libs] && ![dict get $portinfo installs_libs]} {
return 1
}
set skip_archcheck [_mportkey $dependent_mport depends_skip_archcheck]
if {[lsearch -exact -nocase $skip_archcheck [dict get $portinfo name]] >= 0} {
return 1
}
set required_archs [_mport_archs $dependent_mport]
if {[_mport_supports_archs $mport $required_archs]} {
return 1
}
# Since only depends_lib and depends_run are considered in mpkg,
# there's no need to check if the dep type needs matching archs.
return 0
}
proc get_dependencies {mport dep_map base_options variations} {
set portinfo [mport_info $mport]
set portname [dict get $portinfo name]
if {![dict exists $dep_map $portname]} {
# guard against infinite recursion with circular dependencies
dict set dep_map $portname {}
}
# get the union of depends_run and depends_lib
set depends [list]
if {[dict exists $portinfo depends_run]} { lappend depends {*}[dict get $portinfo depends_run] }
if {[dict exists $portinfo depends_lib]} { lappend depends {*}[dict get $portinfo depends_lib] }
foreach depspec $depends {
set dep [_get_dep_port $depspec]
if {$dep ne ""} {
# Get the dep's mport handle, opening it if needed
if {[catch {set res [mport_lookup $dep]} error]} {
ui_debug $::errorInfo
return -code error "port lookup failed: $error"
}
# depname will have canonical case and so can safely be
# used as the dict key
lassign $res depname dep_portinfo
set add_deps 0
if {[dict exists $dep_map $depname]} {
set dep_map_entry [dict get $dep_map $depname]
if {$dep_map_entry eq {}} {
ui_debug "Circular dependency involving $depname"
continue
}
set dep_mport [lindex $dep_map_entry 0]
# The dep has already been processed, so there's
# nothing to do in this case if the archs match.
} else {
set options $base_options
dict set options subport $depname
exec_with_available_privileges {
set dep_mport [mport_open [dict get $dep_portinfo porturl] $options $variations]
}
set add_deps 1
}
# Reopen with +universal if possible if the archs aren't compatible
if {![archcheck $dep_mport $mport] && ![dict exists $variations universal]} {
set check_portinfo [mport_info $dep_mport]
set dep_archs [_mport_archs $dep_mport]
if {[dict exists $check_portinfo variants] && "universal" in [dict get $check_portinfo variants]
&& [llength $dep_archs] < 2} {
mport_close $dep_mport
set uvariations $variations
dict set uvariations universal +
set options $base_options
dict set options subport $depname
exec_with_available_privileges {
set dep_mport [mport_open [dict get $dep_portinfo porturl] $options $uvariations]
}
set add_deps 1
# dep_map entry for this dep will be updated in the recursive call
}
}
if {$add_deps} {
# Add this dependency and its dependencies to the dep_map
set dep_map [get_dependencies $dep_mport $dep_map $base_options $variations]
}
}
}
# ensure this port comes after its deps in the dict
dict unset dep_map $portname
dict set dep_map $portname [list $mport [dict get $portinfo version] [dict get $portinfo revision]]
return $dep_map
}
proc make_dependency_list {portname destination} {
global prefix package.flat requested_variations
if {[catch {set res [mport_lookup $portname]} error]} {
ui_debug $::errorInfo
return -code error "port lookup failed: $error"
}
lassign $res portname portinfo
set base_options [dict create prefix $prefix package.destpath ${destination} package.flat ${package.flat}]
set options $base_options
dict set options subport $portname
set variations [array get requested_variations]
exec_with_available_privileges {
set mport [mport_open [dict get $portinfo porturl] $options $variations]
}
set result [get_dependencies $mport [dict create] $base_options $variations]
mport_close $mport
# don't re-package ourself
dict unset result $portname
return $result
}
proc make_one_package {portname mport} {
ui_debug "building dependency package: $portname"
exec_with_available_privileges {
set result [mport_exec $mport pkg]
}
mport_close $mport
if {$result} {
error "Processing of port $portname failed"
}
}
proc mpkg_path {portname portversion portrevision} {
global package.destpath
return ${package.destpath}/[portpkg::image_name ${portname} ${portversion} ${portrevision}].mpkg
}
proc package_mpkg {portname portepoch portversion portrevision} {
global os.major workpath porturl description long_description homepage \
package.flat package.destpath
set mpkgpath [mpkg_path $portname $portversion $portrevision]
if {${package.flat} && ${os.major} >= 10} {
set pkgpath ${package.destpath}/[portpkg::image_name ${portname} ${portversion} ${portrevision}]-component.pkg
set packages_path ${workpath}/mpkg_packages
set resources_path ${workpath}/mpkg_resources
} else {
set pkgpath ${package.destpath}/[portpkg::image_name ${portname} ${portversion} ${portrevision}].pkg
set packages_path ${mpkgpath}/Contents/Packages
set resources_path ${mpkgpath}/Contents/Resources
}
xinstall -d -m 0755 ${packages_path} ${resources_path}
set dependencies [list]
# get deplist
set deps [make_dependency_list $portname $packages_path]
dict for {name depinfo} $deps {
lassign $depinfo mport vers rev
make_one_package $name $mport
if {${package.flat} && ${os.major} >= 10} {
lappend dependencies org.macports.${name} [portpkg::image_name ${name} ${vers} ${rev}]-component.pkg
} else {
lappend dependencies [portpkg::image_name ${name} ${vers} ${rev}].pkg
}
}
if {${package.flat} && ${os.major} >= 10} {
lappend dependencies org.macports.${portname} [portpkg::image_name ${portname} ${portversion} ${portrevision}]-component.pkg
} else {
lappend dependencies [portpkg::image_name ${portname} ${portversion} ${portrevision}].pkg
}
# copy our own pkg into the mpkg
system "cp -PR [shellescape ${pkgpath}] [shellescape ${packages_path}]"
if {!${package.flat} || ${os.major} < 10} {
global prefix
portpkg::write_PkgInfo ${mpkgpath}/Contents/PkgInfo
mpkg_write_info_plist ${mpkgpath}/Contents/Info.plist $portname $portversion $portrevision $prefix $dependencies
portpkg::write_description_plist ${mpkgpath}/Contents/Resources/Description.plist $portname $portversion $description
set resources_path ${mpkgpath}/Contents/Resources
}
# long_description, description, or homepage may not exist
foreach variable {long_description description homepage} {
if {![info exists $variable]} {
set pkg_$variable ""
} else {
set pkg_$variable [set $variable]
}
}
portpkg::write_welcome_html ${resources_path}/Welcome.html $portname $portversion $portrevision $pkg_long_description $pkg_description $pkg_homepage
file copy -force -- [getportresourcepath $porturl "port1.0/package/background.tiff"] ${resources_path}/background.tiff
if {${package.flat} && ${os.major} >= 10} {
write_distribution ${workpath}/Distribution $portname $dependencies
set productbuild [findBinary productbuild]
set v [portpkg::mp_version_to_apple_version $portepoch $portversion $portrevision]
set cmdline "$productbuild --resources [shellescape ${resources_path}] --identifier org.macports.mpkg.${portname} --distribution [shellescape ${workpath}/Distribution] --package-path [shellescape ${packages_path}] --version ${v} [shellescape ${mpkgpath}]"
ui_debug "Running command line: $cmdline"
system $cmdline
}
return 0
}
proc write_distribution {dfile portname dependencies} {
# TODO: Set hostArchitectures. This requires calculating the intersection
# of the archs of all the component pkgs.
global macosx_deployment_target
set portname [portpkg::xml_escape $portname]
set dfd [open $dfile w+]
puts $dfd "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<installer-gui-script minSpecVersion=\"1\">
<title>${portname}</title>
<options customize=\"never\"/>
<allowed-os-versions><os-version min=\"${macosx_deployment_target}\"/></allowed-os-versions>
<background file=\"background.tiff\" mime-type=\"image/tiff\" alignment=\"bottomleft\" scaling=\"none\"/>
<welcome mime-type=\"text/html\" file=\"Welcome.html\"/>
<choices-outline>
<line choice=\"default\">
<line choice=\"org.macports.mpkg.${portname}\"/>
</line>
</choices-outline>
<choice id=\"default\"/>
<choice id=\"org.macports.mpkg.${portname}\" visible=\"false\">
"
foreach {identifier package} $dependencies {
set id [portpkg::xml_escape $identifier]
set pkg [portpkg::xml_escape $package]
puts $dfd " <pkg-ref id=\"${id}\"/>"
lappend pkgrefs "<pkg-ref id=\"${id}\">${pkg}</pkg-ref>"
}
puts $dfd " </choice>"
foreach pkgref $pkgrefs {
puts $dfd " $pkgref"
}
puts $dfd "</installer-gui-script>"
close $dfd
}
proc mpkg_write_info_plist {infofile portname portversion portrevision destination dependencies} {
set vers [split $portversion "."]
if {[string index $destination end] ne "/"} {
append destination /
}
set depxml ""
foreach dep $dependencies {
set dep [portpkg::xml_escape $dep]
append depxml "<dict>
<key>IFPkgFlagPackageLocation</key>
<string>${dep}</string>
<key>IFPkgFlagPackageSelection</key>
<string>selected</string>
</dict>
"
}
set portname [portpkg::xml_escape $portname]
set portversion [portpkg::xml_escape $portversion]
set portrevision [portpkg::xml_escape $portrevision]
set infofd [open ${infofile} w+]
puts $infofd {<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
}
puts $infofd "<dict>
<key>CFBundleGetInfoString</key>
<string>${portname} ${portversion}</string>
<key>CFBundleIdentifier</key>
<string>org.macports.mpkg.${portname}</string>
<key>CFBundleName</key>
<string>${portname}</string>
<key>CFBundleShortVersionString</key>
<string>${portversion}</string>
<key>IFMajorVersion</key>
<integer>${portrevision}</integer>
<key>IFMinorVersion</key>
<integer>0</integer>
<key>IFPkgFlagComponentDirectory</key>
<string>./Contents/Packages</string>
<key>IFPkgFlagPackageList</key>
<array>
${depxml}</array>
<key>IFPkgFormatVersion</key>
<real>0.10000000149011612</real>
</dict>
</plist>"
close $infofd
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+3 -309
View File
@@ -1,38 +1,8 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
# portunarchive.tcl
#
# Copyright (c) 2005, 2007-2012 The MacPorts Project
# Copyright (c) 2004 Robert Shaw <rshaw@opendarwin.org>
# Copyright (c) 2002 - 2003 Apple Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# License: see portunarchive_run.tcl
package provide portunarchive 1.0
package require portutil 1.0
set org.macports.unarchive [target_new org.macports.unarchive portunarchive::unarchive_main]
target_runtype ${org.macports.unarchive} always
@@ -41,9 +11,7 @@ target_provides ${org.macports.unarchive} unarchive
target_requires ${org.macports.unarchive} main archivefetch
target_prerun ${org.macports.unarchive} portunarchive::unarchive_start
target_postrun ${org.macports.unarchive} portunarchive::unarchive_finish
namespace eval portunarchive {
}
target_runpkg ${org.macports.unarchive} portunarchive_run
# defaults
default unarchive.dir {${destpath}}
@@ -57,277 +25,3 @@ default unarchive.type {}
default unarchive.file {}
default unarchive.path {}
default unarchive.skip 0
set_ui_prefix
proc portunarchive::unarchive_init {args} {
global target_state_fd unarchive.skip destroot \
ports_force ports_source_only ports_binary_only \
subport version revision portvariants \
unarchive.type unarchive.file unarchive.path
# Determine if unarchive should be skipped
set skipped 0
if {[check_statefile target org.macports.unarchive $target_state_fd]} {
return 0
} elseif {[info exists ports_source_only] && $ports_source_only eq "yes"} {
ui_debug "Skipping unarchive ($subport) since source-only is set"
set skipped 1
} elseif {[check_statefile target org.macports.destroot $target_state_fd]
&& [file isdirectory $destroot]} {
ui_debug "Skipping unarchive ($subport) since destroot completed"
set skipped 1
} elseif {[info exists ports_force] && $ports_force eq "yes"} {
ui_debug "Skipping unarchive ($subport) since force is set"
set skipped 1
} else {
set unarchive.path [find_portarchive_path]
set unarchive.file [file tail ${unarchive.path}]
set unarchive.type [string range [file extension ${unarchive.file}] 1 end]
if {${unarchive.path} ne ""} {
ui_debug "Found [string toupper ${unarchive.type}] archive: ${unarchive.path}"
} elseif {[registry_exists $subport $version $revision $portvariants]
&& [file isdirectory [set unarchive.path [file rootname [get_portimage_path]]]]} {
set unarchive.type directory
set unarchive.file [file tail ${unarchive.path}]
ui_debug "Found extracted port image: ${unarchive.path}"
} else {
if {[info exists ports_binary_only] && $ports_binary_only eq "yes"} {
return -code error "Archive for ${subport} ${version}_${revision}${portvariants} not found, required when binary-only is set!"
} else {
ui_debug "Skipping unarchive ($subport) since no suitable archive found"
set skipped 1
}
}
}
# Skip running the main body of this target
set unarchive.skip $skipped
return 0
}
proc portunarchive::unarchive_start {args} {
global UI_PREFIX subport version revision portvariants \
unarchive.type unarchive.skip
if {${unarchive.skip}} {
return 0
}
if {[getuid] == 0 && [geteuid] != 0} {
# run as root if possible so file ownership can be preserved
elevateToRoot "unarchive"
}
# create any users and groups needed by the port
handle_add_users
ui_msg "$UI_PREFIX [format [msgcat::mc "Unpacking ${unarchive.type} archive for %s %s_%s%s"] $subport $version $revision $portvariants]"
return 0
}
proc portunarchive::unarchive_command_setup {args} {
global unarchive.env unarchive.cmd unarchive.pre_args unarchive.args \
unarchive.post_args unarchive.type unarchive.path \
unarchive.pipe_cmd
# Define appropriate unarchive command and options
set unarchive.env {}
set unarchive.cmd {}
set unarchive.pre_args {}
set unarchive.args {}
set unarchive.post_args {}
set unarchive.pipe_cmd ""
switch -regex ${unarchive.type} {
aar {
set aa "aa"
if {[catch {set aa [findBinary $aa ${::portutil::autoconf::aa_path}]} errmsg] == 0} {
ui_debug "Using $aa"
set unarchive.cmd "$aa"
set unarchive.pre_args {extract -afsc-all -enable-dedup -enable-holes -v}
set unarchive.args "-i [shellescape ${unarchive.path}]"
} else {
ui_debug $errmsg
return -code error "No '$aa' was found on this system!"
}
}
cp(io|gz) {
set pax "pax"
if {[catch {set pax [findBinary $pax ${::portutil::autoconf::pax_path}]} errmsg] == 0} {
ui_debug "Using $pax"
set unarchive.cmd "$pax"
if {[geteuid] == 0} {
set unarchive.pre_args {-r -v -p e}
} else {
set unarchive.pre_args {-r -v -p p}
}
if {[regexp {z$} ${unarchive.type}]} {
set unarchive.args {.}
set gzip "gzip"
if {[catch {set gzip [findBinary $gzip ${::portutil::autoconf::gzip_path}]} errmsg] == 0} {
ui_debug "Using $gzip"
set unarchive.pipe_cmd "$gzip -d -c [shellescape ${unarchive.path}] |"
} else {
ui_debug $errmsg
return -code error "No '$gzip' was found on this system!"
}
} else {
set unarchive.args "-f [shellescape ${unarchive.path}] ."
}
} else {
ui_debug $errmsg
return -code error "No '$pax' was found on this system!"
}
}
t(ar|bz|lz|xz|gz) {
set tar "tar"
if {[catch {set tar [findBinary $tar ${::portutil::autoconf::tar_path}]} errmsg] == 0} {
ui_debug "Using $tar"
set unarchive.cmd "$tar"
set unarchive.pre_args {-xvpf}
if {[regexp {z2?$} ${unarchive.type}]} {
set unarchive.args {-}
if {[regexp {bz2?$} ${unarchive.type}]} {
if {![catch {binaryInPath lbzip2}]} {
set gzip "lbzip2"
} elseif {![catch {binaryInPath pbzip2}]} {
set gzip "pbzip2"
} else {
set gzip "bzip2"
}
} elseif {[regexp {lz$} ${unarchive.type}]} {
set gzip "lzma"
} elseif {[regexp {xz$} ${unarchive.type}]} {
set gzip "xz"
} else {
set gzip "gzip"
}
if {[info exists ::portutil::autoconf::${gzip}_path]} {
set hint [set ::portutil::autoconf::${gzip}_path]
} else {
set hint ""
}
if {[catch {set gzip [findBinary $gzip $hint]} errmsg] == 0} {
ui_debug "Using $gzip"
set unarchive.pipe_cmd "$gzip -d -c [shellescape ${unarchive.path}] |"
} else {
ui_debug $errmsg
return -code error "No '$gzip' was found on this system!"
}
} else {
set unarchive.args [shellescape ${unarchive.path}]
}
} else {
ui_debug $errmsg
return -code error "No '$tar' was found on this system!"
}
}
xar {
set xar "xar"
if {[catch {set xar [findBinary $xar ${::portutil::autoconf::xar_path}]} errmsg] == 0} {
ui_debug "Using $xar"
set unarchive.cmd "$xar"
set unarchive.pre_args {-xvpf}
set unarchive.args [shellescape ${unarchive.path}]
} else {
ui_debug $errmsg
return -code error "No '$xar' was found on this system!"
}
}
zip {
set unzip "unzip"
if {[catch {set unzip [findBinary $unzip ${::portutil::autoconf::unzip_path}]} errmsg] == 0} {
ui_debug "Using $unzip"
set unarchive.cmd "$unzip"
if {[geteuid] == 0} {
set unarchive.pre_args {-oX}
} else {
set unarchive.pre_args {-o}
}
set unarchive.args "[shellescape ${unarchive.path}] -d ."
} else {
ui_debug $errmsg
return -code error "No '$unzip' was found on this system!"
}
}
default {
return -code error "Invalid port archive type '${unarchive.type}' specified!"
}
}
return 0
}
proc portunarchive::unarchive_main {args} {
global UI_PREFIX unarchive.dir unarchive.file unarchive.path \
unarchive.pipe_cmd unarchive.skip
if {${unarchive.skip}} {
return 0
}
if {[file isfile ${unarchive.path}]} {
# Setup unarchive command
unarchive_command_setup
# Create destination directory for unpacking
if {![file isdirectory ${unarchive.dir}]} {
file mkdir ${unarchive.dir}
}
# Unpack the archive
ui_info "$UI_PREFIX [format [msgcat::mc "Extracting %s"] ${unarchive.file}]"
if {${unarchive.pipe_cmd} eq ""} {
command_exec unarchive
} else {
command_exec unarchive "${unarchive.pipe_cmd} (" ")"
}
} else {
ui_info "$UI_PREFIX [format [msgcat::mc "Copying %s to destroot"] ${unarchive.file}]"
if {[file exists ${unarchive.dir}]} {
delete ${unarchive.dir}
}
copy ${unarchive.path} ${unarchive.dir}
}
return 0
}
proc portunarchive::unarchive_finish {args} {
global UI_PREFIX target_state_fd unarchive.file subport workpath portpath destpath unarchive.skip
if {${unarchive.skip}} {
return 0
}
# Reset state file with archive version
set statefile [file join $workpath .macports.${subport}.state]
set plus_state [file join $destpath "+STATE"]
if {[file isfile $plus_state]} {
close $target_state_fd
file copy -force $plus_state $statefile
file mtime $statefile [clock seconds]
chownAsRoot $statefile
update_statefile checksum [sha256 file ${portpath}/Portfile] $statefile
set newstate 1
} else {
# fake it
write_statefile target org.macports.destroot $target_state_fd
}
# Cleanup all control files when finished
set control_files [glob -nocomplain -types f [file join $destpath +*]]
foreach file $control_files {
ui_debug "Removing $file"
file delete -force $file
}
if {[info exists newstate]} {
# Update the state from unpacked archive version
set target_state_fd [open_statefile]
}
ui_info "$UI_PREFIX [format [msgcat::mc "Archive %s unpacked"] ${unarchive.file}]"
return 0
}
+308
View File
@@ -0,0 +1,308 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
#
# Copyright (c) 2005, 2007-2012 The MacPorts Project
# Copyright (c) 2004 Robert Shaw <rshaw@opendarwin.org>
# Copyright (c) 2002 - 2003 Apple Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Inc. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
package provide portunarchive_run 1.0
namespace eval portunarchive {
proc unarchive_init {args} {
global target_state_fd unarchive.skip destroot \
ports_force ports_source_only ports_binary_only \
subport version revision portvariants \
unarchive.type unarchive.file unarchive.path
# Determine if unarchive should be skipped
set skipped 0
if {[check_statefile target org.macports.unarchive $target_state_fd]} {
return 0
} elseif {[info exists ports_source_only] && $ports_source_only eq "yes"} {
ui_debug "Skipping unarchive ($subport) since source-only is set"
set skipped 1
} elseif {[check_statefile target org.macports.destroot $target_state_fd]
&& [file isdirectory $destroot]} {
ui_debug "Skipping unarchive ($subport) since destroot completed"
set skipped 1
} elseif {[info exists ports_force] && $ports_force eq "yes"} {
ui_debug "Skipping unarchive ($subport) since force is set"
set skipped 1
} else {
set unarchive.path [find_portarchive_path]
set unarchive.file [file tail ${unarchive.path}]
set unarchive.type [string range [file extension ${unarchive.file}] 1 end]
if {${unarchive.path} ne ""} {
ui_debug "Found [string toupper ${unarchive.type}] archive: ${unarchive.path}"
} elseif {[registry_exists $subport $version $revision $portvariants]
&& [file isdirectory [set unarchive.path [file rootname [get_portimage_path]]]]} {
set unarchive.type directory
set unarchive.file [file tail ${unarchive.path}]
ui_debug "Found extracted port image: ${unarchive.path}"
} else {
if {[info exists ports_binary_only] && $ports_binary_only eq "yes"} {
return -code error "Archive for ${subport} ${version}_${revision}${portvariants} not found, required when binary-only is set!"
} else {
ui_debug "Skipping unarchive ($subport) since no suitable archive found"
set skipped 1
}
}
}
# Skip running the main body of this target
set unarchive.skip $skipped
return 0
}
proc unarchive_start {args} {
global UI_PREFIX subport version revision portvariants \
unarchive.type unarchive.skip
if {${unarchive.skip}} {
return 0
}
if {[getuid] == 0 && [geteuid] != 0} {
# run as root if possible so file ownership can be preserved
elevateToRoot "unarchive"
}
# create any users and groups needed by the port
handle_add_users
ui_msg "$UI_PREFIX [format [msgcat::mc "Unpacking ${unarchive.type} archive for %s %s_%s%s"] $subport $version $revision $portvariants]"
return 0
}
proc unarchive_command_setup {args} {
global unarchive.env unarchive.cmd unarchive.pre_args unarchive.args \
unarchive.post_args unarchive.type unarchive.path \
unarchive.pipe_cmd
# Define appropriate unarchive command and options
set unarchive.env {}
set unarchive.cmd {}
set unarchive.pre_args {}
set unarchive.args {}
set unarchive.post_args {}
set unarchive.pipe_cmd ""
switch -regex ${unarchive.type} {
aar {
set aa "aa"
if {[catch {set aa [findBinary $aa ${::portutil::autoconf::aa_path}]} errmsg] == 0} {
ui_debug "Using $aa"
set unarchive.cmd "$aa"
set unarchive.pre_args {extract -afsc-all -enable-dedup -enable-holes -v}
set unarchive.args "-i [shellescape ${unarchive.path}]"
} else {
ui_debug $errmsg
return -code error "No '$aa' was found on this system!"
}
}
cp(io|gz) {
set pax "pax"
if {[catch {set pax [findBinary $pax ${::portutil::autoconf::pax_path}]} errmsg] == 0} {
ui_debug "Using $pax"
set unarchive.cmd "$pax"
if {[geteuid] == 0} {
set unarchive.pre_args {-r -v -p e}
} else {
set unarchive.pre_args {-r -v -p p}
}
if {[regexp {z$} ${unarchive.type}]} {
set unarchive.args {.}
set gzip "gzip"
if {[catch {set gzip [findBinary $gzip ${::portutil::autoconf::gzip_path}]} errmsg] == 0} {
ui_debug "Using $gzip"
set unarchive.pipe_cmd "$gzip -d -c [shellescape ${unarchive.path}] |"
} else {
ui_debug $errmsg
return -code error "No '$gzip' was found on this system!"
}
} else {
set unarchive.args "-f [shellescape ${unarchive.path}] ."
}
} else {
ui_debug $errmsg
return -code error "No '$pax' was found on this system!"
}
}
t(ar|bz|lz|xz|gz) {
set tar "tar"
if {[catch {set tar [findBinary $tar ${::portutil::autoconf::tar_path}]} errmsg] == 0} {
ui_debug "Using $tar"
set unarchive.cmd "$tar"
set unarchive.pre_args {-xvpf}
if {[regexp {z2?$} ${unarchive.type}]} {
set unarchive.args {-}
if {[regexp {bz2?$} ${unarchive.type}]} {
if {![catch {binaryInPath lbzip2}]} {
set gzip "lbzip2"
} elseif {![catch {binaryInPath pbzip2}]} {
set gzip "pbzip2"
} else {
set gzip "bzip2"
}
} elseif {[regexp {lz$} ${unarchive.type}]} {
set gzip "lzma"
} elseif {[regexp {xz$} ${unarchive.type}]} {
set gzip "xz"
} else {
set gzip "gzip"
}
if {[info exists ::portutil::autoconf::${gzip}_path]} {
set hint [set ::portutil::autoconf::${gzip}_path]
} else {
set hint ""
}
if {[catch {set gzip [findBinary $gzip $hint]} errmsg] == 0} {
ui_debug "Using $gzip"
set unarchive.pipe_cmd "$gzip -d -c [shellescape ${unarchive.path}] |"
} else {
ui_debug $errmsg
return -code error "No '$gzip' was found on this system!"
}
} else {
set unarchive.args [shellescape ${unarchive.path}]
}
} else {
ui_debug $errmsg
return -code error "No '$tar' was found on this system!"
}
}
xar {
set xar "xar"
if {[catch {set xar [findBinary $xar ${::portutil::autoconf::xar_path}]} errmsg] == 0} {
ui_debug "Using $xar"
set unarchive.cmd "$xar"
set unarchive.pre_args {-xvpf}
set unarchive.args [shellescape ${unarchive.path}]
} else {
ui_debug $errmsg
return -code error "No '$xar' was found on this system!"
}
}
zip {
set unzip "unzip"
if {[catch {set unzip [findBinary $unzip ${::portutil::autoconf::unzip_path}]} errmsg] == 0} {
ui_debug "Using $unzip"
set unarchive.cmd "$unzip"
if {[geteuid] == 0} {
set unarchive.pre_args {-oX}
} else {
set unarchive.pre_args {-o}
}
set unarchive.args "[shellescape ${unarchive.path}] -d ."
} else {
ui_debug $errmsg
return -code error "No '$unzip' was found on this system!"
}
}
default {
return -code error "Invalid port archive type '${unarchive.type}' specified!"
}
}
return 0
}
proc unarchive_main {args} {
global UI_PREFIX unarchive.dir unarchive.file unarchive.path \
unarchive.pipe_cmd unarchive.skip
if {${unarchive.skip}} {
return 0
}
if {[file isfile ${unarchive.path}]} {
# Setup unarchive command
unarchive_command_setup
# Create destination directory for unpacking
if {![file isdirectory ${unarchive.dir}]} {
file mkdir ${unarchive.dir}
}
# Unpack the archive
ui_info "$UI_PREFIX [format [msgcat::mc "Extracting %s"] ${unarchive.file}]"
if {${unarchive.pipe_cmd} eq ""} {
command_exec unarchive
} else {
command_exec unarchive "${unarchive.pipe_cmd} (" ")"
}
} else {
ui_info "$UI_PREFIX [format [msgcat::mc "Copying %s to destroot"] ${unarchive.file}]"
if {[file exists ${unarchive.dir}]} {
delete ${unarchive.dir}
}
copy ${unarchive.path} ${unarchive.dir}
}
return 0
}
proc unarchive_finish {args} {
global UI_PREFIX target_state_fd unarchive.file subport workpath portpath destpath unarchive.skip
if {${unarchive.skip}} {
return 0
}
# Reset state file with archive version
set statefile [file join $workpath .macports.${subport}.state]
set plus_state [file join $destpath "+STATE"]
if {[file isfile $plus_state]} {
close $target_state_fd
file copy -force $plus_state $statefile
file mtime $statefile [clock seconds]
chownAsRoot $statefile
update_statefile checksum [sha256 file ${portpath}/Portfile] $statefile
set newstate 1
} else {
# fake it
write_statefile target org.macports.destroot $target_state_fd
}
# Cleanup all control files when finished
set control_files [glob -nocomplain -types f [file join $destpath +*]]
foreach file $control_files {
ui_debug "Removing $file"
file delete -force $file
}
if {[info exists newstate]} {
# Update the state from unpacked archive version
set target_state_fd [open_statefile]
}
ui_info "$UI_PREFIX [format [msgcat::mc "Archive %s unpacked"] ${unarchive.file}]"
return 0
}
}
@@ -11,7 +11,9 @@ source ./library.tcl
macports_worker_init
package require portutil 1.0
package require portarchivefetch 1.0
package require portarchivefetch_run
namespace eval portutil {
namespace eval autoconf {
variable openssl_path "/usr/bin/openssl"
+2
View File
@@ -9,7 +9,9 @@ source ../package_test_autoconf.tcl
source $macports::autoconf::top_srcdir/src/macports1.0/tests/test_setup.tcl
source ./library.tcl
package require portutil 1.0
package require portdmg 1.0
package require portdmg_run
package require portpkg 1.0
macports_worker_init
+2
View File
@@ -11,7 +11,9 @@ source ./library.tcl
macports_worker_init
package require portutil 1.0
package require portmdmg
package require portmdmg_run
package require portmpkg
package require portpkg
source ../../port1.0/port_autoconf.tcl
+3 -1
View File
@@ -9,8 +9,10 @@ source ../package_test_autoconf.tcl
source $macports::autoconf::top_srcdir/src/macports1.0/tests/test_setup.tcl
source ./library.tcl
package require portutil 1.0
package require portmpkg 1.0
package require portpkg 1.0
package require portmpkg_run
package require portpkg_run
macports_worker_init
# mock getportresourcepath, tests should be able to operate without a ports tree
+1 -1
View File
@@ -9,7 +9,7 @@ source ../package_test_autoconf.tcl
source $macports::autoconf::top_srcdir/src/macports1.0/tests/test_setup.tcl
source ./library.tcl
package require portmpkg 1.0
package require portutil 1.0
package require portpkg 1.0
macports_worker_init

Some files were not shown because too many files have changed in this diff Show More