diff --git a/lobster/tool.py b/lobster/tool.py index 435f381..0ce2613 100644 --- a/lobster/tool.py +++ b/lobster/tool.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # # LOBSTER - Lightweight Open BMW Software Traceability Evidence Report -# Copyright (C) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# Copyright (C) 2023, 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -24,6 +24,7 @@ from abc import ABCMeta, abstractmethod from functools import partial +from typing import List, Union, Tuple from lobster.version import FULL_NAME, get_version from lobster.errors import Message_Handler @@ -95,9 +96,21 @@ def __init__(self, name, description, extensions, official): self.add_argument = self.g_tool.add_argument @get_version - def process_commandline_options(self): + def process_commandline_options( + self, + ) -> Tuple[argparse.Namespace, List[Tuple[File_Reference, str]]]: + """Processes all command line options""" options = self.ap.parse_args() + work_list = self.process_common_options(options) + self.process_tool_options(options, work_list) + return options, work_list + def process_common_options( + self, + options: argparse.Namespace, + ) -> List[Tuple[File_Reference, str]]: + """Generates the exact list of files to work on later. The list is sorted + alphabetically.""" # Sanity check output if options.out and \ os.path.exists(options.out) and \ @@ -137,13 +150,19 @@ def process_commandline_options(self): elif os.path.isdir(item): for path, dirs, files in os.walk(item): + # TODO: why in reverse order? for n, dir_name in reversed(list(enumerate(dirs))): keep = True + # TODO: "exclude_pat" is always empty, + # and "traverse-bazel-dirs" is always ignored! for pattern in self.exclude_pat: if pattern.match(dir_name): keep = False break if not keep: + # TODO: can be simplified, "keep" is not necessary! + # But unit test should be written first, just to make + # sure! del dirs[n] for file_name in files: @@ -161,11 +180,14 @@ def process_commandline_options(self): work_list.sort() - self.process_tool_options(options, work_list) - - return options, work_list + return work_list - def write_output(self, ok, options, items): + def write_output( + self, + ok: bool, + options: argparse.Namespace, + items: List[Union[Activity, Implementation, Requirement]], + ): assert isinstance(ok, bool) assert isinstance(options, argparse.Namespace) assert isinstance(items, list) @@ -190,7 +212,11 @@ def write_output(self, ok, options, items): return 1 @abstractmethod - def process_tool_options(self, options, work_list): + def process_tool_options( + self, + options: argparse.Namespace, + work_list: List[Tuple[File_Reference, str]], + ): assert isinstance(options, argparse.Namespace) assert isinstance(work_list, list) @@ -211,8 +237,12 @@ def __init__(self, name, description, extensions, official=False): @classmethod @abstractmethod - def process(cls, options, file_name): - return True, [] + def process( + cls, + options, + file_name, + ) -> Tuple[bool, List[Union[Activity, Implementation, Requirement]]]: + pass def execute(self): options, work_list = self.process_commandline_options() diff --git a/lobster/tools/json/json.py b/lobster/tools/json/json.py index eea67e9..4b80458 100755 --- a/lobster/tools/json/json.py +++ b/lobster/tools/json/json.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # # lobster_json - Extract JSON tags for LOBSTER -# Copyright (C) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# Copyright (C) 2023-2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -16,11 +16,12 @@ # You should have received a copy of the GNU Affero General Public # License along with this program. If not, see # . - +import argparse import sys import json from pathlib import PurePath from pprint import pprint +from typing import Tuple, List from lobster.tool import LOBSTER_Per_File_Tool from lobster.items import Tracing_Tag, Activity @@ -98,12 +99,16 @@ def __init__(self): help = ("Member name indicator for " " justifications.")) - def process_tool_options(self, options, work_list): + def process_tool_options( + self, + options: argparse.Namespace, + work_list: List[Tuple[File_Reference, str]], + ): + super().process_tool_options(options, work_list) self.schema = Activity - return True @classmethod - def process(cls, options, file_name): + def process(cls, options, file_name) -> Tuple[bool, List[Activity]]: try: with open(file_name, "r", encoding="UTF-8") as fd: data = json.load(fd) @@ -158,6 +163,8 @@ def process(cls, options, file_name): required = False) else: item_just = [] + + # TODO: this can be moved into a function, as it is duplicated code if isinstance(item_just, list): pass elif isinstance(item_just, str):