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

Last change on this file since 73303 was 73303, checked in by jmr@…, 7 years ago

pass variations along to dependencies in portmpkg (#27231)

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