You've already forked macports-base
mirror of
https://github.com/macports/macports-base.git
synced 2026-07-12 18:18:43 -07:00
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
+4
-514
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user