diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2015-09-22 17:21:15 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-09-23 09:53:11 +0100 |
commit | 374e1fed0ee2be830d4d721f820e30bb5494e003 (patch) | |
tree | 10e6f836f187aa927f14ea3e473b7103c8fd0c76 | |
parent | 7fb3fb9cc279c2e1fd2b8dd0040f7cab6a5a28db (diff) | |
download | poky-374e1fed0ee2be830d4d721f820e30bb5494e003.tar.gz |
lib/oe/recipeutils: properly split unexpanded variable values
Variables such as SRC_URI which are space-separated may also contain
Python expressions (${@...}) which themselves contain spaces that
shouldn't be split when splitting the value into items. In order to
ensure this we need to use a custom splitting function instead of just
string.split().
This issue could be seen when doing "devtool modify sudo", adding a
commit to the resulting source repository then "devtool update-recipe" -
the Python expression in SRC_URI was being unnecessarily broken onto
multiple lines.
Fixes [YOCTO #8046].
(From OE-Core rev: bbec2ee98a08270c681189a6ba26beb1034d3e2f)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | meta/lib/oe/recipeutils.py | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/meta/lib/oe/recipeutils.py b/meta/lib/oe/recipeutils.py index d4fa72651c..190ac3a078 100644 --- a/meta/lib/oe/recipeutils.py +++ b/meta/lib/oe/recipeutils.py | |||
@@ -95,6 +95,63 @@ def get_var_files(fn, varlist, d): | |||
95 | return varfiles | 95 | return varfiles |
96 | 96 | ||
97 | 97 | ||
98 | def split_var_value(value, assignment=True): | ||
99 | """ | ||
100 | Split a space-separated variable's value into a list of items, | ||
101 | taking into account that some of the items might be made up of | ||
102 | expressions containing spaces that should not be split. | ||
103 | Parameters: | ||
104 | value: | ||
105 | The string value to split | ||
106 | assignment: | ||
107 | True to assume that the value represents an assignment | ||
108 | statement, False otherwise. If True, and an assignment | ||
109 | statement is passed in the first item in | ||
110 | the returned list will be the part of the assignment | ||
111 | statement up to and including the opening quote character, | ||
112 | and the last item will be the closing quote. | ||
113 | """ | ||
114 | inexpr = 0 | ||
115 | lastchar = None | ||
116 | out = [] | ||
117 | buf = '' | ||
118 | for char in value: | ||
119 | if char == '{': | ||
120 | if lastchar == '$': | ||
121 | inexpr += 1 | ||
122 | elif char == '}': | ||
123 | inexpr -= 1 | ||
124 | elif assignment and char in '"\'' and inexpr == 0: | ||
125 | if buf: | ||
126 | out.append(buf) | ||
127 | out.append(char) | ||
128 | char = '' | ||
129 | buf = '' | ||
130 | elif char.isspace() and inexpr == 0: | ||
131 | char = '' | ||
132 | if buf: | ||
133 | out.append(buf) | ||
134 | buf = '' | ||
135 | buf += char | ||
136 | lastchar = char | ||
137 | if buf: | ||
138 | out.append(buf) | ||
139 | |||
140 | # Join together assignment statement and opening quote | ||
141 | outlist = out | ||
142 | if assignment: | ||
143 | assigfound = False | ||
144 | for idx, item in enumerate(out): | ||
145 | if '=' in item: | ||
146 | assigfound = True | ||
147 | if assigfound: | ||
148 | if '"' in item or "'" in item: | ||
149 | outlist = [' '.join(out[:idx+1])] | ||
150 | outlist.extend(out[idx+1:]) | ||
151 | break | ||
152 | return outlist | ||
153 | |||
154 | |||
98 | def patch_recipe_file(fn, values, patch=False, relpath=''): | 155 | def patch_recipe_file(fn, values, patch=False, relpath=''): |
99 | """Update or insert variable values into a recipe file (assuming you | 156 | """Update or insert variable values into a recipe file (assuming you |
100 | have already identified the exact file you want to update.) | 157 | have already identified the exact file you want to update.) |
@@ -112,7 +169,7 @@ def patch_recipe_file(fn, values, patch=False, relpath=''): | |||
112 | if name in nowrap_vars: | 169 | if name in nowrap_vars: |
113 | tf.write(rawtext) | 170 | tf.write(rawtext) |
114 | elif name in list_vars: | 171 | elif name in list_vars: |
115 | splitvalue = values[name].split() | 172 | splitvalue = split_var_value(values[name], assignment=False) |
116 | if len(splitvalue) > 1: | 173 | if len(splitvalue) > 1: |
117 | linesplit = ' \\\n' + (' ' * (len(name) + 4)) | 174 | linesplit = ' \\\n' + (' ' * (len(name) + 4)) |
118 | tf.write('%s = "%s%s"\n' % (name, linesplit.join(splitvalue), linesplit)) | 175 | tf.write('%s = "%s%s"\n' % (name, linesplit.join(splitvalue), linesplit)) |
@@ -518,7 +575,7 @@ def bbappend_recipe(rd, destlayerdir, srcfiles, install=None, wildcardver=False, | |||
518 | instfunclines.append(line) | 575 | instfunclines.append(line) |
519 | return (instfunclines, None, 4, False) | 576 | return (instfunclines, None, 4, False) |
520 | else: | 577 | else: |
521 | splitval = origvalue.split() | 578 | splitval = split_var_value(origvalue, assignment=False) |
522 | changed = False | 579 | changed = False |
523 | removevar = varname | 580 | removevar = varname |
524 | if varname in ['SRC_URI', 'SRC_URI_append%s' % appendoverride]: | 581 | if varname in ['SRC_URI', 'SRC_URI_append%s' % appendoverride]: |