diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2015-05-18 12:04:55 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-12-01 21:32:04 +0000 |
commit | 1fbd76093dadd990dcb6ef8bd35659c73950cf7e (patch) | |
tree | ae6f5f9ea817ba02e721cceb9d2dda2227e2258a /meta/lib/oe | |
parent | 0b850cb231231371b496ae5ee6f7571c3de2f448 (diff) | |
download | poky-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.py | 160 |
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 |
22 | recipe_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'] | 22 | recipe_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 |
24 | nowrap_vars = ['SUMMARY', 'HOMEPAGE', 'BUGTRACKER'] | 24 | nowrap_vars = ['SUMMARY', 'HOMEPAGE', 'BUGTRACKER', 'SRC_URI[md5sum]', 'SRC_URI[sha256sum]'] |
25 | list_vars = ['SRC_URI', 'LIC_FILES_CHKSUM'] | 25 | list_vars = ['SRC_URI', 'LIC_FILES_CHKSUM'] |
26 | meta_vars = ['SUMMARY', 'DESCRIPTION', 'HOMEPAGE', 'BUGTRACKER', 'SECTION'] | 26 | meta_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 | |||
246 | def localise_file_vars(fn, varfiles, varlist): | 272 | def 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 |