source: trunk/base/src/package1.0/portmpkg.tcl @ 7155

Last change on this file since 7155 was 7155, checked in by jkh, 16 years ago

Close worker reference once we're done with it.

  • Property svn:eol-style set to native
File size: 6.6 KB
Line 
1# et:ts=4
2# portmpkg.tcl
3#
4# Copyright (c) 2002 - 2003 Apple Computer, Inc.
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15# 3. Neither the name of Apple Computer, Inc. nor the names of its contributors
16#    may be used to endorse or promote products derived from this software
17#    without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29# POSSIBILITY OF SUCH DAMAGE.
30#
31
32package provide portmpkg 1.0
33package require portutil 1.0
34
35set com.apple.mpkg [target_new com.apple.mpkg mpkg_main]
36target_runtype ${com.apple.mpkg} always
37target_provides ${com.apple.mpkg} mpkg
38target_requires ${com.apple.mpkg} pkg
39
40# define options
41options package.destpath
42
43set_ui_prefix
44
45proc mpkg_main {args} {
46    global portname portversion portrevision package.destpath UI_PREFIX
47
48    # Make sure the destination path exists.
49    system "mkdir -p ${package.destpath}"
50
51    return [package_mpkg $portname $portversion $portrevision]
52}
53
54proc make_dependency_list {portname} {
55        set result {}
56        if {[catch {set res [dportsearch "^$portname\$"]} error]} {
57                ui_error "port search failed: $error"
58                return 1
59        }
60        foreach {name array} $res {
61                array set portinfo $array
62
63                if {[info exists portinfo(depends_run)] || [info exists portinfo(depends_lib)]} {
64                        # get the union of depends_run and depends_lib
65                        # xxx: only examines the portfile component of the depspec
66                        set depends {}
67                        if {[info exists portinfo(depends_run)]} { eval "lappend depends $portinfo(depends_run)" }
68                        if {[info exists portinfo(depends_lib)]} { eval "lappend depends $portinfo(depends_lib)" }
69
70                        foreach depspec $depends {
71                                set dep [lindex [split $depspec :] 2]
72       
73                                # xxx: nasty hack
74                                if {$dep != "XFree86"} {
75                                        eval "lappend result [make_dependency_list $dep]"
76                                }
77                        }
78                }
79                lappend result $portinfo(name)/$portinfo(version)
80                unset portinfo
81        }
82        ui_debug "dependencies for ${portname}: $result"
83        return $result
84}
85
86proc make_one_package {portname portversion mpkgpath} {
87        global prefix package.destpath
88        if {[catch {set res [dportsearch "^$portname\$"]} result]} {
89                ui_error "port search failed: $result"
90                return 1
91        }
92        foreach {name array} $res {
93                array set portinfo $array
94               
95                if {[info exists portinfo(porturl)] && [info exists portinfo(version)] && $portinfo(version) == $portversion} {
96                        # only the prefix gets passed to the worker.
97                        ui_debug "building dependency package: $portname"
98                        set worker [dportopen $portinfo(porturl) [list prefix $prefix package.destpath ${mpkgpath}/Contents/Resources]]
99                        dportexec $worker pkg
100                        dportclose $worker
101                }
102                unset portinfo
103        }
104}
105
106proc package_mpkg {portname portversion portrevision} {
107    global portdbpath destpath workpath prefix portresourcepath description package.destpath long_description homepage depends_run depends_lib
108
109        set pkgpath ${package.destpath}/${portname}-${portversion}.pkg
110        set mpkgpath ${package.destpath}/${portname}-${portversion}.mpkg
111        system "mkdir -p -m 0755 ${mpkgpath}/Contents/Resources"
112
113        set dependencies {}
114        # get deplist
115        set deps [make_dependency_list $portname]
116        set deps [lsort -unique $deps]
117        foreach dep $deps {
118                set name [lindex [split $dep /] 0]
119                set vers [lindex [split $dep /] 1]
120                # don't re-package ourself
121                if {$name != $portname} {
122                        make_one_package $name $vers $mpkgpath
123                        lappend dependencies ${name}-${vers}.pkg
124                }
125        }
126       
127        # copy our own pkg into the mpkg
128        system "cp -PR ${pkgpath} ${mpkgpath}/Contents/Resources/"
129        lappend dependencies ${portname}-${portversion}.pkg
130       
131    write_PkgInfo ${mpkgpath}/Contents/PkgInfo
132    mpkg_write_info_plist ${mpkgpath}/Contents/Info.plist $portname $portversion $portrevision $prefix $dependencies
133    write_description_plist ${mpkgpath}/Contents/Resources/Description.plist $portname $portversion $description
134    # long_description, description, or homepage may not exist
135    foreach variable {long_description description homepage} {
136        if {![info exists $variable]} {
137            set pkg_$variable ""
138        } else {
139            set pkg_$variable [set $variable]
140        }
141    }
142    write_welcome_html ${mpkgpath}/Contents/Resources/Welcome.rtf $portname $portversion $pkg_long_description $pkg_description $pkg_homepage
143    file copy -force -- ${portresourcepath}/package/background.tiff ${mpkgpath}/Contents/Resources/background.tiff
144
145        return 0
146}
147
148proc mpkg_write_info_plist {infofile portname portversion portrevision destination dependencies} {
149        set vers [split $portversion "."]
150       
151        if {[string index $destination end] != "/"} {
152                append destination /
153        }
154       
155        set depxml ""
156        foreach dep $dependencies {
157                append depxml "<dict>
158                        <key>IFPkgFlagPackageLocation</key>
159                        <string>${dep}</string>
160                        <key>IFPkgFlagPackageSelection</key>
161                        <string>selected</string>
162                </dict>
163                "
164        }
165
166        set infofd [open ${infofile} w+]
167        puts $infofd {<?xml version="1.0" encoding="UTF-8"?>
168<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
169<plist version="1.0">
170}
171        puts $infofd "<dict>
172        <key>CFBundleGetInfoString</key>
173        <string>${portname} ${portversion}</string>
174        <key>CFBundleIdentifier</key>
175        <string>org.opendarwin.darwinports.mpkg.${portname}</string>
176        <key>CFBundleName</key>
177        <string>${portname}</string>
178        <key>CFBundleShortVersionString</key>
179        <string>${portversion}</string>
180        <key>IFMajorVersion</key>
181        <integer>${portrevision}</integer>
182        <key>IFMinorVersion</key>
183        <integer>0</integer>
184        <key>IFPkgFlagComponentDirectory</key>
185        <string>./Contents/Resources</string>
186        <key>IFPkgFlagPackageList</key>
187        <array>
188                ${depxml}</array>
189        <key>IFPkgFormatVersion</key>
190        <real>0.10000000149011612</real>
191</dict>
192</plist>"
193        close $infofd
194}
Note: See TracBrowser for help on using the repository browser.