pacman-key: rework importing distro/repo provided keyrings
[pacman-ng.git] / test / pacman / pmpkg.py
blob00f345c0975bb21ea88b97f593e37ad4dcf277cb
1 #! /usr/bin/python
3 # Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 import os
20 import tempfile
21 import stat
22 import shutil
23 from StringIO import StringIO
24 import tarfile
26 import util
28 class pmpkg(object):
29 """Package object.
31 Object holding data from an Arch Linux package.
32 """
34 def __init__(self, name, version = "1.0-1"):
35 self.path = "" #the path of the generated package
36 # desc
37 self.name = name
38 self.version = version
39 self.desc = ""
40 self.groups = []
41 self.url = ""
42 self.license = []
43 self.arch = ""
44 self.builddate = ""
45 self.installdate = ""
46 self.packager = ""
47 self.size = 0
48 self.csize = 0
49 self.isize = 0
50 self.reason = 0
51 self.md5sum = "" # sync only
52 self.pgpsig = "" # sync only
53 self.replaces = []
54 self.depends = []
55 self.optdepends = []
56 self.conflicts = []
57 self.provides = []
58 # files
59 self.files = []
60 self.backup = []
61 # install
62 self.install = {
63 "pre_install": "",
64 "post_install": "",
65 "pre_remove": "",
66 "post_remove": "",
67 "pre_upgrade": "",
68 "post_upgrade": "",
70 self.path = None
72 def __str__(self):
73 s = ["%s" % self.fullname()]
74 s.append("description: %s" % self.desc)
75 s.append("url: %s" % self.url)
76 s.append("files: %s" % " ".join(self.files))
77 s.append("reason: %d" % self.reason)
78 return "\n".join(s)
80 def fullname(self):
81 """Long name of a package.
83 Returns a string formatted as follows: "pkgname-pkgver".
84 """
85 return "%s-%s" % (self.name, self.version)
87 def filename(self):
88 """File name of a package, including its extension.
90 Returns a string formatted as follows: "pkgname-pkgver.PKG_EXT_PKG".
91 """
92 return "%s%s" % (self.fullname(), util.PM_EXT_PKG)
94 @staticmethod
95 def parse_filename(name):
96 filename = name
97 if filename[-1] == "*":
98 filename = filename.rstrip("*")
99 if filename.find(" -> ") != -1:
100 filename, extra = filename.split(" -> ")
101 elif filename.find("|") != -1:
102 filename, extra = filename.split("|")
103 return filename
105 def makepkg(self, path):
106 """Creates an Arch Linux package archive.
108 A package archive is generated in the location 'path', based on the data
109 from the object.
111 archive_files = []
113 # .PKGINFO
114 data = ["pkgname = %s" % self.name]
115 data.append("pkgver = %s" % self.version)
116 data.append("pkgdesc = %s" % self.desc)
117 data.append("url = %s" % self.url)
118 data.append("builddate = %s" % self.builddate)
119 data.append("packager = %s" % self.packager)
120 data.append("size = %s" % self.size)
121 if self.arch:
122 data.append("arch = %s" % self.arch)
123 for i in self.license:
124 data.append("license = %s" % i)
125 for i in self.replaces:
126 data.append("replaces = %s" % i)
127 for i in self.groups:
128 data.append("group = %s" % i)
129 for i in self.depends:
130 data.append("depend = %s" % i)
131 for i in self.optdepends:
132 data.append("optdepend = %s" % i)
133 for i in self.conflicts:
134 data.append("conflict = %s" % i)
135 for i in self.provides:
136 data.append("provides = %s" % i)
137 for i in self.backup:
138 data.append("backup = %s" % i)
139 archive_files.append((".PKGINFO", "\n".join(data)))
141 # .INSTALL
142 if any(self.install.values()):
143 archive_files.append((".INSTALL", self.installfile()))
145 self.path = os.path.join(path, self.filename())
146 util.mkdir(os.path.dirname(self.path))
148 # Generate package metadata
149 tar = tarfile.open(self.path, "w:gz")
150 for name, data in archive_files:
151 info = tarfile.TarInfo(name)
152 info.size = len(data)
153 tar.addfile(info, StringIO(data))
155 # Generate package file system
156 for name in self.files:
157 fileinfo = util.getfileinfo(name)
158 info = tarfile.TarInfo(fileinfo["filename"])
159 if fileinfo["hasperms"]:
160 info.mode = fileinfo["perms"]
161 if fileinfo["isdir"]:
162 info.type = tarfile.DIRTYPE
163 tar.addfile(info)
164 elif fileinfo["islink"]:
165 info.type = tarfile.SYMTYPE
166 info.linkname = fileinfo["link"]
167 tar.addfile(info)
168 else:
169 # TODO wow what a hack, adding a newline to match mkfile?
170 filedata = name + "\n"
171 info.size = len(filedata)
172 tar.addfile(info, StringIO(filedata))
174 tar.close()
176 def install_package(self, root):
177 """Install the package in the given root."""
178 for f in self.files:
179 util.mkfile(root, f, f)
180 path = os.path.join(root, f)
181 if os.path.isfile(path):
182 os.utime(path, (355, 355))
184 def full_filelist(self):
185 """Generate a list of package files.
187 Each path is decomposed to generate the list of all directories leading
188 to the file.
190 Example with 'usr/local/bin/dummy':
191 The resulting list will be:
192 usr/
193 usr/local/
194 usr/local/bin/
195 usr/local/bin/dummy
197 file_set = set()
198 for name in self.files:
199 name = self.parse_filename(name)
200 file_set.add(name)
201 while "/" in name:
202 name, tmp = name.rsplit("/", 1)
203 file_set.add(name + "/")
204 return sorted(file_set)
206 def local_backup_entries(self):
207 return ["%s\t%s" % (self.parse_filename(i), util.mkmd5sum(i)) for i in self.backup]
209 def installfile(self):
210 data = []
211 for key, value in self.install.iteritems():
212 if value:
213 data.append("%s() {\n%s\n}\n" % (key, value))
215 return "\n".join(data)
217 # vim: set ts=4 sw=4 et: