source: trunk/base/portmgr/packaging/packageall.tcl @ 27961

Last change on this file since 27961 was 26177, checked in by jmpp@…, 13 years ago

Finally merging the dp2mp-move branch into trunk, woot!

This basically means all strings in our sources,
whether it's something we output to the user or something
internal, such as a function/proc naming, are entirely in
the macports namespace and we no longer mix darwinports
with apple with macports strings.

It also means we now have new paths in svn and on
the client side at installation time, added to a
cleaner structure under ${prefix}/var/. Read
http://trac.macports.org/projects/macports/wiki/MacPortsRenaming
for more information.

NOTE: This commit also marks the rsync server finally
being moved over to the macosforge boxes, with the new
layout outlined in the dp2mp-move branch in place.
DNS entries still point to the old rsync server for
macports, however, so sync'ing/selfupdating an installation
based on these sources will be temporarily broken
until dns refresh.

To developers and testers, please do test the upgrade
target in the main base/Makefile as thouroughly as
possible and report any bugs/shortcomings/unexpected_behavior
to me, thanks!

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 11.9 KB
Line 
1#!/usr/bin/env tclsh
2# packageall.tcl
3# $Id: packageall.tcl 26177 2007-06-15 10:11:22Z jmpp@macports.org $
4#
5# Copyright (c) 2003 Kevin Van Vechten <kevin@opendarwin.org>
6# Copyright (c) 2002 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
33package require darwinports
34
35# globals
36set portdir .
37
38# UI Instantiations
39array set ui_options {}
40# ui_options(ports_debug) - If set, output debugging messages.
41# ui_options(ports_verbose) - If set, output info messages (ui_info)
42# ui_options(ports_quiet) - If set, don't output "standard messages"
43
44# ui_options accessor
45proc ui_isset {val} {
46    global ui_options
47    if {[info exists ui_options($val)]} {
48        if {$ui_options($val) == "yes"} {
49            return 1
50        }
51    }
52    return 0
53}
54
55# UI Callback
56
57proc ui_prefix {priority} {
58    switch $priority {
59        debug {
60                return "DEBUG: "
61        }
62        error {
63                return "Error: "
64        }
65        warn {
66                return "Warning: "
67        }
68        default {
69                return ""
70        }
71    }
72}
73
74proc ui_channels {priority} {
75    global logfd
76    switch $priority {
77        debug {
78            if {[ui_isset ports_debug]} {
79                return {stdout}
80            } else {
81                return {}
82            }
83        }
84        info {
85                        # put verbose stuff only to the log file
86            if {[ui_isset ports_verbose]} {
87                return {$logfd}
88            } else {
89                return {}
90                        }
91                }
92        msg {
93            if {[ui_isset ports_quiet]} {
94                return {}
95                        } else {
96                                return {stdout}
97                        }
98                }
99        default {
100                return {stdout}
101        }
102    }
103}
104       
105proc pkg_ui_log {message} {
106    global logfd
107    if {[string length $logfd] > 0 } {
108        log_message $logfd $message
109    }
110}
111
112proc log_message {channel message} {
113    seek $channel 0 end
114    puts $channel $message
115    flush $channel
116}
117
118# Recursive bottom-up approach of building a list of dependencies.
119proc get_dependencies {portname includeBuildDeps} {
120        set result {}
121       
122        if {[catch {set res [dportsearch "^$portname\$"]} error]} {
123                global errorInfo
124                ui_debug "$errorInfo"
125                ui_error "Internal error: port search failed: $error"
126                return {}
127        }
128        foreach {name array} $res {
129                array set portinfo $array
130                if {![info exists portinfo(name)] ||
131                        ![info exists portinfo(version)] || 
132                        ![info exists portinfo(categories)]} {
133                        ui_error "Internal error: $name missing some portinfo keys"
134                        continue
135                }
136               
137                set portname $portinfo(name)
138                set portversion $portinfo(version)
139                set category [lindex $portinfo(categories) 0]
140
141                # Append the package itself to the result list
142                #set pkgpath ${category}/${portname}-${portversion}.pkg
143                lappend result [list $portname $portversion $category]
144
145                # Append the package's dependents to the result list
146                set depends {}
147                if {[info exists portinfo(depends_run)]} { eval "lappend depends $portinfo(depends_run)" }
148                if {[info exists portinfo(depends_lib)]} { eval "lappend depends $portinfo(depends_lib)" }
149                if {$includeBuildDeps != "" && [info exists portinfo(depends_build)]} { 
150                        eval "lappend depends $portinfo(depends_build)"
151                }
152                foreach depspec $depends {
153                        set dep [lindex [split $depspec :] end]
154                        set x [get_dependencies $dep $includeBuildDeps]
155                        eval "lappend result $x"
156                        set result [lsort -unique $result]
157                }
158        }
159        return $result
160}
161
162# Install binary packages if they've already been built.  This will
163# speed up the testing, since we won't have to recompile dependencies
164# which have already been compiled.
165
166proc install_binary_if_available {dep basepath} {
167        set portname [lindex $dep 0]
168        set portversion [lindex $dep 1]
169        set category [lindex $dep 2]
170       
171        set pkgpath ${basepath}/${category}/${portname}-${portversion}.pkg
172        if {[file readable $pkgpath]} {
173                ui_msg "installing binary: $pkgpath"
174                if {[catch {system "cd / && gunzip -c ${pkgpath}/Contents/Archive.pax.gz | pax -r"} error]} {
175                        global errorInfo
176                        ui_debug "$errorInfo"
177                        ui_error "Internal error: $error"
178                }
179                # Touch the receipt
180                # xxx: use some variable to describe this path
181                if {[catch {system "touch /opt/local/var/db/dports/receipts/${portname}-${portversion}.bz2"} error]} {
182                        global errorInfo
183                        ui_debug "$errorInfo"
184                        ui_error "Internal error: $error"
185                }
186        }
187}
188
189
190# Standard procedures
191
192proc fatal args {
193    global argv0
194    puts stderr "$argv0: $args"
195    exit
196}
197
198# Main
199array set options [list]
200array set variations [list]
201#       set ui_options(ports_verbose) yes
202
203if {[catch {dportinit ui_options options variations} result]} {
204    puts "Failed to initialize ports system, $result"
205    exit 1
206}
207
208package require Pextlib
209
210# If no arguments were given, default to all ports.
211if {[llength $argv] == 0} {
212        lappend argv ".*"
213}
214
215foreach pname $argv {
216
217if {[catch {set res [dportsearch "^${pname}\$"]} result]} {
218        puts "port search failed: $result"
219        exit 1
220}
221
222set logpath "/darwinports/logs"
223set logfd ""
224
225foreach {name array} $res {
226        array unset portinfo
227        array set portinfo $array
228
229        # Start with verbose output off;
230        # this will prevent the repopulation of /opt from getting logged.
231        set ui_options(ports_verbose) no
232
233        if {![info exists portinfo(porturl)]} {
234                puts stderr "Internal error: no porturl for $name"
235                continue
236        }
237       
238        set pkgbase /darwinports/pkgs/
239        set porturl $portinfo(porturl)
240
241        # Skip up-to-date packages
242        if {[regsub {^file://} $portinfo(porturl) "" portpath]} {
243                if {[info exists portinfo(name)] &&
244                        [info exists portinfo(version)] &&
245                        [info exists portinfo(categories)]} {
246                        set portname $portinfo(name)
247                        set portversion $portinfo(version)
248                        set category [lindex $portinfo(categories) 0]
249                        set pkgfile ${pkgbase}/${category}/${portname}-${portversion}.pkg/Contents/Archive.pax.gz
250                        if {[file readable $pkgfile] && ([file mtime ${pkgfile}] > [file mtime ${portpath}/Portfile])} {
251                                puts stderr "Skipping ${portname}-${portversion}; package is up to date."
252                                continue
253                        }
254                }
255        }
256       
257        # Skipt packages which previously failed
258               
259        # Building the port:
260        # - remove /opt so it won't pollute the port.
261        # - re-install DarwinPorts.
262        # - keep distfiles outside /opt so we don't have to keep fetching them.
263        # - send out an email to the maintainer if any errors occurred.
264
265        ui_msg "removing /opt"
266        #unset ui_options(ports_verbose)
267        if {[catch {system "rm -Rf /opt"} error]} {
268                puts stderr "Internal error: $error"
269        }
270        if {[catch {system "rm -Rf /usr/X11R6"} error]} {
271                puts stderr "Internal error: $error"
272        }
273        if {[catch {system "rm -Rf /etc/X11"} error]} {
274                puts stderr "Internal error: $error"
275        }
276        if {[catch {system "rm -Rf /etc/fonts"} error]} {
277                puts stderr "Internal error: $error"
278        }
279        if {[catch {system "cd $env(HOME)/darwinports && make && make install"} error]} {
280                puts stderr "Internal error: $error"
281        }
282        if {[catch {system "rmdir /opt/local/var/db/dports/distfiles"} error]} {
283                puts stderr "Internal error: $error"
284        }
285        if {[catch {system "ln -s /darwinports/distfiles /opt/local/var/db/dports/distfiles"} error]} {
286                puts stderr "Internal error: $error"
287        }
288        #set ui_options(ports_verbose) yes
289
290        # If there was a log file left over from the previous pass,
291        # then the port failed with an error.  Send the log in an
292        # email to the maintainers.
293        if {[string length $logfd] > 0} {
294                close $logfd
295                set logfd ""
296        }
297        #if {[file readable $logfilename]} {
298        #       if {[catch {system "cat $logfilename | /usr/sbin/sendmail -t"} error]} {
299        #               puts stderr "Internal error: $error"
300        #       }
301        #}
302
303        # Open the log file for writing
304        set logfd [open ${logpath}/${name}.log w]
305
306        set valid 1
307
308        set lint_errors {}
309        set portname ""
310        set portversion ""
311        set description ""
312        set category ""
313
314        if {![info exists portinfo(name)]} {
315                lappend lint_errors "missing name key"
316                set valid 0
317        } else {
318                set portname $portinfo(name)
319        }
320       
321        if {![info exists portinfo(description)]} {
322                lappend lint_errors "missing description key"
323                set valid 0
324        } else {
325                set description $portinfo(description)
326        }
327       
328        if {![info exists portinfo(version)]} {
329                lappend lint_errors "missing version key"
330                set valid 0
331        } else {
332                set portversion $portinfo(version)
333        }
334       
335        if {![info exists portinfo(categories)]} {
336                lappend lint_errors "missing categories key"
337                set valid 0
338        } else {
339                set category [lindex $portinfo(categories) 0]
340        }
341       
342        if {![info exists portinfo(maintainers)]} {
343                append lint_errors "missing maintainers key"
344                set valid 0
345                set maintainers kevin@opendarwin.org
346        } else {
347                set maintainers $portinfo(maintainers)
348        }
349       
350        pkg_ui_log "To: [join $maintainers {, }]"
351        pkg_ui_log "From: donotreply@opendarwin.org"
352        pkg_ui_log "Subject: DarwinPorts $portinfo(name)-$portinfo(version) build failure"
353        pkg_ui_log ""
354        pkg_ui_log "The following is a transcript produced by the DarwinPorts automated build       "
355        pkg_ui_log "system.  You are receiving this email because you are listed as a maintainer    "
356        pkg_ui_log "of this port, which has failed the automated packaging process.  Please update  "
357        pkg_ui_log "the port as soon as possible."
358        pkg_ui_log ""
359        pkg_ui_log ""
360        pkg_ui_log "Thank you,"
361        pkg_ui_log "The DarwinPorts Team"
362        pkg_ui_log ""
363        pkg_ui_log "================================================================================"
364        pkg_ui_log ""
365
366        if {!$valid} {
367                foreach error $lint_errors {
368                        ui_error $error
369                }
370        }
371
372        ui_msg "packaging ${category}/${portname}-${portversion}"
373
374        # Install binary dependencies if we can, to speed things up.
375        #set depends {}
376        #if {[info exists portinfo(depends_run)]} { eval "lappend depends $portinfo(depends_run)" }
377        #if {[info exists portinfo(depends_lib)]} { eval "lappend depends $portinfo(depends_lib)" }
378        #if {[info exists portinfo(depends_build)]} { eval "lappend depends $portinfo(depends_build)" }
379        #foreach depspec $depends {
380        #       set dep [lindex [split $depspec :] end]
381                #install_binary_if_available $dep $pkgbase
382        #}
383        set dependencies [get_dependencies $portname 1]
384        set dependencies [lsort -unique $dependencies]
385        foreach dep $dependencies {
386                install_binary_if_available $dep $pkgbase
387        }
388
389        set options(package.type) pkg
390        set options(package.destpath) ${pkgbase}/${category}/
391
392        # Turn on verbose output for the build
393        set ui_options(ports_verbose) yes
394        if {[catch {set workername [dportopen $porturl [array get options] [array get variations] yes]} result] ||
395                $result == 1} {
396                global errorInfo
397                ui_debug "$errorInfo"
398            ui_error "Internal error: unable to open port: $result"
399            continue
400        }       
401        if {[catch {set result [dportexec $workername pkg]} result] ||
402                $result == 1} {
403                global errorInfo
404                ui_debug "$errorInfo"
405            ui_error "port package failed: $result"
406                dportclose $workername
407            continue
408        }
409        set ui_options(ports_verbose) no
410        # Turn verbose output off after the build
411
412        dportclose $workername
413
414        # We made it to the end.  We can delete the log file.
415        close $logfd
416        set logfd ""
417        file delete ${logpath}/${name}.log
418}
419
420}
421# end foreach pname
Note: See TracBrowser for help on using the repository browser.