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

Last change on this file since 83052 was 83052, checked in by ryandesign@…, 6 years ago

Update plist doctype

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.3 KB
Line 
1# et:ts=4
2# portmpkg.tcl
3# $Id: portmpkg.tcl 83052 2011-08-24 20:48:24Z ryandesign@macports.org $
4#
5# Copyright (c) 2005, 2007 - 2011 The MacPorts Project
6# Copyright (c) 2002 - 2004 Apple 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 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 portmpkg 1.0
35package require portutil 1.0
36
37set org.macports.mpkg [target_new org.macports.mpkg portmpkg::mpkg_main]
38target_runtype ${org.macports.mpkg} always
39target_provides ${org.macports.mpkg} mpkg
40target_requires ${org.macports.mpkg} pkg
41
42namespace eval portmpkg {
43}
44
45# define options
46options package.destpath package.flat
47
48set_ui_prefix
49
50proc portmpkg::mpkg_main {args} {
51    global subport version revision package.destpath package.flat UI_PREFIX
52
53    # Make sure the destination path exists.
54    file mkdir ${package.destpath}
55
56    return [package_mpkg $subport $version $revision]
57}
58
59proc portmpkg::make_dependency_list {portname destination} {
60    global variations prefix package.destpath package.flat
61        set result {}
62        if {[catch {set res [mport_lookup $portname]} error]} {
63                global errorInfo
64                ui_debug "$errorInfo"
65                return -code error "port lookup failed: $error"
66        }
67        array set portinfo [lindex $res 1]
68
69        if {[getuid] == 0 && [geteuid] != 0} {
70                setegid 0; seteuid 0
71                set deprivileged 1
72        }
73
74        set mport [mport_open $portinfo(porturl) [list prefix $prefix package.destpath ${destination} package.flat ${package.flat} subport $portinfo(name)] [array get variations]]
75
76    if {[info exists deprivileged]} {
77            global macportsuser
78                setegid [uname_to_gid "$macportsuser"]
79                seteuid [name_to_uid "$macportsuser"]
80        }
81
82    unset portinfo
83    array set portinfo [mport_info $mport]
84
85    # get the union of depends_run and depends_lib
86    set depends {}
87    if {[info exists portinfo(depends_run)]} { eval "lappend depends $portinfo(depends_run)" }
88    if {[info exists portinfo(depends_lib)]} { eval "lappend depends $portinfo(depends_lib)" }
89
90    foreach depspec $depends {
91        set dep [_get_dep_port $depspec]
92        if {$dep != ""} {
93            eval "lappend result [make_dependency_list $dep $destination]"
94        }
95    }
96
97    lappend result [list $portinfo(name) $portinfo(version) $mport]
98        ui_debug "dependencies for ${portname}: $result"
99        return $result
100}
101
102proc portmpkg::make_one_package {portname portversion mport} {
103        if {[getuid] == 0 && [geteuid] != 0} {
104                setegid 0; seteuid 0
105                set deprivileged 1
106        }
107
108    ui_debug "building dependency package: $portname"
109    mport_exec $mport pkg
110    mport_close $mport
111
112        if {[info exists deprivileged]} {
113            global macportsuser
114                setegid [uname_to_gid "$macportsuser"]
115                seteuid [name_to_uid "$macportsuser"]
116        }
117}
118
119proc portmpkg::package_mpkg {portname portversion portrevision} {
120    global portdbpath destpath workpath prefix porturl description package.destpath package.flat long_description homepage depends_run depends_lib
121
122        set pkgpath ${package.destpath}/${portname}-${portversion}.pkg
123        set mpkgpath ${package.destpath}/${portname}-${portversion}.mpkg
124        system "mkdir -p -m 0755 ${mpkgpath}/Contents/Resources"
125        system "mkdir -p -m 0755 ${mpkgpath}/Contents/Packages"
126
127        set dependencies {}
128        # get deplist
129        set deps [make_dependency_list $portname ${mpkgpath}/Contents/Packages]
130        set deps [lsort -unique $deps]
131        foreach dep $deps {
132                set name [lindex $dep 0]
133                set vers [lindex $dep 1]
134                set mport [lindex $dep 2]
135                # don't re-package ourself
136                if {$name != $portname} {
137                        make_one_package $name $vers $mport
138                        lappend dependencies ${name}-${vers}.pkg
139                }
140        }
141
142        # copy our own pkg into the mpkg
143        system "cp -PR ${pkgpath} ${mpkgpath}/Contents/Packages/"
144        lappend dependencies ${portname}-${portversion}.pkg
145       
146    portpkg::write_PkgInfo ${mpkgpath}/Contents/PkgInfo
147    mpkg_write_info_plist ${mpkgpath}/Contents/Info.plist $portname $portversion $portrevision $prefix $dependencies
148    portpkg::write_description_plist ${mpkgpath}/Contents/Resources/Description.plist $portname $portversion $description
149    # long_description, description, or homepage may not exist
150    foreach variable {long_description description homepage} {
151        if {![info exists $variable]} {
152            set pkg_$variable ""
153        } else {
154            set pkg_$variable [set $variable]
155        }
156    }
157    portpkg::write_welcome_html ${mpkgpath}/Contents/Resources/Welcome.html $portname $portversion $pkg_long_description $pkg_description $pkg_homepage
158    file copy -force -- [getportresourcepath $porturl "port1.0/package/background.tiff"] ${mpkgpath}/Contents/Resources/background.tiff
159
160        return 0
161}
162
163proc portmpkg::xml_escape {s} {
164        regsub -all {&} $s {\&} s
165        regsub -all {<} $s {\&lt;} s
166        regsub -all {>} $s {\&gt;} s
167        return $s
168}
169
170proc portmpkg::mpkg_write_info_plist {infofile portname portversion portrevision destination dependencies} {
171        set vers [split $portversion "."]
172       
173        if {[string index $destination end] != "/"} {
174                append destination /
175        }
176       
177        set depxml ""
178        foreach dep $dependencies {
179                set dep [xml_escape $dep]
180                append depxml "<dict>
181                        <key>IFPkgFlagPackageLocation</key>
182                        <string>${dep}</string>
183                        <key>IFPkgFlagPackageSelection</key>
184                        <string>selected</string>
185                </dict>
186                "
187        }
188
189        set portname [xml_escape $portname]
190        set portversion [xml_escape $portversion]
191        set portrevision [xml_escape $portrevision]
192
193        set infofd [open ${infofile} w+]
194        puts $infofd {<?xml version="1.0" encoding="UTF-8"?>
195<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
196<plist version="1.0">
197}
198        puts $infofd "<dict>
199        <key>CFBundleGetInfoString</key>
200        <string>${portname} ${portversion}</string>
201        <key>CFBundleIdentifier</key>
202        <string>org.macports.mpkg.${portname}</string>
203        <key>CFBundleName</key>
204        <string>${portname}</string>
205        <key>CFBundleShortVersionString</key>
206        <string>${portversion}</string>
207        <key>IFMajorVersion</key>
208        <integer>${portrevision}</integer>
209        <key>IFMinorVersion</key>
210        <integer>0</integer>
211        <key>IFPkgFlagComponentDirectory</key>
212        <string>./Contents/Packages</string>
213        <key>IFPkgFlagPackageList</key>
214        <array>
215                ${depxml}</array>
216        <key>IFPkgFormatVersion</key>
217        <real>0.10000000149011612</real>
218</dict>
219</plist>"
220        close $infofd
221}
Note: See TracBrowser for help on using the repository browser.