+++ /dev/null
-#!/usr/bin/env python3
-#
-# Try to automatically sanitize an old "annotations" file, dropping all the
-# deprecated flags, arbitrary enforcements rules, etc.
-#
-# Usage:
-# $ ./sanitize-annotations debian.master/config/annotations
-
-import sys
-import re
-
-
-def remove_flags_and_drop_lines(file_path):
- # Read the contents of the file
- with open(file_path, "r", encoding="utf-8") as file:
- content = file.read()
-
- # Check if the file has the required headers
- lines = content.splitlines()
- if (
- len(lines) < 2
- or lines[0].strip() != "# Menu: HEADER"
- or lines[1].strip() != "# FORMAT: 4"
- ):
- print(f"ERROR: {file_path} doesn't have a valid header")
- print("Fix the headers as explained here: " +
- "https://docs.google.com/document/d/1NnGC2aknyy2TJWMsoYzhrZMr9rYMA09JQBEvC-LW_Lw/")
- sys.exit(1)
-
- # Remove unsupported annotations
- updated_content = re.sub(r"(flag|mark)<.*?>", "", content)
-
- # Drop lines with a single word and trailing spaces
- updated_content = re.sub(r"^\w+\s*$", "", updated_content, flags=re.MULTILINE)
-
- # Add a space after all caps followed by 'policy'
- updated_content = re.sub(r"([A-Z]+)(policy)", r"\1 \2", updated_content)
-
- # Add 'note' if missing
- updated_content = re.sub(r"(\s+)(<.*?>)", r"\1note\2", updated_content)
-
- # Write the updated contents back to the file
- with open(file_path, "w", encoding="utf-8") as file:
- file.write(updated_content)
-
-
-if __name__ == "__main__":
- file_path = sys.argv[1]
- remove_flags_and_drop_lines(file_path)
from argcomplete import autocomplete
from kconfig.annotations import Annotation, KConfig
+from kconfig.utils import autodetect_annotations, arg_fail
+from kconfig.version import VERSION
-VERSION = "0.1"
SKIP_CONFIGS = (
# CONFIG_VERSION_SIGNATURE is dynamically set during the build
_ARGPARSER = make_parser()
-def arg_fail(message, show_usage=True):
- print(message)
- if show_usage:
- _ARGPARSER.print_usage()
- sys.exit(1)
-
-
def print_result(config, res):
if res is not None and config not in res:
res = {config or "*": res}
def do_query(args):
if args.arch is None and args.flavour is not None:
- arg_fail("error: --flavour requires --arch")
+ arg_fail(_ARGPARSER, "error: --flavour requires --arch")
a = Annotation(args.file)
res = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour)
print_result(args.config, res)
def do_source(args):
if args.config is None:
- arg_fail("error: --source requires --config")
+ arg_fail(_ARGPARSER, "error: --source requires --config")
if not os.path.exists("tags"):
print("tags not found in the current directory, try: `make tags`")
sys.exit(1)
def do_note(args):
if args.config is None:
- arg_fail("error: --note requires --config")
+ arg_fail(_ARGPARSER, "error: --note requires --config")
# Set the note in annotations
a = Annotation(args.file)
def do_write(args):
if args.config is None:
- arg_fail("error: --write requires --config")
+ arg_fail(_ARGPARSER, "error: --write requires --config")
# Set the value in annotations ('null' means remove)
a = Annotation(args.file)
def do_export(args):
if args.arch is None:
- arg_fail("error: --export requires --arch")
+ arg_fail(_ARGPARSER, "error: --export requires --arch")
a = Annotation(args.file)
conf = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour)
if conf:
def do_import(args):
if args.arch is None:
- arg_fail("error: --arch is required with --import")
+ arg_fail(_ARGPARSER, "error: --arch is required with --import")
if args.flavour is None:
- arg_fail("error: --flavour is required with --import")
+ arg_fail(_ARGPARSER, "error: --flavour is required with --import")
if args.config is not None:
- arg_fail("error: --config cannot be used with --import (try --update)")
+ arg_fail(
+ _ARGPARSER, "error: --config cannot be used with --import (try --update)"
+ )
# Merge with the current annotations
a = Annotation(args.file)
def do_update(args):
if args.arch is None:
- arg_fail("error: --arch is required with --update")
+ arg_fail(_ARGPARSER, "error: --arch is required with --update")
# Merge with the current annotations
a = Annotation(args.file)
def do_check(args):
# Determine arch and flavour
if args.arch is None:
- arg_fail("error: --arch is required with --check")
+ arg_fail(_ARGPARSER, "error: --arch is required with --check")
print(f"check-config: loading annotations from {args.file}")
total = good = ret = 0
sys.exit(ret)
-def autodetect_annotations(args):
- if args.file:
- return
- # If --file/-f isn't specified try to automatically determine the right
- # location of the annotations file looking at debian/debian.env.
- try:
- with open("debian/debian.env", "rt", encoding="utf-8") as fd:
- args.file = fd.read().rstrip().split("=")[1] + "/config/annotations"
- except (FileNotFoundError, IndexError):
- arg_fail(
- "error: could not determine DEBDIR, try using: --file/-f", show_usage=False
- )
-
-
def main():
# Prevent broken pipe errors when showing output in pipe to other tools
# (less for example)
# Main annotations program
autocomplete(_ARGPARSER)
args = _ARGPARSER.parse_args()
- autodetect_annotations(args)
+
+ if args.file is None:
+ args.file = autodetect_annotations()
+ if args.file is None:
+ arg_fail(
+ _ARGPARSER,
+ "error: could not determine DEBDIR, try using: --file/-f",
+ show_usage=False,
+ )
if args.config and not args.config.startswith("CONFIG_"):
args.config = "CONFIG_" + args.config
--- /dev/null
+#!/usr/bin/env python3
+# -*- mode: python -*-
+# Try to automatically sanitize an old annotations file, dropping all the
+# deprecated flags, arbitrary enforcements rules, etc.
+# Copyright © 2023 Canonical Ltd.
+
+import sys
+import re
+import argparse
+from argcomplete import autocomplete
+
+from kconfig.utils import autodetect_annotations, arg_fail
+from kconfig.version import VERSION
+
+
+def make_parser():
+ parser = argparse.ArgumentParser(
+ description="Santizie old Ubuntu kernel annotations file",
+ )
+ parser.add_argument(
+ "--version", "-v", action="version", version=f"%(prog)s {VERSION}"
+ )
+ parser.add_argument(
+ "--file",
+ "-f",
+ action="store",
+ help="Specify annotations file to be sanitized",
+ )
+
+ return parser
+
+
+_ARGPARSER = make_parser()
+
+
+def remove_flags_and_drop_lines(file_path):
+ # Read the contents of the file
+ with open(file_path, "r", encoding="utf-8") as file:
+ content = file.read()
+
+ # Check if the file has the required headers
+ lines = content.splitlines()
+ if (
+ len(lines) < 2
+ or lines[0].strip() != "# Menu: HEADER"
+ or lines[1].strip() != "# FORMAT: 4"
+ ):
+ print(f"ERROR: {file_path} doesn't have a valid header")
+ print(
+ "Fix the headers as explained here: "
+ + "https://discourse.ubuntu.com/t/kernel-configuration-in-ubuntu/35857"
+ )
+ sys.exit(1)
+
+ # Remove unsupported annotations
+ updated_content = re.sub(r"(flag|mark)<.*?>", "", content)
+
+ # Drop lines with a single word and trailing spaces
+ updated_content = re.sub(r"^\w+\s*$", "", updated_content, flags=re.MULTILINE)
+
+ # Add a space after all caps followed by 'policy'
+ updated_content = re.sub(r"([A-Z]+)(policy)", r"\1 \2", updated_content)
+
+ # Add 'note' if missing
+ updated_content = re.sub(r"(\s+)(<.*?>)", r"\1note\2", updated_content)
+
+ # Write the updated contents back to the file
+ with open(file_path, "w", encoding="utf-8") as file:
+ file.write(updated_content)
+
+
+def main():
+ autocomplete(_ARGPARSER)
+ args = _ARGPARSER.parse_args()
+
+ if args.file is None:
+ args.file = autodetect_annotations()
+ if args.file is None:
+ arg_fail(
+ _ARGPARSER,
+ "error: could not determine DEBDIR, try using: --file/-f",
+ show_usage=False,
+ )
+ remove_flags_and_drop_lines(args.file)
+
+
+if __name__ == "__main__":
+ main()
--- /dev/null
+#!/usr/bin/env python
+# -*- mode: python -*-
+# Misc helpers for Kconfig and annotations
+# Copyright © 2023 Canonical Ltd.
+
+import sys
+
+
+def autodetect_annotations():
+ try:
+ with open("debian/debian.env", "rt", encoding="utf-8") as fd:
+ return fd.read().rstrip().split("=")[1] + "/config/annotations"
+ except (FileNotFoundError, IndexError):
+ return None
+
+
+def arg_fail(parser, message, show_usage=True):
+ print(message)
+ if show_usage:
+ parser.print_usage()
+ sys.exit(1)
too-many-statements,
redefined-outer-name,
# End of default disables
+ similarities,
too-many-branches,
too-many-return-statements,
too-few-public-methods
def run(self):
for cmd in ("flake8", "pylint"):
command = [cmd]
- for pattern in ("*.py", "kconfig/*.py", "bin/*"):
+ for pattern in ("*.py", "kconfig/*.py"):
command += glob(pattern)
subprocess.call(command)
url="https://git.launchpad.net/~arighi/+git/annotations-tools",
license="GPLv2",
long_description=open( # pylint: disable=consider-using-with
- os.path.join(os.path.dirname(__file__), "README.rst"),
+ os.path.join(os.path.dirname(__file__), "README.md"),
"r",
encoding="utf-8",
).read(),
entry_points={
"console_scripts": [
"annotations = kconfig.run:main",
+ "sanitize-annotations = kconfig.sanitize:main",
]
},
cmdclass={
"lint": LintCommand,
},
- scripts=[
- "bin/sanitize-annotations",
- ],
include_package_data=True,
classifiers=[
"Environment :: Console",
aliases:
- annotations
+ sanitize:
+ command: bin/sanitize-annotations
+ plugs:
+ - home
+ aliases:
+ - sanitize-annotations
+
parts:
annotations:
build-packages: