summaryrefslogtreecommitdiffstats
path: root/meta/classes/buildhistory.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'meta/classes/buildhistory.bbclass')
-rw-r--r--meta/classes/buildhistory.bbclass251
1 files changed, 250 insertions, 1 deletions
diff --git a/meta/classes/buildhistory.bbclass b/meta/classes/buildhistory.bbclass
index 21f8493ce5..1859961012 100644
--- a/meta/classes/buildhistory.bbclass
+++ b/meta/classes/buildhistory.bbclass
@@ -1,7 +1,7 @@
1# 1#
2# Records history of build output in order to detect regressions 2# Records history of build output in order to detect regressions
3# 3#
4# Based in part on testlab.bbclass 4# Based in part on testlab.bbclass and packagehistory.bbclass
5# 5#
6# Copyright (C) 2011 Intel Corporation 6# Copyright (C) 2011 Intel Corporation
7# Copyright (C) 2007-2011 Koen Kooi <koen@openembedded.org> 7# Copyright (C) 2007-2011 Koen Kooi <koen@openembedded.org>
@@ -9,10 +9,259 @@
9 9
10BUILDHISTORY_DIR ?= "${TMPDIR}/buildhistory" 10BUILDHISTORY_DIR ?= "${TMPDIR}/buildhistory"
11BUILDHISTORY_DIR_IMAGE = "${BUILDHISTORY_DIR}/images/${MACHINE_ARCH}/${TCLIBC}/${IMAGE_BASENAME}" 11BUILDHISTORY_DIR_IMAGE = "${BUILDHISTORY_DIR}/images/${MACHINE_ARCH}/${TCLIBC}/${IMAGE_BASENAME}"
12BUILDHISTORY_DIR_PACKAGE = "${BUILDHISTORY_DIR}/packages/${MULTIMACH_TARGET_SYS}/${PN}"
12BUILDHISTORY_COMMIT ?= "0" 13BUILDHISTORY_COMMIT ?= "0"
13BUILDHISTORY_COMMIT_AUTHOR ?= "buildhistory <buildhistory@${DISTRO}>" 14BUILDHISTORY_COMMIT_AUTHOR ?= "buildhistory <buildhistory@${DISTRO}>"
14BUILDHISTORY_PUSH_REPO ?= "" 15BUILDHISTORY_PUSH_REPO ?= ""
15 16
17# Must inherit package first before changing PACKAGEFUNCS
18inherit package
19PACKAGEFUNCS += "buildhistory_emit_pkghistory"
20
21#
22# Called during do_package to write out metadata about this package
23# for comparision when writing future packages
24#
25python buildhistory_emit_pkghistory() {
26 import re
27
28 pkghistdir = d.getVar('BUILDHISTORY_DIR_PACKAGE', True)
29
30 class RecipeInfo:
31 def __init__(self, name):
32 self.name = name
33 self.pe = "0"
34 self.pv = "0"
35 self.pr = "r0"
36 self.depends = ""
37 self.packages = ""
38
39 class PackageInfo:
40 def __init__(self, name):
41 self.name = name
42 self.pe = "0"
43 self.pv = "0"
44 self.pr = "r0"
45 self.size = 0
46 self.depends = ""
47 self.rdepends = ""
48 self.rrecommends = ""
49 self.files = ""
50 self.filelist = ""
51
52 # Should check PACKAGES here to see if anything removed
53
54 def getpkgvar(pkg, var):
55 val = bb.data.getVar('%s_%s' % (var, pkg), d, 1)
56 if val:
57 return val
58 val = bb.data.getVar('%s' % (var), d, 1)
59
60 return val
61
62 def readRecipeInfo(pn, histfile):
63 rcpinfo = RecipeInfo(pn)
64 f = open(histfile, "r")
65 try:
66 for line in f:
67 lns = line.split('=')
68 name = lns[0].strip()
69 value = lns[1].strip(" \t\r\n").strip('"')
70 if name == "PE":
71 rcpinfo.pe = value
72 elif name == "PV":
73 rcpinfo.pv = value
74 elif name == "PR":
75 rcpinfo.pr = value
76 elif name == "DEPENDS":
77 rcpinfo.depends = value
78 elif name == "PACKAGES":
79 rcpinfo.packages = value
80 finally:
81 f.close()
82 return rcpinfo
83
84 def readPackageInfo(pkg, histfile):
85 pkginfo = PackageInfo(pkg)
86 f = open(histfile, "r")
87 try:
88 for line in f:
89 lns = line.split('=')
90 name = lns[0].strip()
91 value = lns[1].strip(" \t\r\n").strip('"')
92 if name == "PE":
93 pkginfo.pe = value
94 elif name == "PV":
95 pkginfo.pv = value
96 elif name == "PR":
97 pkginfo.pr = value
98 elif name == "RDEPENDS":
99 pkginfo.rdepends = value
100 elif name == "RRECOMMENDS":
101 pkginfo.rrecommends = value
102 elif name == "PKGSIZE":
103 pkginfo.size = long(value)
104 elif name == "FILES":
105 pkginfo.files = value
106 elif name == "FILELIST":
107 pkginfo.filelist = value
108 finally:
109 f.close()
110 return pkginfo
111
112 def getlastrecipeversion(pn):
113 try:
114 histfile = os.path.join(pkghistdir, "latest")
115 return readRecipeInfo(pn, histfile)
116 except EnvironmentError:
117 return None
118
119 def getlastpkgversion(pkg):
120 try:
121 histfile = os.path.join(pkghistdir, pkg, "latest")
122 return readPackageInfo(pkg, histfile)
123 except EnvironmentError:
124 return None
125
126 def squashspaces(string):
127 return re.sub("\s+", " ", string)
128
129 pn = d.getVar('PN', True)
130 pe = d.getVar('PE', True) or "0"
131 pv = d.getVar('PV', True)
132 pr = d.getVar('PR', True)
133 packages = squashspaces(d.getVar('PACKAGES', True))
134
135 rcpinfo = RecipeInfo(pn)
136 rcpinfo.pe = pe
137 rcpinfo.pv = pv
138 rcpinfo.pr = pr
139 rcpinfo.depends = squashspaces(d.getVar('DEPENDS', True) or "")
140 rcpinfo.packages = packages
141 write_recipehistory(rcpinfo, d)
142 write_latestlink(None, pe, pv, pr, d)
143
144 # Apparently the version can be different on a per-package basis (see Python)
145 pkgdest = d.getVar('PKGDEST', True)
146 for pkg in packages.split():
147 pe = getpkgvar(pkg, 'PE') or "0"
148 pv = getpkgvar(pkg, 'PV')
149 pr = getpkgvar(pkg, 'PR')
150 #
151 # Find out what the last version was
152 # Make sure the version did not decrease
153 #
154 lastversion = getlastpkgversion(pkg)
155 if lastversion:
156 last_pe = lastversion.pe
157 last_pv = lastversion.pv
158 last_pr = lastversion.pr
159 r = bb.utils.vercmp((pe, pv, pr), (last_pe, last_pv, last_pr))
160 if r < 0:
161 bb.fatal("Package version for package %s went backwards which would break package feeds from (%s:%s-%s to %s:%s-%s)" % (pkg, last_pe, last_pv, last_pr, pe, pv, pr))
162
163 pkginfo = PackageInfo(pkg)
164 pkginfo.pe = pe
165 pkginfo.pv = pv
166 pkginfo.pr = pr
167 pkginfo.rdepends = squashspaces(getpkgvar(pkg, 'RDEPENDS') or "")
168 pkginfo.rrecommends = squashspaces(getpkgvar(pkg, 'RRECOMMENDS') or "")
169 pkginfo.files = squashspaces(getpkgvar(pkg, 'FILES') or "")
170
171 # Gather information about packaged files
172 pkgdestpkg = os.path.join(pkgdest, pkg)
173 filelist = []
174 pkginfo.size = 0
175 for root, dirs, files in os.walk(pkgdestpkg):
176 relpth = os.path.relpath(root, pkgdestpkg)
177 for f in files:
178 fstat = os.lstat(os.path.join(root, f))
179 pkginfo.size += fstat.st_size
180 filelist.append(os.sep + os.path.join(relpth, f))
181 pkginfo.filelist = " ".join(filelist)
182
183 write_pkghistory(pkginfo, d)
184
185 if lastversion:
186 check_pkghistory(pkginfo, lastversion)
187
188 write_latestlink(pkg, pe, pv, pr, d)
189}
190
191
192def check_pkghistory(pkginfo, lastversion):
193
194 bb.debug(2, "Checking package history")
195 # RDEPENDS removed?
196 # PKG changed?
197 # Each file list of each package for file removals?
198
199
200def write_recipehistory(rcpinfo, d):
201 bb.debug(2, "Writing recipe history")
202
203 pkghistdir = d.getVar('BUILDHISTORY_DIR_PACKAGE', True)
204
205 if not os.path.exists(pkghistdir):
206 os.makedirs(pkghistdir)
207
208 verfile = os.path.join(pkghistdir, "%s:%s-%s" % (rcpinfo.pe, rcpinfo.pv, rcpinfo.pr))
209 f = open(verfile, "w")
210 try:
211 if rcpinfo.pe != "0":
212 f.write("PE = %s\n" % rcpinfo.pe)
213 f.write("PV = %s\n" % rcpinfo.pv)
214 f.write("PR = %s\n" % rcpinfo.pr)
215 f.write("DEPENDS = %s\n" % rcpinfo.depends)
216 f.write("PACKAGES = %s\n" % rcpinfo.packages)
217 finally:
218 f.close()
219
220
221def write_pkghistory(pkginfo, d):
222 bb.debug(2, "Writing package history")
223
224 pkghistdir = d.getVar('BUILDHISTORY_DIR_PACKAGE', True)
225
226 verpath = os.path.join(pkghistdir, pkginfo.name)
227 if not os.path.exists(verpath):
228 os.makedirs(verpath)
229
230 verfile = os.path.join(verpath, "%s:%s-%s" % (pkginfo.pe, pkginfo.pv, pkginfo.pr))
231 f = open(verfile, "w")
232 try:
233 if pkginfo.pe != "0":
234 f.write("PE = %s\n" % pkginfo.pe)
235 f.write("PV = %s\n" % pkginfo.pv)
236 f.write("PR = %s\n" % pkginfo.pr)
237 f.write("RDEPENDS = %s\n" % pkginfo.rdepends)
238 f.write("RRECOMMENDS = %s\n" % pkginfo.rrecommends)
239 f.write("PKGSIZE = %d\n" % pkginfo.size)
240 f.write("FILES = %s\n" % pkginfo.files)
241 f.write("FILELIST = %s\n" % pkginfo.filelist)
242 finally:
243 f.close()
244
245
246def write_latestlink(pkg, pe, pv, pr, d):
247 import shutil
248
249 pkghistdir = d.getVar('BUILDHISTORY_DIR_PACKAGE', True)
250
251 def rm_link(path):
252 try:
253 os.unlink(path)
254 except OSError:
255 return
256
257 if pkg:
258 filedir = os.path.join(pkghistdir, pkg)
259 else:
260 filedir = pkghistdir
261 rm_link(os.path.join(filedir, "latest"))
262 shutil.copy(os.path.join(filedir, "%s:%s-%s" % (pe, pv, pr)), os.path.join(filedir, "latest"))
263
264
16buildhistory_get_image_installed() { 265buildhistory_get_image_installed() {
17 # Anything requiring the use of the packaging system should be done in here 266 # Anything requiring the use of the packaging system should be done in here
18 # in case the packaging files are going to be removed for this image 267 # in case the packaging files are going to be removed for this image