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

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

Add another (optional) argument to dportopen so that we can defeat the cache in cases where we need to open an existing instance
but set different options for it.
Reviewed by: kvv

  • 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] {} yes]
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.