source: branches/gsoc13-tests/src/package1.0/portdpkg.tcl @ 139170

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

combine multiple adjacent calls to options

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.7 KB
Line 
1# et:ts=4
2# portdpkg.tcl
3# $Id: portdpkg.tcl 106643 2013-06-03 08:11:09Z jmr@macports.org $
4#
5# Copyright (c) 2005, 2007, 2009, 2011 The MacPorts Project
6# Copyright (c) 2004 Landon Fuller <landonf@macports.org>
7# Copyright (c) 2002 - 2003 Apple Inc.
8# All rights reserved.
9#
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions
12# are met:
13# 1. Redistributions of source code must retain the above copyright
14#    notice, this list of conditions and the following disclaimer.
15# 2. Redistributions in binary form must reproduce the above copyright
16#    notice, this list of conditions and the following disclaimer in the
17#    documentation and/or other materials provided with the distribution.
18# 3. Neither the name of Apple Inc. nor the names of its contributors
19#    may be used to endorse or promote products derived from this software
20#    without specific prior written permission.
21#
22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32# POSSIBILITY OF SUCH DAMAGE.
33#
34
35package provide portdpkg 1.0
36package require portutil 1.0
37
38set org.macports.dpkg [target_new org.macports.dpkg portdpkg::main]
39target_runtype ${org.macports.dpkg} always
40target_provides ${org.macports.dpkg} dpkg
41target_requires ${org.macports.dpkg} archivefetch unarchive destroot
42
43namespace eval portdpkg {
44}
45
46# Options
47options dpkg.asroot \
48        package.destpath
49
50# Set up defaults
51default dpkg.asroot yes
52
53set_ui_prefix
54
55proc portdpkg::main {args} {
56        global UI_PREFIX destpath os.arch os.platform supported_archs configure.build_arch
57
58        ui_msg "$UI_PREFIX [format [msgcat::mc "Creating dpkg for %s-%s"] [option subport] [option version]]"
59
60        # get deplist
61        set deps [make_dependency_list [option subport]]
62        set deps [lsort -unique $deps]
63        foreach dep $deps {
64                set name [lindex [split $dep /] 0]
65                set vers [lindex [split $dep /] 1]
66                # don't re-package ourself
67                if {$name != [option subport]} {
68                        lappend dependencies "${name} (>= ${vers})"
69                }
70        }
71
72        if {[info exists dependencies]} {
73                ui_debug $dependencies
74        }
75
76        set controlpath [file join ${destpath} DEBIAN]
77        if {[file exists ${controlpath}]} {
78                if {![file isdirectory ${controlpath}]} {
79                        return -code error [format [msgcat::mc "Can not create dpkg control directory. %s not a directory."] ${controlpath}]
80                } else {
81                        ui_info [msgcat::mc "Removing stale dpkg control directory."]
82                        delete "${controlpath}"
83                }
84        }
85        file mkdir ${controlpath}
86
87        set controlfd [open [file join ${controlpath} control] w+]
88
89        # Size, in kilobytes, of ${destpath}
90        set pkg_installed-size [expr [dirSize ${destpath}] / 1024]
91
92        # Create debian dependency list
93        if {[info exists dependencies]} {
94                if {[llength ${dependencies}] != 0} {
95                        set pkg_depends [join ${dependencies} ", "]
96                }
97        }
98
99        # Create dpkg version number
100        if {[expr [option epoch] != 0]} {
101                set pkg_version "[option epoch]:[option version]"
102        } else {
103                set pkg_version "[option version]"
104        }
105        if {[expr [option revision] != 0]} {
106                append pkg_version "-[option revision]"
107        }
108
109        # Set dpkg category to first (main) category
110        set pkg_category [lindex [option categories] 0]
111
112        # Format the long description. Add a homepage if possible.
113        if {[exists long_description]} {
114                set pkg_long_description " [option long_description]\n"
115        } elseif {[exists description]} {
116                set pkg_long_description " [option description]\n"
117        } else {
118                set pkg_long_description " [option subport]\n"
119        }
120
121        if {[exists homepage]} {
122                append pkg_long_description " .\n"
123                append pkg_long_description " [option homepage]\n"
124        }
125
126        # Discern correct architecture
127        # From http://www.debian.org/doc/debian-policy/ch-customized-programs.html#fr55:
128        # The following architectures and operating systems are currently recognised
129        # by dpkg-archictecture. The architecture, arch, is one of the following:
130        # alpha, arm, hppa, i386, ia64, m68k, mips, mipsel, powerpc, s390, sh, sheb,
131        # sparc and sparc64. The operating system, os, is one of: linux, gnu,
132        # freebsd and openbsd. Use of gnu in this string is reserved for the
133        # GNU/Hurd operating system.
134        switch -regex ${configure.build_arch} {
135                i[3-9]86 { set pkg_arch "i386" }
136                x86_64 { set pkg_arch "x86_64" }
137                default { set pkg_arch ${os.arch} }
138        }
139
140        # On systems other than Linux, the Architecture must contain
141        # the operating system name
142        if {${os.platform} != "linux"} {
143                set pkg_arch "${os.platform}-${pkg_arch}"
144        } elseif {${pkg_arch} == "x86_64"} {
145                set pkg_arch "amd64"
146        }
147
148        # An architecture-independent package
149        if {$supported_archs == "noarch"} {
150                set pkg_arch "all"
151        }
152
153        puts $controlfd "Package: [option subport]"
154        puts $controlfd "Architecture: ${pkg_arch}"
155        puts $controlfd "Version: ${pkg_version}"
156        puts $controlfd "Section: ${pkg_category}"
157        puts $controlfd "Maintainer: [option maintainers]"
158        if {[info exists pkg_depends]} {
159                puts $controlfd "Depends: ${pkg_depends}"
160        }
161        puts $controlfd "Installed-Size: ${pkg_installed-size}"
162
163        puts $controlfd "Description: [option description]"
164        # pkg_long_description is pre-formatted. Do not add a newline
165        puts -nonewline $controlfd "$pkg_long_description"
166        close $controlfd
167
168        # Build debian package in package.destpath
169        system "dpkg-deb -b \"${destpath}\" \"[option package.destpath]\""
170
171        ui_info [msgcat::mc "Removing dpkg control directory."]
172        delete "${controlpath}"
173}
174
175proc portdpkg::make_dependency_list {portname} {
176        set result {}
177        if {[catch {set res [mport_lookup $portname]} error]} {
178                global errorInfo
179                ui_debug "$errorInfo"
180                ui_error "port lookup failed: $error"
181                return 1
182        }
183        foreach {name array} $res {
184                array set portinfo $array
185
186                if {[info exists portinfo(depends_run)] || [info exists portinfo(depends_lib)]} {
187                        # get the union of depends_run and depends_lib
188                        # xxx: only examines the portfile component of the depspec
189                        set depends {}
190                        if {[info exists portinfo(depends_run)]} {
191                                eval "lappend depends $portinfo(depends_run)"
192                        }
193                        if {[info exists portinfo(depends_lib)]} {
194                                eval "lappend depends $portinfo(depends_lib)"
195                        }
196
197                        foreach depspec $depends {
198                                set dep [lindex [split $depspec :] end]
199                                eval "lappend result [make_dependency_list $dep]"
200                        }
201                }
202                                lappend result $portinfo(name)/$portinfo(version)
203                                unset portinfo
204        }
205        return $result
206}
Note: See TracBrowser for help on using the repository browser.