annotations: set and delete configs from command line
authorAndrea Righi <andrea.righi@canonical.com>
Tue, 29 Nov 2022 08:13:44 +0000 (09:13 +0100)
committerAndrea Righi <andrea.righi@canonical.com>
Tue, 29 Nov 2022 08:13:44 +0000 (09:13 +0100)
Allow to set and delete config options from command line using the
'annotations' script (instead of manually editing the annotations file).

This also provides an interface to manage the annotations file from
other scripts.

Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
annotations
kconfig/annotations.py

index 1056bb55f82280176fb445339f3e7583f1738859..5af9ebd0bdb6f265a868c997320d3d67d9e57ad2 100755 (executable)
@@ -31,8 +31,14 @@ def make_parser():
                         help='Select flavour (default is "generic")')
     parser.add_argument('--config', '-c', action='store',
                         help='Select a specific config option')
+    parser.add_argument('--note', '-n', action='store',
+                        help='Write a specific note to a config option in annotations (used with --write)')
 
     ga = parser.add_argument_group(title='Action').add_mutually_exclusive_group(required=True)
+
+    ga.add_argument('--write', '-w', action='store',
+                        metavar='VALUE', dest='value',
+                        help='Set a specific config value in annotations (use \'null\' to remove)')
     ga.add_argument('--query', '-q', action='store_true',
                         help='Query annotations')
     ga.add_argument('--export', '-e', action='store_true',
@@ -60,6 +66,24 @@ def do_query(args):
     res = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour)
     print(json.dumps(res, indent=4))
 
+def do_write(args):
+    if args.config is None:
+        arg_fail('error: --write requires --config')
+
+    # Set the value in annotations ('null' means remove)
+    a = Annotation(args.file)
+    if args.value == 'null':
+        a.remove(args.config, arch=args.arch, flavour=args.flavour)
+    else:
+        a.set(args.config, arch=args.arch, flavour=args.flavour, value=args.value, note=args.note)
+
+    # Save back to annotations
+    a.save(args.file)
+
+    # Query and print back the value
+    res = a.search_config(config=args.config)
+    print(json.dumps(res, indent=4))
+
 def do_export(args):
     if args.arch is None:
         arg_fail('error: --export requires --arch')
@@ -150,6 +174,8 @@ def main():
     autodetect_annotations(args)
     if args.query:
         do_query(args)
+    elif args.value:
+        do_write(args)
     elif args.export:
         do_export(args)
     elif args.import_file:
index 5d21ef8afa5e919a954b79fe5411380e5c784d15..fa218e7601fe806527b25e643e163d82e7612de8 100644 (file)
@@ -110,6 +110,44 @@ class Annotation(Config):
                 raise Exception(str(e) + f', line = {line}')
         return config
 
+    def _remove_entry(self, config : str):
+        if 'policy' in self.config[config]:
+            del self.config[config]['policy']
+        if 'note' in self.config[config]:
+            del self.config[config]['note']
+        if not self.config[config]:
+            del self.config[config]
+
+    def remove(self, config : str, arch: str = None, flavour: str = None):
+        if config not in self.config:
+            return
+        if arch is not None:
+            if flavour is not None:
+                flavour = f'{arch}-{flavour}'
+            else:
+                flavour = arch
+            del self.config[config]['policy'][flavour]
+            if not self.config[config]['policy']:
+                self._remove_entry(config)
+        else:
+            self._remove_entry(config)
+
+    def set(self, config : str, arch: str = None, flavour: str = None,
+            value : str = None, note : str = None):
+        if config not in self.config:
+            self.config[config] = { 'policy': {} }
+        if arch is not None:
+            if flavour is not None:
+                flavour = f'{arch}-{flavour}'
+            else:
+                flavour = arch
+            self.config[config]['policy'][flavour] = value
+        else:
+            for arch in self.arch:
+                self.config[config]['policy'][arch] = value
+        if note is not None:
+            self.config[config]['note'] = "'" + note.replace("'", '') + "'"
+
     def update(self, c: KConfig, arch: str, flavour: str = None, configs: list = []):
         """ Merge configs from a Kconfig object into Annotation object """