summaryrefslogtreecommitdiffstats
path: root/meta/lib/oe
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2015-05-18 12:04:55 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-12-01 21:32:04 +0000
commit1fbd76093dadd990dcb6ef8bd35659c73950cf7e (patch)
treeae6f5f9ea817ba02e721cceb9d2dda2227e2258a /meta/lib/oe
parent0b850cb231231371b496ae5ee6f7571c3de2f448 (diff)
downloadpoky-1fbd76093dadd990dcb6ef8bd35659c73950cf7e.tar.gz
lib/oe/recipeutils: refactor patch_recipe_file() to use edit_metadata()
Use bb.utils.edit_metadata() to replace some of the logic in this function; this avoids us effectively having two implementations of the same thing. In the process fix the following issues: * Insert values before any leading comments for the next variable instead of after them * Insert overridden variables (e.g. RDEPENDS_${PN}) in the correct place * Properly handle replacing varflag settings (e.g. SRC_URI[md5sum]) (From OE-Core rev: 0f81b83fc5fd908efa7f6b837137830ca65f6ed6) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oe')
-rw-r--r--meta/lib/oe/recipeutils.py160
1 files changed, 93 insertions, 67 deletions
diff --git a/meta/lib/oe/recipeutils.py b/meta/lib/oe/recipeutils.py
index 8918facb5b..5e0fda5235 100644
--- a/meta/lib/oe/recipeutils.py
+++ b/meta/lib/oe/recipeutils.py
@@ -19,9 +19,9 @@ from collections import OrderedDict, defaultdict
19 19
20 20
21# Help us to find places to insert values 21# Help us to find places to insert values
22recipe_progression = ['SUMMARY', 'DESCRIPTION', 'HOMEPAGE', 'BUGTRACKER', 'SECTION', 'LICENSE', 'LIC_FILES_CHKSUM', 'PROVIDES', 'DEPENDS', 'PR', 'PV', 'SRCREV', 'SRC_URI', 'S', 'do_fetch', 'do_unpack', 'do_patch', 'EXTRA_OECONF', 'do_configure', 'EXTRA_OEMAKE', 'do_compile', 'do_install', 'do_populate_sysroot', 'INITSCRIPT', 'USERADD', 'GROUPADD', 'PACKAGES', 'FILES', 'RDEPENDS', 'RRECOMMENDS', 'RSUGGESTS', 'RPROVIDES', 'RREPLACES', 'RCONFLICTS', 'ALLOW_EMPTY', 'do_package', 'do_deploy'] 22recipe_progression = ['SUMMARY', 'DESCRIPTION', 'HOMEPAGE', 'BUGTRACKER', 'SECTION', 'LICENSE', 'LIC_FILES_CHKSUM', 'PROVIDES', 'DEPENDS', 'PR', 'PV', 'SRCREV', 'SRC_URI', 'S', 'do_fetch()', 'do_unpack()', 'do_patch()', 'EXTRA_OECONF', 'do_configure()', 'EXTRA_OEMAKE', 'do_compile()', 'do_install()', 'do_populate_sysroot()', 'INITSCRIPT', 'USERADD', 'GROUPADD', 'PACKAGES', 'FILES', 'RDEPENDS', 'RRECOMMENDS', 'RSUGGESTS', 'RPROVIDES', 'RREPLACES', 'RCONFLICTS', 'ALLOW_EMPTY', 'do_package()', 'do_deploy()']
23# Variables that sometimes are a bit long but shouldn't be wrapped 23# Variables that sometimes are a bit long but shouldn't be wrapped
24nowrap_vars = ['SUMMARY', 'HOMEPAGE', 'BUGTRACKER'] 24nowrap_vars = ['SUMMARY', 'HOMEPAGE', 'BUGTRACKER', 'SRC_URI[md5sum]', 'SRC_URI[sha256sum]']
25list_vars = ['SRC_URI', 'LIC_FILES_CHKSUM'] 25list_vars = ['SRC_URI', 'LIC_FILES_CHKSUM']
26meta_vars = ['SUMMARY', 'DESCRIPTION', 'HOMEPAGE', 'BUGTRACKER', 'SECTION'] 26meta_vars = ['SUMMARY', 'DESCRIPTION', 'HOMEPAGE', 'BUGTRACKER', 'SECTION']
27 27
@@ -164,85 +164,111 @@ def patch_recipe_file(fn, values, patch=False, relpath=''):
164 Note that some manual inspection/intervention may be required 164 Note that some manual inspection/intervention may be required
165 since this cannot handle all situations. 165 since this cannot handle all situations.
166 """ 166 """
167
168 import bb.utils
169
170 recipe_progression_res = []
171 recipe_progression_restrs = []
172 for item in recipe_progression:
173 if item.endswith('()'):
174 key = item[:-2]
175 else:
176 key = item
177 restr = '%s(_[a-zA-Z0-9-_$(){}]+|\[[^\]]*\])?' % key
178 if item.endswith('()'):
179 recipe_progression_restrs.append(restr + '()')
180 else:
181 recipe_progression_restrs.append(restr)
182 recipe_progression_res.append(re.compile('^%s$' % restr))
183
184 def get_recipe_pos(variable):
185 for i, p in enumerate(recipe_progression_res):
186 if p.match(variable):
187 return i
188 return -1
189
167 remainingnames = {} 190 remainingnames = {}
168 for k in values.keys(): 191 for k in values.keys():
169 remainingnames[k] = recipe_progression.index(k) if k in recipe_progression else -1 192 remainingnames[k] = get_recipe_pos(k)
170 remainingnames = OrderedDict(sorted(remainingnames.iteritems(), key=lambda x: x[1])) 193 remainingnames = OrderedDict(sorted(remainingnames.iteritems(), key=lambda x: x[1]))
171 194
172 with tempfile.NamedTemporaryFile('w', delete=False) as tf: 195 modifying = False
173 def outputvalue(name): 196
174 rawtext = '%s = "%s"\n' % (name, values[name]) 197 def outputvalue(name, lines, rewindcomments=False):
175 if name in nowrap_vars: 198 if values[name] is None:
176 tf.write(rawtext) 199 return
177 elif name in list_vars: 200 rawtext = '%s = "%s"\n' % (name, values[name])
178 splitvalue = split_var_value(values[name], assignment=False) 201 addlines = []
179 if len(splitvalue) > 1: 202 if name in nowrap_vars:
180 linesplit = ' \\\n' + (' ' * (len(name) + 4)) 203 addlines.append(rawtext)
181 tf.write('%s = "%s%s"\n' % (name, linesplit.join(splitvalue), linesplit)) 204 elif name in list_vars:
182 else: 205 splitvalue = split_var_value(values[name], assignment=False)
183 tf.write(rawtext) 206 if len(splitvalue) > 1:
207 linesplit = ' \\\n' + (' ' * (len(name) + 4))
208 addlines.append('%s = "%s%s"\n' % (name, linesplit.join(splitvalue), linesplit))
184 else: 209 else:
185 wrapped = textwrap.wrap(rawtext) 210 addlines.append(rawtext)
186 for wrapline in wrapped[:-1]: 211 else:
187 tf.write('%s \\\n' % wrapline) 212 wrapped = textwrap.wrap(rawtext)
188 tf.write('%s\n' % wrapped[-1]) 213 for wrapline in wrapped[:-1]:
189 214 addlines.append('%s \\\n' % wrapline)
190 tfn = tf.name 215 addlines.append('%s\n' % wrapped[-1])
191 with open(fn, 'r') as f: 216 if rewindcomments:
192 # First runthrough - find existing names (so we know not to insert based on recipe_progression) 217 # Ensure we insert the lines before any leading comments
193 # Second runthrough - make the changes 218 # (that we'd want to ensure remain leading the next value)
194 existingnames = [] 219 for i, ln in reversed(list(enumerate(lines))):
195 for runthrough in [1, 2]: 220 if ln[0] != '#':
196 currname = None 221 lines[i+1:i+1] = addlines
197 for line in f: 222 break
198 if not currname: 223 else:
199 insert = False 224 lines.extend(addlines)
200 for k in remainingnames.keys(): 225 else:
201 for p in recipe_progression: 226 lines.extend(addlines)
202 if re.match('^%s(_prepend|_append)*[ ?:=(]' % p, line): 227
203 if remainingnames[k] > -1 and recipe_progression.index(p) > remainingnames[k] and runthrough > 1 and not k in existingnames: 228 existingnames = []
204 outputvalue(k) 229 def patch_recipe_varfunc(varname, origvalue, op, newlines):
205 del remainingnames[k] 230 if modifying:
206 break 231 # Insert anything that should come before this variable
207 for k in remainingnames.keys(): 232 pos = get_recipe_pos(varname)
208 if re.match('^%s[ ?:=]' % k, line): 233 for k in remainingnames.keys()[:]:
209 currname = k 234 if remainingnames[k] > -1 and pos >= remainingnames[k] and not k in existingnames:
210 if runthrough == 1: 235 outputvalue(k, newlines, rewindcomments=True)
211 existingnames.append(k) 236 del remainingnames[k]
212 else: 237 # Now change this variable, if it needs to be changed
213 del remainingnames[k] 238 if varname in existingnames:
214 break 239 outputvalue(varname, newlines)
215 if currname and runthrough > 1: 240 del remainingnames[varname]
216 outputvalue(currname) 241 return None, None, 0, True
217 242 else:
218 if currname: 243 if varname in values:
219 sline = line.rstrip() 244 existingnames.append(varname)
220 if not sline.endswith('\\'): 245 return origvalue, None, 0, True
221 currname = None 246
222 continue 247 # First run - establish which values we want to set are already in the file
223 if runthrough > 1: 248 varlist = [re.escape(item) for item in values.keys()]
224 tf.write(line) 249 with open(fn, 'r') as f:
225 f.seek(0) 250 changed, fromlines = bb.utils.edit_metadata(f, varlist, patch_recipe_varfunc)
226 if remainingnames: 251 # Second run - actually set everything
227 tf.write('\n') 252 modifying = True
228 for k in remainingnames.keys(): 253 varlist.extend(recipe_progression_restrs)
229 outputvalue(k) 254 changed, tolines = bb.utils.edit_metadata(fromlines, varlist, patch_recipe_varfunc, match_overrides=True)
230 255
231 with open(tfn, 'U') as f: 256 if remainingnames:
232 tolines = f.readlines() 257 if tolines[-1].strip() != '':
258 tolines.append('\n')
259 for k in remainingnames.keys():
260 outputvalue(k, tolines)
261
233 if patch: 262 if patch:
234 with open(fn, 'U') as f:
235 fromlines = f.readlines()
236 relfn = os.path.relpath(fn, relpath) 263 relfn = os.path.relpath(fn, relpath)
237 diff = difflib.unified_diff(fromlines, tolines, 'a/%s' % relfn, 'b/%s' % relfn) 264 diff = difflib.unified_diff(fromlines, tolines, 'a/%s' % relfn, 'b/%s' % relfn)
238 os.remove(tfn)
239 return diff 265 return diff
240 else: 266 else:
241 with open(fn, 'w') as f: 267 with open(fn, 'w') as f:
242 f.writelines(tolines) 268 f.writelines(tolines)
243 os.remove(tfn)
244 return None 269 return None
245 270
271
246def localise_file_vars(fn, varfiles, varlist): 272def localise_file_vars(fn, varfiles, varlist):
247 """Given a list of variables and variable history (fetched with get_var_files()) 273 """Given a list of variables and variable history (fetched with get_var_files())
248 find where each variable should be set/changed. This handles for example where a 274 find where each variable should be set/changed. This handles for example where a