|
16 | 16 | # You should have received a copy of the GNU Affero General Public |
17 | 17 | # License along with this program. If not, see |
18 | 18 | # <https://www.gnu.org/licenses/>. |
19 | | -import os.path |
20 | 19 | from pathlib import Path |
21 | 20 | import sys |
22 | 21 | import xml.etree.ElementTree as ET |
23 | 22 | import json |
24 | 23 | import re |
25 | | -from typing import Dict, List, Optional, Sequence |
| 24 | +from typing import Dict, Optional, Sequence |
26 | 25 | from xml.dom import minidom |
27 | 26 | from argparse import Namespace |
28 | 27 |
|
| 28 | +from lobster.common.multi_file_input_config import Config |
| 29 | +from lobster.common.multi_file_input_tool import create_worklist, MultiFileInputTool |
29 | 30 | from lobster.common.exceptions import LOBSTER_Exception |
30 | | -from lobster.common.io import lobster_write |
31 | 31 | from lobster.common.items import Activity, Tracing_Tag |
32 | 32 | from lobster.common.location import File_Reference |
33 | | -from lobster.common.meta_data_tool_base import MetaDataToolBase |
34 | 33 |
|
35 | 34 | NS = { |
36 | 35 | "ecu": "http://www.tracetronic.de/xml/ecu-test", |
|
39 | 38 | TSBLOCK = "TsBlock" |
40 | 39 |
|
41 | 40 |
|
42 | | -def get_valid_files( |
43 | | - file_dir: List[str] |
44 | | -) -> List[str]: |
45 | | - file_list = [] |
46 | | - for item in file_dir: |
47 | | - if os.path.isfile(item): |
48 | | - file_list.append(item) |
49 | | - elif os.path.isdir(item): |
50 | | - for path, _, files in os.walk(item): |
51 | | - for filename in files: |
52 | | - _, ext = os.path.splitext(filename) |
53 | | - if ext in (".pkg", ".ta"): |
54 | | - file_list.append(os.path.join(path, filename)) |
55 | | - else: |
56 | | - raise FileNotFoundError("%s is not a file or directory" % item) |
57 | | - return file_list |
58 | | - |
59 | | - |
60 | | -def write_to_file(options: Namespace, data: Dict[str, Activity]) -> None: |
61 | | - with open(options.out, "w", encoding="UTF-8") as file: |
62 | | - lobster_write(file, Activity, "lobster-pkg", data.values()) |
63 | | - print("Written output for %u items to %s" % (len(data), options.out)) |
64 | | - |
65 | | - |
66 | 41 | def create_raw_entry( |
67 | 42 | data: Dict[str, Activity], file_name: str, trace_list: list |
68 | 43 | ) -> None: |
@@ -284,87 +259,93 @@ def extract_lobster_traces_from_trace_analysis(tree, filename): |
284 | 259 | return valid_traces, misplaced_traces |
285 | 260 |
|
286 | 261 |
|
287 | | -def lobster_pkg(options): |
288 | | - """ |
289 | | - The main function to parse tracing information from .pkg files for LOBSTER. |
| 262 | +class PkgTool(MultiFileInputTool): |
| 263 | + def __init__(self): |
| 264 | + super().__init__( |
| 265 | + name="pkg", |
| 266 | + description="Extract tracing tags from pkg files for LOBSTER", |
| 267 | + extensions=["pkg", "ta"], |
| 268 | + official=True, |
| 269 | + ) |
290 | 270 |
|
291 | | - This function processes the input files or directories specified in 'options.files', |
292 | | - extracts tracing tags and activities from XML content (including both standard and |
293 | | - TRACE-ANALYSIS blocks), and writes the results to an output file |
| 271 | + def _add_config_argument(self): |
| 272 | + # This tool does not use a config file |
| 273 | + pass |
| 274 | + |
| 275 | + def lobster_pkg(self, options): |
| 276 | + """ |
| 277 | + The main function to parse tracing information from .pkg files for LOBSTER. |
| 278 | +
|
| 279 | + This function processes the input files or directories specified in |
| 280 | + 'options.files', extracts tracing tags and activities from XML content |
| 281 | + (including both standard and TRACE-ANALYSIS blocks), and writes the |
| 282 | + results to an output file |
| 283 | +
|
| 284 | + Parameters |
| 285 | + ---------- |
| 286 | + options (Namespace): Parsed command-line arguments with at least: |
| 287 | + - dir_or_files: list of file or directory paths to process |
| 288 | + - out: output file path (optional; if not set, output is report.lobster) |
| 289 | + """ |
| 290 | + config = Config( |
| 291 | + inputs=None, |
| 292 | + inputs_from_file=None, |
| 293 | + extensions=self._extensions, |
| 294 | + exclude_patterns=None, |
| 295 | + schema=Activity, |
| 296 | + ) |
| 297 | + file_list = create_worklist(config, options.dir_or_files) |
| 298 | + if not file_list: |
| 299 | + raise ValueError("No input files found to process!") |
294 | 300 |
|
295 | | - Parameters |
296 | | - ---------- |
297 | | - options (Namespace): Parsed command-line arguments with at least: |
298 | | - - files: list of file or directory paths to process |
299 | | - - out: output file path (optional; if not set, output is report.lobster) |
300 | | - """ |
301 | | - file_list = get_valid_files(options.files) |
302 | | - data = {} |
| 301 | + data = {} |
303 | 302 |
|
304 | | - for file_path in file_list: |
305 | | - filename = Path(file_path).name |
306 | | - with open(file_path, "r", encoding="UTF-8") as file: |
307 | | - try: |
308 | | - file_content = file.read() |
| 303 | + for file_path in file_list: |
| 304 | + filename = Path(file_path).name |
| 305 | + with open(file_path, "r", encoding="UTF-8") as file: |
| 306 | + try: |
| 307 | + file_content = file.read() |
309 | 308 |
|
310 | | - tree = ET.fromstring(file_content) |
| 309 | + tree = ET.fromstring(file_content) |
311 | 310 |
|
312 | | - getvalues = xml_parser(file_content, filename) |
| 311 | + getvalues = xml_parser(file_content, filename) |
313 | 312 |
|
314 | | - # Also extract from TRACE-ANALYSIS blocks |
315 | | - valid_traces, misplaced_traces = ( |
316 | | - extract_lobster_traces_from_trace_analysis( |
317 | | - tree, filename |
| 313 | + # Also extract from TRACE-ANALYSIS blocks |
| 314 | + valid_traces, misplaced_traces = ( |
| 315 | + extract_lobster_traces_from_trace_analysis( |
| 316 | + tree, filename |
| 317 | + ) |
318 | 318 | ) |
319 | | - ) |
320 | | - getvalues.extend(valid_traces) |
321 | | - for msg in misplaced_traces: |
322 | | - print(msg) |
323 | | - |
324 | | - if getvalues: |
325 | | - create_raw_entry(data, file.name, json.dumps(getvalues)) |
326 | | - else: |
327 | | - create_default_activity(file_content, filename, data) |
328 | | - |
329 | | - except ET.ParseError as err: |
330 | | - print(f"Error parsing XML file '{filename}' : {err}") |
331 | | - raise |
332 | | - except LOBSTER_Exception as err: |
333 | | - err.dump() |
334 | | - raise |
335 | | - |
336 | | - # Set default output file if not specified |
337 | | - output_file = getattr(options, "out", None) |
338 | | - if not output_file: |
339 | | - options.out = "report.lobster" |
340 | | - |
341 | | - write_to_file(options, data) |
342 | | - |
343 | | - return 0 |
344 | | - |
345 | | - |
346 | | -class PkgTool(MetaDataToolBase): |
347 | | - def __init__(self): |
348 | | - super().__init__( |
349 | | - name="pkg", |
350 | | - description="Extract tracing tags from pkg files for LOBSTER", |
351 | | - official=True, |
352 | | - ) |
353 | | - self._argument_parser.add_argument( |
354 | | - "files", |
355 | | - nargs="+", |
356 | | - metavar="FILE|DIR", |
357 | | - help="Path to pkg file or directory.", |
| 319 | + getvalues.extend(valid_traces) |
| 320 | + for msg in misplaced_traces: |
| 321 | + print(msg) |
| 322 | + |
| 323 | + if getvalues: |
| 324 | + create_raw_entry(data, file.name, json.dumps(getvalues)) |
| 325 | + else: |
| 326 | + create_default_activity(file_content, filename, data) |
| 327 | + |
| 328 | + except ET.ParseError as err: |
| 329 | + print(f"Error parsing XML file '{filename}' : {err}") |
| 330 | + raise |
| 331 | + except LOBSTER_Exception as err: |
| 332 | + err.dump() |
| 333 | + raise |
| 334 | + |
| 335 | + items = ( |
| 336 | + list(data.values()) |
| 337 | + if not isinstance(data.values(), list) |
| 338 | + else data.values() |
358 | 339 | ) |
359 | | - self._argument_parser.add_argument( |
360 | | - "--out", |
361 | | - required=True, |
362 | | - help="write output to this file; otherwise output is report.lobster", |
| 340 | + self._write_output( |
| 341 | + schema=config.schema, |
| 342 | + out_file=options.out, |
| 343 | + items=items, |
363 | 344 | ) |
364 | 345 |
|
365 | 346 | def _run_impl(self, options: Namespace) -> int: |
366 | 347 | try: |
367 | | - lobster_pkg(options) |
| 348 | + self.lobster_pkg(options) |
368 | 349 | return 0 |
369 | 350 | except (ValueError, FileNotFoundError, |
370 | 351 | LOBSTER_Exception, ET.ParseError) as exception: |
|
0 commit comments