Skip to content

Commit

Permalink
Split LOBSTER_Tool.process_commandline_options
Browse files Browse the repository at this point in the history
The function `LOBSTER_Tool.process_commandline_options`
does two things.
It processes
- the common command line options
- and the tool specific command line options.

The code has been refactored such that there are dedicated
functions for each of these two steps.
This increases readability of the code.

Type hints have been added to some functions.

The implementation of the method `LOBSTER_Per_File_Tool.process` has been
replaced by a single `pass`, because it is abstract.
  • Loading branch information
phiwuu committed Jan 13, 2025
1 parent f2bc895 commit 4416961
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 14 deletions.
48 changes: 39 additions & 9 deletions lobster/tool.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -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:
Expand All @@ -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)
Expand All @@ -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)

Expand All @@ -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()
Expand Down
17 changes: 12 additions & 5 deletions lobster/tools/json/json.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -16,11 +16,12 @@
# You should have received a copy of the GNU Affero General Public
# License along with this program. If not, see
# <https://www.gnu.org/licenses/>.

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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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):
Expand Down

0 comments on commit 4416961

Please sign in to comment.