diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2014-12-19 10:20:30 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2014-12-23 10:18:20 +0000 |
commit | b1e5a6794f1631a82c57fad0724ddf5fb9639652 (patch) | |
tree | c38ca6997be6ea82ca4ddbc05e00b118d3cc9e82 /bitbake/lib/bb | |
parent | 7b70d5e8a481a7485a3866623efce993ddd9b607 (diff) | |
download | poky-b1e5a6794f1631a82c57fad0724ddf5fb9639652.tar.gz |
bitbake: utils: add basic metadata manipulation functions
* Add a generic edit_metadata_file() function to modify variable
assignments in any metadata file (conf, bb, bbappend) using a callback
for flexibility
* Add a specific edit_bblayers_conf() function to modify
conf/bblayers.conf and add and/or remove layers from the BBLAYERS
value within it.
(Bitbake rev: aa03a28b442549dd8ffe92ae4d6390f62202a76a)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb')
-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 | |||