From 5ff58f96e05d9dbde4acc4e516e376ee3585e352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=2E=20Bj=C3=B6rklund?= Date: Thu, 18 Dec 2008 08:46:30 +0000 Subject: [PATCH] add xpkg (binary) and portpkg (source) xar archive formats git-svn-id: https://svn.macports.org/repository/macports/trunk/base@43959 d073be05-634f-4543-b044-5fe20cf6d1d6 --- ChangeLog | 4 + doc/macports.conf.in | 2 +- src/macports1.0/macports.tcl | 3 +- src/package1.0/Makefile | 2 +- src/package1.0/package.tcl | 1 + src/package1.0/portarchive.tcl | 116 ++++++++++++++++- src/package1.0/portportpkg.tcl | 206 +++++++++++++++++++++++++++++++ src/package1.0/portunarchive.tcl | 2 +- src/port/port.tcl | 1 + src/port1.0/portsubmit.tcl | 152 +---------------------- src/port1.0/portutil.tcl | 3 +- 11 files changed, 340 insertions(+), 152 deletions(-) create mode 100644 src/package1.0/portportpkg.tcl diff --git a/ChangeLog b/ChangeLog index 70933d085..dc0b512ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,10 @@ Release 1.8.0 (unreleased): + - Add xpkg archive type, xar-based format with XML. (afb) + + - Split portpkg creation out from portsubmit phase. (afb) + Release 1.7.1 (unreleased): diff --git a/doc/macports.conf.in b/doc/macports.conf.in index 84fca3423..6d06a62a9 100644 --- a/doc/macports.conf.in +++ b/doc/macports.conf.in @@ -47,7 +47,7 @@ portarchivepath @localstatedir_expanded@/macports/packages # Unarchive uses multiple types as a search list to locate the archive, # first archive to match one of the specified types in order is used. # -# Supported types: tgz (default), tar, tbz, tbz2, tlz, xar, zip, cpgz, cpio +# Supported types: tgz (default), tar, tbz, tbz2, tlz, xar, xpkg, zip, cpgz, cpio portarchivetype tgz # Use ccache (C/C++ compiler cache) - see http://ccache.samba.org/ diff --git a/src/macports1.0/macports.tcl b/src/macports1.0/macports.tcl index 47b1091bc..6efca8969 100644 --- a/src/macports1.0/macports.tcl +++ b/src/macports1.0/macports.tcl @@ -1290,7 +1290,7 @@ proc mportexec {mport target} { || $target == "dmg" || $target == "mdmg" || $target == "pkg" || $target == "mpkg" || $target == "rpm" || $target == "dpkg" - || $target == "srpm" } { + || $target == "srpm"|| $target == "portpkg" } { if {[mportdepends $mport $target] != 0} { return 1 @@ -1722,6 +1722,7 @@ proc mportdepends {mport {target ""} {recurseDeps 1} {skipSatisfied 1} {accDeps archive - dmg - pkg - + portpkg - mdmg - mpkg - rpm - diff --git a/src/package1.0/Makefile b/src/package1.0/Makefile index 784e48d0d..aef07fefc 100644 --- a/src/package1.0/Makefile +++ b/src/package1.0/Makefile @@ -1,6 +1,6 @@ INSTALLDIR= ${DESTDIR}${datadir}/macports/Tcl/package1.0 -SRCS= package.tcl portdmg.tcl portmdmg.tcl portmpkg.tcl portpkg.tcl \ +SRCS= package.tcl portdmg.tcl portmdmg.tcl portmpkg.tcl portpkg.tcl portportpkg.tcl \ portrpm.tcl portsrpm.tcl portdpkg.tcl portunarchive.tcl portarchive.tcl include ../../Mk/macports.autoconf.mk diff --git a/src/package1.0/package.tcl b/src/package1.0/package.tcl index 82e92fa51..7b2cecce9 100644 --- a/src/package1.0/package.tcl +++ b/src/package1.0/package.tcl @@ -39,5 +39,6 @@ package require portmpkg 1.0 package require portdmg 1.0 package require portmdmg 1.0 package require portdpkg 1.0 +package require portportpkg 1.0 package require portunarchive 1.0 package require portarchive 1.0 diff --git a/src/package1.0/portarchive.tcl b/src/package1.0/portarchive.tcl index dfa482c42..24b345caf 100644 --- a/src/package1.0/portarchive.tcl +++ b/src/package1.0/portarchive.tcl @@ -54,6 +54,10 @@ default archive.type {} default archive.file {} default archive.path {} +default archive.meta false +default archive.metaname {} +default archive.metapath {} + set_ui_prefix proc archive_init {args} { @@ -61,7 +65,8 @@ proc archive_init {args} { global variations package.destpath workpath global ports_force ports_source_only ports_binary_only global portname portversion portrevision portvariants - global archive.destpath archive.type archive.file archive.path archive.fulldestpath + global archive.destpath archive.type archive.meta + global archive.file archive.path archive.fulldestpath # Check mode in case archive called directly by user if {[option portarchivemode] != "yes"} { @@ -108,6 +113,9 @@ proc archive_init {args} { set unsupported [expr $unsupported + 1] } } + if {${archive.type} == "xpkg"} { + set archive.meta true + } if {[llength [option portarchivetype]] == $unsupported} { ui_debug "Skipping archive ($portname) since specified archive types not supported" set skipped 1 @@ -138,6 +146,7 @@ proc archive_command_setup {args} { global archive.env archive.cmd global archive.pre_args archive.args archive.post_args global archive.type archive.path + global archive.metaname archive.metapath global os.platform os.version # Define appropriate archive command and options @@ -216,6 +225,19 @@ proc archive_command_setup {args} { return -code error "No '$xar' was found on this system!" } } + xpkg { + set xar "xar" + set compression "bzip2" + if {[catch {set xar [binaryInPath $xar]} errmsg] == 0} { + ui_debug "Using $xar" + set archive.cmd "$xar" + set archive.pre_args "-cv --exclude='\./\+.*' --compression=${compression} -n ${archive.metaname} -s ${archive.metapath} -f" + set archive.args "${archive.path} ." + } else { + ui_debug $errmsg + return -code error "No '$xar' was found on this system!" + } + } zip { set zip "zip" if {[catch {set zip [binaryInPath $zip]} errmsg] == 0} { @@ -236,11 +258,28 @@ proc archive_command_setup {args} { return 0 } +proc putel { fd el data } { + # Quote xml data + set quoted [string map { & & < < > > } $data] + # Write the element + puts $fd "<${el}>${quoted}" +} + +proc putlist { fd listel itemel list } { + puts $fd "<$listel>" + foreach item $list { + putel $fd $itemel $item + } + puts $fd "" +} + proc archive_main {args} { global UI_PREFIX variations global workpath destpath portpath ports_force global portname portepoch portversion portrevision portvariants global archive.fulldestpath archive.type archive.file archive.path + global archive.meta archive.metaname archive.metapath + global os.platform os.arch # Create archive destination path (if needed) if {![file isdirectory ${archive.fulldestpath}]} { @@ -319,6 +358,81 @@ proc archive_main {args} { } close $fd + # the XML package metadata, for XAR package + # (doesn't contain any file list/checksums) + if {${archive.meta}} { + set archive.metaname "xpkg" + set archive.metapath [file join $workpath "${archive.metaname}.xml"] + set sd [open ${archive.metapath} w] + puts $sd "" + # TODO: split contents into (new) and (current) + # see existing for the matching source package layout + + putel $sd name ${portname} + putel $sd epoch ${portepoch} + putel $sd version ${portversion} + putel $sd revision ${portrevision} + putel $sd major 0 + putel $sd minor 0 + + putel $sd platform ${os.platform} + putel $sd arch ${os.arch} + set vlist [lsort -ascii [array names variations]] + putlist $sd variants variant $vlist + + if {[exists categories]} { + set primary [lindex [split [option categories] " "] 0] + putel $sd category $primary + } + if {[exists description]} { + putel $sd comment "[option description]" + } + if {[exists long_description]} { + putel $sd desc "[option long_description]" + } + if {[exists homepage]} { + putel $sd homepage "[option homepage]" + } + + # Emit dependencies provided by this package + puts $sd "" + set name ${portname} + puts $sd "" + putel $sd name $name + putel $sd major 0 + putel $sd minor 0 + puts $sd "" + puts $sd "" + + set res [mport_search ^$portname\$] + if {[llength $res] < 2} { + ui_error "Dependency $portname not found" + } else { + array set portinfo [lindex $res 1] + + # Emit build, library, and runtime dependencies + puts $sd "" + foreach {key type} { + depends_build "build" + depends_lib "library" + depends_run "runtime" + } { + if {[info exists portinfo($key)]} { + set name [lindex [split $portinfo($key) :] end] + puts $sd "" + putel $sd name $name + putel $sd major 0 + putel $sd minor 0 + puts $sd "" + } + } + puts $sd "" + } + + puts $sd "" + close $sd + } + # Now create the archive(s) # Loop through archive types foreach archive.type [option portarchivetype] { diff --git a/src/package1.0/portportpkg.tcl b/src/package1.0/portportpkg.tcl new file mode 100644 index 000000000..2617b3cf4 --- /dev/null +++ b/src/package1.0/portportpkg.tcl @@ -0,0 +1,206 @@ +# et:ts=4 +# portportpkg.tcl +# $Id$ +# +# Copyright (c) 2002 - 2004 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 portportpkg 1.0 +package require portutil 1.0 + +set org.macports.portpkg [target_new org.macports.portpkg portpkg_main] +target_runtype ${org.macports.portpkg} always +target_provides ${org.macports.portpkg} portpkg +target_requires ${org.macports.portpkg} main + +set_ui_prefix + + +proc xar_path {args} { + global prefix_frozen + set xar "" + foreach path "${portutil::autoconf::xar_path} ${prefix_frozen}/bin/xar xar" { + if { [file executable ${path}] } { + set xar $path + break; + } + } + if { "${xar}" == "" } { + ui_error "The xar tool is required to make portpkgs" + ui_error "Please install the xar port before proceeding." + return -code error [msgcat::mc "Portpkg failed"] + } + + return $xar +} + + +# escape quotes, and things that make the shell cry +proc shell_escape {str} { + regsub -all -- {\\} $str {\\\\} str + regsub -all -- {"} $str {\"} str + regsub -all -- {'} $str {\'} str + return $str +} + + +proc putel { fd el data } { + # Quote xml data + set quoted [string map { & & < < > > } $data] + # Write the element + puts $fd "<${el}>${quoted}" +} + + +proc putlist { fd listel itemel list } { + puts $fd "<$listel>" + foreach item $list { + putel $fd $itemel $item + } + puts $fd "" +} + + +proc create_portpkg {} { + global portname portversion prefix UI_PREFIX workpath portpath + + set xar [xar_path] + + set dirname "portpkg" + set dirpath "${workpath}/${dirname}" + set pkgpath "${workpath}/${portname}.portpkg" + set metaname "portpkg_meta.xml" + set metapath "${workpath}/${metaname}" + + # Expose and default some global variables + set vars " portname portversion maintainers categories description \ + long_description master_sites homepage epoch version revision \ + PortInfo \ + submitter_name submitter_email submitter_key \ + " + eval "global $vars" + foreach var $vars { + if {![info exists $var]} { set $var {} } + } + + # Unobscure the maintainer addresses + set maintainers [unobscure_maintainers $maintainers] + + # Make sure our workpath is clean + file delete -force $dirpath $metapath $pkgpath + + # Create the portpkg directory + file mkdir $dirpath + + # Move in the Portfile + file copy Portfile ${dirpath} + + # Move in files + if {[file isdirectory "files"]} { + file copy files ${dirpath} + } + + # Create the metadata subdoc + set sd [open ${metapath} w] + puts $sd "" + + puts $sd "" + putel $sd name $submitter_name + putel $sd email $submitter_email + + # TODO provide means to set notes? + putel $sd notes "" + puts $sd "" + + puts $sd "" + putel $sd name $portname + putel $sd homepage $homepage + putlist $sd categories category $categories + putlist $sd maintainers maintainer $maintainers + + putel $sd epoch $epoch + putel $sd version $version + putel $sd revision $revision + + putel $sd description [join $description] + putel $sd long_description [join $long_description] + + # TODO: variants has platforms in it + if {[info exists PortInfo(variants)]} { + if {[info exists PortInfo(variant_desc)]} { + array set descs $PortInfo(variant_desc) + } else { + array set descs "" + } + + puts $sd "" + foreach v $PortInfo(variants) { + puts $sd "" + putel $sd name $v + if {[info exists descs($v)]} { + putel $sd description $descs($v) + } + puts $sd "" + } + puts $sd "" + } else { + putel $sd variants "" + } + + # TODO: Dependencies and platforms + #putel $sd dependencies "" + #putel $sd platforms "" + + puts $sd "" + + puts $sd "" + close $sd + + # Create portpkg.xar, including the metadata and the portpkg directory contents + set cmd "cd ${workpath}; ${xar} -cf ${pkgpath} --exclude \\.DSStore --exclude \\.svn ${dirname} -s ${metapath} -n ${metaname}" + if {[system $cmd] != ""} { + return -code error [format [msgcat::mc "Failed to create portpkg for port : %s"] $portname] + } + + return ${pkgpath} +} + + +proc portpkg_main {args} { + global portname portversion portverbose prefix UI_PREFIX workpath portpath + + ui_msg "$UI_PREFIX [format [msgcat::mc "Creating portpkg for %s-%s"] ${portname} ${portversion}]" + + # Make sure we have a work directory + file mkdir ${workpath} + + # Create portpkg.xar in the work directory + set pkgpath [create_portpkg] + + return 0 +} diff --git a/src/package1.0/portunarchive.tcl b/src/package1.0/portunarchive.tcl index 02073d666..9ba93147c 100644 --- a/src/package1.0/portunarchive.tcl +++ b/src/package1.0/portunarchive.tcl @@ -223,7 +223,7 @@ proc unarchive_command_setup {args} { return -code error "No '$tar' was found on this system!" } } - xar { + (xar|xpkg) { set xar "xar" if {[catch {set xar [binaryInPath $xar]} errmsg] == 0} { ui_debug "Using $xar" diff --git a/src/port/port.tcl b/src/port/port.tcl index 4656adfa6..a872abad8 100644 --- a/src/port/port.tcl +++ b/src/port/port.tcl @@ -2683,6 +2683,7 @@ array set action_array [list \ dpkg [list action_target [action_args_const ports]] \ mpkg [list action_target [action_args_const ports]] \ pkg [list action_target [action_args_const ports]] \ + portpkg [list action_target [action_args_const ports]] \ rpm [list action_target [action_args_const ports]] \ srpm [list action_target [action_args_const ports]] \ \ diff --git a/src/port1.0/portsubmit.tcl b/src/port1.0/portsubmit.tcl index b1e3cc4e1..6379889f6 100644 --- a/src/port1.0/portsubmit.tcl +++ b/src/port1.0/portsubmit.tcl @@ -32,34 +32,16 @@ package provide portsubmit 1.0 package require portutil 1.0 +package require portportpkg 1.0 set org.macports.submit [target_new org.macports.submit submit_main] target_runtype ${org.macports.submit} always target_provides ${org.macports.submit} submit -target_requires ${org.macports.submit} main +target_requires ${org.macports.submit} portpkg set_ui_prefix -proc xar_path {args} { - global prefix_frozen - set xar "" - foreach path "${portutil::autoconf::xar_path} ${prefix_frozen}/bin/xar xar" { - if { [file executable ${path}] } { - set xar $path - break; - } - } - if { "${xar}" == "" } { - ui_error "The xar tool is required to submit ports" - ui_error "Please install the xar port before proceeding." - return -code error [msgcat::mc "Submit failed"] - } - - return $xar -} - - # escape quotes, and things that make the shell cry proc shell_escape {str} { regsub -all -- {\\} $str {\\\\} str @@ -69,143 +51,21 @@ proc shell_escape {str} { } -proc putel { fd el data } { - # Quote xml data - set quoted [string map { & & < < > > } $data] - # Write the element - puts $fd "<${el}>${quoted}" -} - - -proc putlist { fd listel itemel list } { - puts $fd "<$listel>" - foreach item $list { - putel $fd $itemel $item - } - puts $fd "" -} - - -proc create_portpkg {} { - global portname portversion prefix UI_PREFIX workpath portpath - - set xar [xar_path] - - set dirname "portpkg" - set dirpath "${workpath}/${dirname}" - set pkgpath "${workpath}/${portname}.portpkg" - set metaname "portpkg_meta.xml" - set metapath "${workpath}/${metaname}" +proc submit_main {args} { + global mp_remote_submit_url portname portversion portverbose prefix UI_PREFIX workpath portpath - # Expose and default some global variables - set vars " portname portversion maintainers categories description \ - long_description master_sites homepage epoch version revision \ - PortInfo \ - submitter_name submitter_email submitter_key \ - " - eval "global $vars" - foreach var $vars { - if {![info exists $var]} { set $var {} } - } - - # Unobscure the maintainer addresses - set maintainers [unobscure_maintainers $maintainers] - - # Make sure our workpath is clean - file delete -force $dirpath $metapath $pkgpath - - # Create the portpkg directory - file mkdir $dirpath - - # Move in the Portfile - file copy Portfile ${dirpath} - - # Move in files - if {[file isdirectory "files"]} { - file copy files ${dirpath} - } + set submiturl $mp_remote_submit_url # Preconditions for submit if {$submitter_email == ""} { return -code error [format [msgcat::mc "Submitter email is required to submit a port"]] } - # Create the metadata subdoc - set sd [open ${metapath} w] - puts $sd "" - - puts $sd "" - putel $sd name $submitter_name - putel $sd email $submitter_email - - # TODO provide means to set notes? - putel $sd notes "" - puts $sd "" - - puts $sd "" - putel $sd name $portname - putel $sd homepage $homepage - putlist $sd categories category $categories - putlist $sd maintainers maintainer $maintainers - - putel $sd epoch $epoch - putel $sd version $version - putel $sd revision $revision - - putel $sd description [join $description] - putel $sd long_description [join $long_description] - - # TODO: variants has platforms in it - if {[info exists PortInfo(variants)]} { - if {[info exists PortInfo(variant_desc)]} { - array set descs $PortInfo(variant_desc) - } else { - array set descs "" - } - - puts $sd "" - foreach v $PortInfo(variants) { - puts $sd "" - putel $sd name $v - if {[info exists descs($v)]} { - putel $sd description $descs($v) - } - puts $sd "" - } - puts $sd "" - } else { - putel $sd variants "" - } - - # TODO: Dependencies and platforms - #putel $sd dependencies "" - #putel $sd platforms "" - - puts $sd "" - - puts $sd "" - close $sd - - # Create portpkg.xar, including the metadata and the portpkg directory contents - set cmd "cd ${workpath}; ${xar} -cf ${pkgpath} --exclude \\.DSStore --exclude \\.svn ${dirname} -s ${metapath} -n ${metaname}" - if {[system $cmd] != ""} { - return -code error [format [msgcat::mc "Failed to create portpkg for port : %s"] $portname] - } - - return ${pkgpath} -} - - -proc submit_main {args} { - global mp_remote_submit_url portname portversion portverbose prefix UI_PREFIX workpath portpath - - set submiturl $mp_remote_submit_url - # Make sure we have a work directory file mkdir ${workpath} # Create portpkg.xar in the work directory - set pkgpath [create_portpkg] + set pkgpath "${workpath}/${portname}.portpkg" # TODO: If a private key was provided, create a signed digest of the submission diff --git a/src/port1.0/portutil.tcl b/src/port1.0/portutil.tcl index 51c84540c..cb2369975 100644 --- a/src/port1.0/portutil.tcl +++ b/src/port1.0/portutil.tcl @@ -1264,6 +1264,7 @@ proc target_run {ditem} { archive - dmg - pkg - + portpkg - mpkg - rpm - srpm - @@ -2117,7 +2118,7 @@ proc archiveTypeIsSupported {type} { } } } - xar { + xar|xpkg { set xar "xar" if {[catch {set xar [binaryInPath $xar]} errmsg] == 0} { return 0