source: trunk/base/src/port1.0/portpackage.tcl @ 1531

Last change on this file since 1531 was 1531, checked in by landonf (Landon Fuller), 18 years ago

Honor ${package.destpath}

  • Property svn:eol-style set to native
File size: 10.0 KB
Line 
1# et:ts=4
2# portpackage.tcl
3#
4# Copyright (c) 2002 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 portpackage 1.0
33package require portutil 1.0
34
35set com.apple.package [target_new com.apple.package package_main]
36${com.apple.package} set runtype always
37${com.apple.package} provides package
38${com.apple.package} requires registry
39
40# define options
41options package.type package.destpath
42
43# Set defaults
44default package.type pkg
45default package.destpath {${workpath}}
46
47set UI_PREFIX "---> "
48
49proc package_main {args} {
50    global portname portversion package.type package.destpath UI_PREFIX
51
52    set rfile [registry_exists $portname $portversion]
53    if ![string length $rfile] {
54        ui_error "Package ${portname}-${portversion} not installed on this system"
55        return -code error "Package ${portname}-${portversion} not installed on this system"
56    }
57    ui_msg "$UI_PREFIX Creating ${package.type} format package for ${portname}-${portversion}"
58    if [regexp .bz2$ $rfile] {
59        set fd [open "|bunzip2 -c $rfile" r]
60    } else {
61        set fd [open $rfile r]
62    }
63    set entry [read $fd]
64    close $fd
65
66    # Make sure the destination path exists.
67    system "mkdir -p ${package.destpath}"
68
69    # For now we only support pkg and tarball package types.
70    switch -exact -- ${package.type} {
71        pkg {
72            return [package_pkg $portname $portversion $entry]
73        }
74        tarball {
75            return [package_tarball $portname $portversion $entry]
76        }
77        default {
78            ui_error "Do not know how to generate package of type ${package.type}"
79            return -code error "Unknown package type: ${package.type}"
80        }
81    }
82}
83
84# Make a tarball version of a package.  This is our "built-in" packaging
85# method.
86proc package_tarball {portname portversion entry} {
87    global portdbpath package.destpath
88
89    set rfile [registry_exists $portname $portversion]
90    set ix [lsearch $entry contents]
91    if {$ix >= 0} {
92        set contents [lindex $entry [incr ix]]
93        set plist [mkstemp /tmp/XXXXXXXX]
94        set pfile [lindex $plist 0]
95        foreach f $contents {
96            set fname [lindex $f 0]
97            puts $pfile $fname
98        }
99        puts $pfile $rfile
100        close $pfile
101
102        set ptarget ${package.destpath}/${portname}-${portversion}.tar.gz
103        if [catch {system "gnutar -T [lindex $plist 1] -czPpf ${ptarget}"} err] {
104            ui_error "Package creation failed - gnutar returned error status: $err"
105            ui_info "Failed packing list left in [lindex $plist 1]"
106            return -code error "Package creation failed - gnutar returned error status: $err"
107        }
108        exec rm [lindex $plist 1]
109    } else {
110        ui_error "Bad registry entry for ${portname}-${portversion}, no contents"
111        return -code error "Bad registry entry for ${portname}-${portversion}, no contents"
112    }
113    return 0
114}
115
116proc package_pkg {portname portversion entry} {
117    global portdbpath destpath workpath contents prefix portresourcepath description package.destpath long_description
118
119    set resourcepath ${workpath}/pkg_resources
120    set rfile [registry_exists $portname $portversion]
121    set ix [lsearch $entry contents]
122    if {$ix >= 0} {
123                set plist [mkstemp ${workpath}/.${portname}.plist.XXXXXXXXX]
124                set pfile [lindex $plist 0]
125                # XXX hack that allows contents list to be grouped by braces
126                # XXX split contents list up if it contains one argument
127                # XXX this breaks contents lists that contain one filename, with spaces.
128                if {[llength $contents] == 1} {
129                        set clist [eval concat $contents]
130                } else {
131                        set clist $contents
132                }
133       
134                foreach f $clist {
135                        set fname [lindex $f 0]
136                        puts $pfile $fname
137                }
138                close $pfile
139       
140                if {![file isdirectory $destpath]} {
141                        if {[catch {file mkdir $destpath} result]} {
142                        ui_error "Unable to create destination root path: $result"
143                        return -code error "Unable to create destination root path: $result"
144                        }
145                }
146       
147                if [catch {system "(cd ${prefix} && gnutar -T [lindex $plist 1] -cPpf -) | (cd ${destpath} && tar xvf -)"} return] {
148                        ui_error "Package creation failed - gnutar returned error status: $return"
149                        file delete [lindex $plist 1]
150                        return -code error "Package creation failed - gnutar returned error status: $return"
151                }
152                file delete [lindex $plist 1]
153        }
154        if {![file isdirectory $resourcepath]} {
155            if {[catch {file mkdir $resourcepath} result]} {
156                ui_error "Unable to create package resource directory: $result"
157                return -code error "Unable to create package resource directory: $result"
158            }
159        }
160
161# XXX: we need to support .lproj in resources.
162        set pkgpath ${package.destpath}/${portname}.pkg
163        system "mkdir -p -m 0755 ${pkgpath}/Contents/Resources"
164        write_PkgInfo ${pkgpath}/Contents/PkgInfo
165        write_info_file ${pkgpath}/Contents/Resources/${portname}.info $portname $portversion $description $prefix
166        write_info_plist ${pkgpath}/Contents/Info.plist $portname $portversion $prefix
167        write_description_plist ${pkgpath}/Contents/Resources/Description.plist $portname $portversion $description
168        system "cp ${portresourcepath}/package/background.tiff ${pkgpath}/Contents/Resources/background.tiff"
169        system "mkbom ${destpath} ${pkgpath}/Contents/Archive.bom"
170        system "cd ${pkgpath}/Contents/Resources/ && ln -s ../Archive.bom ${portname}.bom"
171        system "cd ${destpath} && pax -w -z . > ${pkgpath}/Contents/Archive.pax.gz"
172        system "cd ${pkgpath}/Contents/Resources/ && ln -s ../Archive.pax.gz ${portname}.pax.gz"
173
174        write_sizes_file ${pkgpath}/Contents/Resources/${portname}.sizes ${pkgpath} ${destpath}
175
176    return 0
177}
178
179proc write_PkgInfo {infofile} {
180        set infofd [open ${infofile} w+]
181        puts $infofd "pmkrpkg1"
182        close $infofd
183}
184
185proc write_info_file {infofile portname portversion description destination} {
186        if {[string index $destination end] != "/"} {
187                append destination /
188        }
189
190        set infofd [open ${infofile} w+]
191        puts $infofd "Title ${portname}
192Version ${portversion}
193Description ${description}
194DefaultLocation ${destination}
195DeleteWarning
196
197### Package Flags
198
199NeedsAuthorization YES
200Required NO
201Relocatable NO
202RequiresReboot NO
203UseUserMask YES
204OverwritePermissions NO
205InstallFat NO
206RootVolumeOnly NO"
207        close $infofd
208}
209
210proc write_info_plist {infofile portname portversion destination} {
211        set vers [split $portversion "."]
212        set major [lindex $vers 0]
213        set minor [lindex $vers 1]
214       
215        if {[string index $destination end] != "/"} {
216                append destination /
217        }
218
219        set infofd [open ${infofile} w+]
220        puts $infofd {<?xml version="1.0" encoding="UTF-8"?>
221<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
222<plist version="1.0">
223}
224        puts $infofd "<dict>
225        <key>CFBundleGetInfoString</key>
226        <string>${portname} ${portversion}</string>
227        <key>CFBundleIdentifier</key>
228        <string>org.opendarwin.darwinports.${portname}</string>
229        <key>CFBundleName</key>
230        <string>${portname}</string>
231        <key>CFBundleShortVersionString</key>
232        <string>${portversion}</string>
233        <key>IFMajorVersion</key>
234        <integer>${major}</integer>
235        <key>IFMinorVersion</key>
236        <integer>${minor}</integer>
237        <key>IFPkgFlagAllowBackRev</key>
238        <false/>
239        <key>IFPkgFlagAuthorizationAction</key>
240        <string>RootAuthorization</string>
241        <key>IFPkgFlagDefaultLocation</key>
242        <string>${destination}</string>
243        <key>IFPkgFlagInstallFat</key>
244        <false/>
245        <key>IFPkgFlagIsRequired</key>
246        <false/>
247        <key>IFPkgFlagRelocatable</key>
248        <false/>
249        <key>IFPkgFlagRestartAction</key>
250        <string>NoRestart</string>
251        <key>IFPkgFlagRootVolumeOnly</key>
252        <false/>
253        <key>IFPkgFlagUpdateInstalledLanguages</key>
254        <false/>
255        <key>IFPkgFormatVersion</key>
256        <real>0.10000000149011612</real>
257</dict>
258</plist>"
259        close $infofd
260}
261
262proc write_description_plist {infofile portname portversion description} {
263        set infofd [open ${infofile} w+]
264        puts $infofd {<?xml version="1.0" encoding="UTF-8"?>
265<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
266<plist version="1.0">
267}
268        puts $infofd "<dict>
269        <key>IFPkgDescriptionDeleteWarning</key>
270        <string></string>
271        <key>IFPkgDescriptionDescription</key>
272        <string>${description}</string>
273        <key>IFPkgDescriptionTitle</key>
274        <string>${portname}</string>
275        <key>IFPkgDescriptionVersion</key>
276        <string>${portversion}</string>
277</dict>
278</plist>"
279        close $infofd
280}
281
282proc write_sizes_file {sizesfile pkgpath destpath} {
283set numFiles 0
284set compressedSize 0
285set installedSize 0
286#       set numFiles `lsbom -s "${pkgpath}/Contents/Archive.bom" | wc -l`
287#       set compresedSize `du -k -s "$pkgpath" | awk '{print $1}'`
288#       incr compressedSize 3
289#       set infoSize `ls -s "${pkgpath}/Contents/Resources/${portname}.info" | awk '{print $1}'`
290#       set bomSize `ls -s "${pkgpath}/Contents/Archive.bom" | awk '{print $1}'`
291#       set installedSize `du -k -s "$destpath" | awk '{print $1}'`
292#       incr installedSize $infoSize
293#       incr installedSize $bomSize
294#       incr installedSize 3
295       
296        set fd [open ${sizesfile} w+]
297        puts $fd "NumFiles $numFiles
298InstalledSize $installedSize
299CompressedSize $compressedSize"
300        close $fd
301}
Note: See TracBrowser for help on using the repository browser.