source: trunk/base/src/package1.0/portarchive.tcl @ 16589

Last change on this file since 16589 was 13738, checked in by pguyot (Paul Guyot), 15 years ago

Add a lot of missing $Id$

  • Property svn:eol-style set to native
File size: 11.8 KB
Line 
1# vim:ts=4 sw=4 fo=croq
2# portarchive.tcl
3# $Id: portarchive.tcl,v 1.6 2005/08/27 00:07:27 pguyot Exp $
4#
5# Copyright (c) 2004 Robert Shaw <rshaw@opendarwin.org>
6# Copyright (c) 2002 - 2003 Apple Computer, Inc.
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions
11# are met:
12# 1. Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14# 2. Redistributions in binary form must reproduce the above copyright
15#    notice, this list of conditions and the following disclaimer in the
16#    documentation and/or other materials provided with the distribution.
17# 3. Neither the name of Apple Computer, Inc. nor the names of its contributors
18#    may be used to endorse or promote products derived from this software
19#    without specific prior written permission.
20#
21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31# POSSIBILITY OF SUCH DAMAGE.
32#
33
34package provide portarchive 1.0
35package require portutil 1.0
36
37set com.apple.archive [target_new com.apple.archive archive_main]
38target_init ${com.apple.archive} archive_init
39target_provides ${com.apple.archive} archive
40target_requires ${com.apple.archive} main fetch extract checksum patch configure build destroot
41target_prerun ${com.apple.archive} archive_start
42target_postrun ${com.apple.archive} archive_finish
43
44# defaults
45default archive.dir {${destpath}}
46default archive.env {}
47default archive.cmd {}
48default archive.pre_args {}
49default archive.args {}
50default archive.post_args {}
51
52default archive.destpath {${portarchivepath}}
53default archive.type {}
54default archive.file {}
55default archive.path {}
56
57set_ui_prefix
58
59proc archive_init {args} {
60        global UI_PREFIX target_state_fd
61        global variations package.destpath workpath
62        global ports_force ports_source_only ports_binary_only
63        global portname portversion portrevision portvariants
64        global archive.destpath archive.type archive.file archive.path
65
66        # Check mode in case archive called directly by user
67        if {[option portarchivemode] != "yes"} {
68                return -code error "Archive mode is not enabled!"
69        }
70
71        # Define port variants if not already defined
72        if { ![info exists portvariants] } {
73                set portvariants ""
74                set vlist [lsort -ascii [array names variations]]
75                # Put together variants in the form +foo+bar for the archive name
76                foreach v $vlist {
77                        if { ![string equal $v [option os.platform]] && ![string equal $v [option os.arch]] } {
78                                set portvariants "${portvariants}+${v}"
79                        }
80                }
81        }
82
83        # Define archive destination directory and target filename
84        if {![string equal ${archive.destpath} ${workpath}] && ![string equal ${archive.destpath} ""]} {
85                set archive.destpath [file join ${archive.destpath} [option os.platform] [option os.arch]]
86        }
87
88        # Determine if archive should be skipped
89        set skipped 0
90        if {[check_statefile target com.apple.archive $target_state_fd]} {
91                return 0
92        } elseif {[check_statefile target com.apple.unarchive $target_state_fd] && ([info exists ports_binary_only] && $ports_binary_only == "yes")} {
93                ui_debug "Skipping archive ($portname) since binary-only is set"
94                set skipped 1
95        } elseif {[info exists ports_source_only] && $ports_source_only == "yes"} {
96                ui_debug "Skipping archive ($portname) since source-only is set"
97                set skipped 1
98        } else {
99                set unsupported 0
100                foreach archive.type [option portarchivetype] {
101                        if {[catch {archiveTypeIsSupported ${archive.type}} errmsg] == 0} {
102                                set archive.file "${portname}-${portversion}_${portrevision}${portvariants}.[option os.arch].${archive.type}"
103                                set archive.path "[file join ${archive.destpath} ${archive.file}]"
104                        } else {
105                                ui_debug "Skipping [string toupper ${archive.type}] archive: $errmsg"
106                                set unsupported [expr $unsupported + 1]
107                        }
108                }
109                if {[llength [option portarchivetype]] == $unsupported} {
110                        ui_debug "Skipping archive ($portname) since specified archive types not supported"
111                        set skipped 1
112                }
113        }
114        # Skip archive target by setting state
115        if {$skipped == 1} {
116                write_statefile target "com.apple.archive" $target_state_fd
117        }
118
119        return 0
120}
121
122proc archive_start {args} {
123        global UI_PREFIX
124        global portname portversion portrevision portvariants
125
126        if {[llength [option portarchivetype]] > 1} {
127                ui_msg "$UI_PREFIX [format [msgcat::mc "Packaging [join [option portarchivetype] {, }] archives for %s %s_%s%s"] $portname $portversion $portrevision $portvariants]"
128        } else {
129                ui_msg "$UI_PREFIX [format [msgcat::mc "Packaging [option portarchivetype] archive for %s %s_%s%s"] $portname $portversion $portrevision $portvariants]"
130        }
131
132        return 0
133}
134
135proc archive_command_setup {args} {
136        global archive.env archive.cmd
137        global archive.pre_args archive.args archive.post_args
138        global archive.type archive.path
139        global os.platform os.version
140
141        # Define appropriate archive command and options
142        set archive.env {}
143        set archive.cmd {}
144        set archive.pre_args {}
145        set archive.args {}
146        set archive.post_args {}
147        switch -regex ${archive.type} {
148                cp(io|gz) {
149                        set pax "pax"
150                        if {[catch {set pax [binaryInPath $pax]} errmsg] == 0} {
151                                ui_debug "Using $pax"
152                                set archive.cmd "$pax"
153                                set archive.pre_args {-w -v -x cpio}
154                                if {[regexp {z$} ${archive.type}]} {
155                                        set gzip "gzip"
156                                        if {[catch {set gzip [binaryInPath $gzip]} errmsg] == 0} {
157                                                ui_debug "Using $gzip"
158                                                set archive.args {.}
159                                                set archive.post_args "| $gzip -c9 > ${archive.path}"
160                                        } else {
161                                                ui_debug $errmsg
162                                                return -code error "No '$gzip' was found on this system!"
163                                        }
164                                } else {
165                                        set archive.args "-f ${archive.path} ."
166                                }
167                        } else {
168                                ui_debug $errmsg
169                                return -code error "No '$pax' was found on this system!"
170                        }
171                }
172                t(ar|bz|gz) {
173                        set tar "tar"
174                        if {[catch {set tar [binaryInPath $tar]} errmsg] == 0} {
175                                ui_debug "Using $tar"
176                                set archive.cmd "$tar"
177                                set archive.pre_args {-cvf}
178                                if {[regexp {z$} ${archive.type}]} {
179                                        if {[regexp {bz$} ${archive.type}]} {
180                                                set gzip "bzip2"
181                                        } else {
182                                                set gzip "gzip"
183                                        }
184                                        if {[catch {set gzip [binaryInPath $gzip]} errmsg] == 0} {
185                                                ui_debug "Using $gzip"
186                                                set archive.args {- .}
187                                                set archive.post_args "| $gzip -c9 > ${archive.path}"
188                                        } else {
189                                                ui_debug $errmsg
190                                                return -code error "No '$gzip' was found on this system!"
191                                        }
192                                } else {
193                                        set archive.args "${archive.path} ."
194                                }
195                        } else {
196                                ui_debug $errmsg
197                                return -code error "No '$tar' was found on this system!"
198                        }
199                }
200                xar {
201                        set xar "xar"
202                        if {[catch {set xar [binaryInPath $xar]} errmsg] == 0} {
203                                ui_debug "Using $xar"
204                                set archive.cmd "$xar"
205                                set archive.pre_args {-cvf}
206                                set archive.args "${archive.path} ."
207                        } else {
208                                ui_debug $errmsg
209                                return -code error "No '$xar' was found on this system!"
210                        }
211                }
212                zip {
213                        set zip "zip"
214                        if {[catch {set zip [binaryInPath $zip]} errmsg] == 0} {
215                                ui_debug "Using $zip"
216                                set archive.cmd "$zip"
217                                set archive.pre_args {-ry9}
218                                set archive.args "${archive.path} ."
219                        } else {
220                                ui_debug $errmsg
221                                return -code error "No '$zip' was found on this system!"
222                        }
223                }
224                default {
225                        return -code error "Invalid port archive type '${archive.type}' specified!"
226                }
227        }
228
229        return 0
230}
231
232proc archive_main {args} {
233        global UI_PREFIX variations
234        global workpath destpath portpath ports_force
235        global portname portversion portrevision portvariants
236        global archive.destpath archive.type archive.file archive.path
237
238        # Create archive destination path (if needed)
239        if {![file isdirectory ${archive.destpath}]} {
240                system "mkdir -p ${archive.destpath}"
241        }
242
243        # Copy state file into destroot for archiving
244        # +STATE contains a copy of the DP state information
245    set statefile [file join $workpath .darwinports.${portname}.state]
246        file copy -force $statefile [file join $destpath "+STATE"]
247
248        # Copy Portfile into destroot for archiving
249        # +PORTFILE contains a copy of the DP Portfile
250    set portfile [file join $portpath Portfile]
251        file copy -force $portfile [file join $destpath "+PORTFILE"]
252
253        # Create some informational files that we don't really use just yet,
254        # but we may in the future in order to allow port installation from
255        # archives without a full "dports" tree of Portfiles.
256        #
257        # Note: These have been modeled after FreeBSD type package files to
258        # start. We can change them however we want for actual future use if
259        # needed.
260        #
261        # +COMMENT contains the port description
262        set fd [open [file join $destpath "+COMMENT"] w]
263    if {[exists description]} {
264                puts $fd "[option description]"
265        }
266        close $fd
267        # +DESC contains the port long_description and homepage
268        set fd [open [file join $destpath "+DESC"] w]
269        if {[exists long_description]} {
270                puts $fd "[option long_description]"
271        }
272        if {[exists homepage]} {
273                puts $fd "\nWWW: [option homepage]"
274        }
275        close $fd
276        # +CONTENTS contains the port version/name info and all installed
277        # files and checksums
278        set control [list]
279        set fd [open [file join $destpath "+CONTENTS"] w]
280        puts $fd "@name ${portname}-${portversion}_${portrevision}${portvariants}"
281        puts $fd "@portname ${portname}"
282        puts $fd "@portversion ${portversion}"
283        puts $fd "@portrevision ${portrevision}"
284        set vlist [lsort -ascii [array names variations]]
285        foreach v $vlist {
286                if {![string equal $v [option os.platform]] && ![string equal $v [option os.arch]]} {
287                        puts $fd "@portvariant +${v}"
288                }
289        }
290        foreach fullpath [exec find $destpath ! -type d] {
291                set relpath [strsed $fullpath "s|^$destpath/||"]
292                if {![regexp {^[+]} $relpath]} {
293                        puts $fd "$relpath"
294                        if {[file isfile $fullpath]} {
295                                ui_debug "checksum file: $fullpath"
296                                set checksum [md5 file $fullpath]
297                                puts $fd "@comment MD5:$checksum"
298                        }
299                } else {
300                        lappend control $relpath
301                }
302        }
303        foreach relpath $control {
304                puts $fd "@ignore"
305                puts $fd "$relpath"
306        }
307        close $fd
308
309        # Now create the archive(s)
310        # Loop through archive types
311        foreach archive.type [option portarchivetype] {
312                if {[catch {archiveTypeIsSupported ${archive.type}} errmsg] == 0} {
313                        # Define archive file/path
314                        set archive.file "${portname}-${portversion}_${portrevision}${portvariants}.[option os.arch].${archive.type}"
315                        set archive.path "[file join ${archive.destpath} ${archive.file}]"
316
317                        # Setup archive command
318                        archive_command_setup
319
320                        # Remove existing archive
321                        if {[file exists ${archive.path}]} {
322                                ui_info "$UI_PREFIX [format [msgcat::mc "Deleting previous %s"] ${archive.file}]"
323                                file delete -force ${archive.path}
324                        }
325
326                        ui_info "$UI_PREFIX [format [msgcat::mc "Creating %s"] ${archive.file}]"
327                        system "[command archive]"
328                        ui_info "$UI_PREFIX [format [msgcat::mc "Archive %s packaged"] ${archive.file}]"
329                }
330        }
331
332    return 0
333}
334
335proc archive_finish {args} {
336        global UI_PREFIX
337        global portname portversion portrevision portvariants
338        global destpath
339
340        # Cleanup all control files when finished
341        set control_files [glob -nocomplain -types f [file join $destpath +*]]
342        foreach file $control_files {
343                ui_debug "removing file: $file"
344                file delete -force $file
345        }
346
347        if {[llength [option portarchivetype]] > 1} {
348                ui_info "$UI_PREFIX [format [msgcat::mc "Archives for %s %s_%s%s packaged"] $portname $portversion $portrevision $portvariants]"
349        } else {
350                ui_info "$UI_PREFIX [format [msgcat::mc "Archive for %s %s_%s%s packaged"] $portname $portversion $portrevision $portvariants]"
351        }
352        return 0
353}
354
Note: See TracBrowser for help on using the repository browser.