diff options
| -rw-r--r-- | bitbake/lib/bb/utils.py | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py index d7c5067613..f26349f4a9 100644 --- a/bitbake/lib/bb/utils.py +++ b/bitbake/lib/bb/utils.py | |||
| @@ -915,3 +915,130 @@ def exec_flat_python_func(func, *args, **kwargs): | |||
| 915 | comp = bb.utils.better_compile(code, '<string>', '<string>') | 915 | comp = bb.utils.better_compile(code, '<string>', '<string>') |
| 916 | bb.utils.better_exec(comp, context, code, '<string>') | 916 | bb.utils.better_exec(comp, context, code, '<string>') |
| 917 | return context['retval'] | 917 | return context['retval'] |
| 918 | |||
| 919 | def edit_metadata_file(meta_file, variables, func): | ||
| 920 | """Edit a recipe or config file and modify one or more specified | ||
| 921 | variable values set in the file using a specified callback function. | ||
| 922 | The file is only written to if the value(s) actually change. | ||
| 923 | """ | ||
| 924 | var_res = {} | ||
| 925 | for var in variables: | ||
| 926 | var_res[var] = re.compile(r'^%s[ \t]*[?=]+' % var) | ||
| 927 | |||
| 928 | updated = False | ||
| 929 | varset_start = '' | ||
| 930 | newlines = [] | ||
| 931 | in_var = None | ||
| 932 | full_value = '' | ||
| 933 | |||
| 934 | def handle_var_end(): | ||
| 935 | (newvalue, indent, minbreak) = func(in_var, full_value) | ||
| 936 | if newvalue != full_value: | ||
| 937 | if isinstance(newvalue, list): | ||
| 938 | intentspc = ' ' * indent | ||
| 939 | if minbreak: | ||
| 940 | # First item on first line | ||
| 941 | if len(newvalue) == 1: | ||
| 942 | newlines.append('%s "%s"\n' % (varset_start, newvalue[0])) | ||
| 943 | else: | ||
| 944 | newlines.append('%s "%s\\\n' % (varset_start, newvalue[0])) | ||
| 945 | for item in newvalue[1:]: | ||
| 946 | newlines.append('%s%s \\\n' % (intentspc, item)) | ||
| 947 | newlines.append('%s"\n' % indentspc) | ||
| 948 | else: | ||
| 949 | # No item on first line | ||
| 950 | newlines.append('%s " \\\n' % varset_start) | ||
| 951 | for item in newvalue: | ||
| 952 | newlines.append('%s%s \\\n' % (intentspc, item)) | ||
| 953 | newlines.append('%s"\n' % intentspc) | ||
| 954 | else: | ||
| 955 | newlines.append('%s "%s"\n' % (varset_start, newvalue)) | ||
| 956 | return True | ||
| 957 | return False | ||
| 958 | |||
| 959 | with open(meta_file, 'r') as f: | ||
| 960 | for line in f: | ||
| 961 | if in_var: | ||
| 962 | value = line.rstrip() | ||
| 963 | full_value += value[:-1] | ||
| 964 | if value.endswith('"') or value.endswith("'"): | ||
| 965 | if handle_var_end(): | ||
| 966 | updated = True | ||
| 967 | in_var = None | ||
| 968 | else: | ||
| 969 | matched = False | ||
| 970 | for (varname, var_re) in var_res.iteritems(): | ||
| 971 | if var_re.match(line): | ||
| 972 | splitvalue = line.split('"', 1) | ||
| 973 | varset_start = splitvalue[0].rstrip() | ||
| 974 | value = splitvalue[1].rstrip() | ||
| 975 | if value.endswith('\\'): | ||
| 976 | value = value[:-1] | ||
| 977 | full_value = value | ||
| 978 | if value.endswith('"') or value.endswith("'"): | ||
| 979 | if handle_var_end(): | ||
| 980 | updated = True | ||
| 981 | else: | ||
| 982 | in_var = varname | ||
| 983 | matched = True | ||
| 984 | break | ||
| 985 | if not matched: | ||
| 986 | newlines.append(line) | ||
| 987 | if updated: | ||
| 988 | with open(meta_file, 'w') as f: | ||
| 989 | f.writelines(newlines) | ||
| 990 | |||
| 991 | def edit_bblayers_conf(bblayers_conf, add, remove): | ||
| 992 | """Edit bblayers.conf, adding and/or removing layers""" | ||
| 993 | |||
| 994 | import fnmatch | ||
| 995 | |||
| 996 | def remove_trailing_sep(pth): | ||
| 997 | if pth and pth[-1] == os.sep: | ||
| 998 | pth = pth[:-1] | ||
| 999 | return pth | ||
| 1000 | |||
| 1001 | def layerlist_param(value): | ||
| 1002 | if not value: | ||
| 1003 | return [] | ||
| 1004 | elif isinstance(value, list): | ||
| 1005 | return [remove_trailing_sep(x) for x in value] | ||
| 1006 | else: | ||
| 1007 | return [remove_trailing_sep(value)] | ||
| 1008 | |||
| 1009 | notadded = [] | ||
| 1010 | notremoved = [] | ||
| 1011 | |||
| 1012 | addlayers = layerlist_param(add) | ||
| 1013 | removelayers = layerlist_param(remove) | ||
| 1014 | |||
| 1015 | def handle_bblayers(varname, origvalue): | ||
| 1016 | updated = False | ||
| 1017 | bblayers = [remove_trailing_sep(x) for x in origvalue.split()] | ||
| 1018 | if removelayers: | ||
| 1019 | for removelayer in removelayers: | ||
| 1020 | matched = False | ||
| 1021 | for layer in bblayers: | ||
| 1022 | if fnmatch.fnmatch(layer, removelayer): | ||
| 1023 | updated = True | ||
| 1024 | matched = True | ||
| 1025 | bblayers.remove(layer) | ||
| 1026 | break | ||
| 1027 | if not matched: | ||
| 1028 | notremoved.append(removelayer) | ||
| 1029 | if addlayers: | ||
| 1030 | for addlayer in addlayers: | ||
| 1031 | if addlayer not in bblayers: | ||
| 1032 | updated = True | ||
| 1033 | bblayers.append(addlayer) | ||
| 1034 | else: | ||
| 1035 | notadded.append(addlayer) | ||
| 1036 | |||
| 1037 | if updated: | ||
| 1038 | return (bblayers, 2, False) | ||
| 1039 | else: | ||
| 1040 | return (origvalue, 2, False) | ||
| 1041 | |||
| 1042 | edit_metadata_file(bblayers_conf, ['BBLAYERS'], handle_bblayers) | ||
| 1043 | return (notadded, notremoved) | ||
| 1044 | |||
