Coverage for mddb_workflow/utils/register.py: 67%
51 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-29 15:48 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-29 15:48 +0000
1from sys import argv
2from os.path import exists
3from datetime import datetime
5from mddb_workflow.utils.auxiliar import load_json, save_json, warn, get_git_version
6from mddb_workflow.utils.constants import DATE_STYLE
7from mddb_workflow.utils.type_hints import *
10class Register:
11 """ The register tracks activity along multiple runs and thus avoids repeating some already succeeded tests
12 It is also responsible for storing test failure warnings to be written in metadata. """
13 def __init__ (self, register_file : 'File'):
14 # Save the previous register
15 self.file = register_file
16 # Save the current workflow call
17 # Quote those arguments including space, since it means they were quoted when inputed
18 quoted_argv = [ f"'{arg}'" if ' ' in arg else arg for arg in argv ]
19 self.call = ' '.join(quoted_argv)
20 # Save the current date
21 self.date = datetime.today().strftime(DATE_STYLE)
22 # Save the current version
23 self.version = get_git_version()
24 # Set the tests tracker
25 self.tests = {}
26 # Set the warnings list, which will be filled by failing tests
27 self.warnings = []
28 # Inherit test results and warning from the register last entry
29 self.entries = []
30 if self.file.exists:
31 # Read the register in disk
32 self.entries = load_json(self.file.path)
33 last_entry = self.entries[-1]
34 # Inherit test results
35 for test_name, test_result in last_entry['tests'].items():
36 self.tests[test_name] = test_result
37 # Inherit warnings
38 for warning in last_entry['warnings']:
39 # DANI: Para quitarnos de encima warnings con el formato antiguo
40 if not warning.get('tag', None):
41 continue
42 self.warnings.append(warning)
43 # Save the entry for the first time
44 self.save()
46 def __repr__ (self):
47 return str(self.to_dict())
49 def to_dict (self) -> dict:
50 # Set a dictionary with the current values
51 dictionary = {
52 'call': self.call,
53 'date': self.date,
54 'version': self.version,
55 'tests': self.tests,
56 'warnings': self.warnings,
57 }
58 return dictionary
60 def update_test (self, key : str, value : Optional[bool]):
61 """ Update a test result and save the register. """
62 self.tests[key] = value
63 self.save()
65 def get_warnings (self, tag : str) -> list[dict]:
66 """ Get current warnings filtered by tag. """
67 return [ warning for warning in self.warnings if warning['tag'] == tag ]
69 def add_warning (self, tag : str, message : str):
70 """ Add warnings with the right format and save the register.
71 A flag is to be passed to handle further removal of warnings. """
72 warn(message)
73 # If we already had this exact warning then do not repeat it
74 for warning in self.warnings:
75 if warning['tag'] == tag and warning['message'] == message : return
76 # Add a new warning
77 warning = { 'tag': tag, 'message': message }
78 self.warnings.append(warning)
79 self.save()
81 def remove_warnings (self, tag : str):
82 """ Remove warnings filtered by tag and save the register. """
83 self.warnings = [ warning for warning in self.warnings if warning['tag'] != tag ]
84 self.save()
86 def save (self):
87 """ Save the register to a json file. """
88 # If path does not exist then do nothing
89 # WARNING: I know this looks a bit silent
90 # WARNING: Otherwise it is a constant spam when something goes wrong close to beginning
91 if not exists(self.file.basepath):
92 return
93 # Set a new entry for the current run
94 current_entry = self.to_dict()
95 # Write entries to disk
96 save_json(self.entries + [ current_entry ], self.file.path, indent = 4)