11# -*- coding: utf-8 -*-
22
3- import json
43from pickle import Unpickler
54import sys
65import argparse
76from argparse import ArgumentParser
8- from typing import Any , Dict , Optional
7+ from typing import Any , Dict
98from .modules import load_modules
109from .modules .machine import Machine
10+ from .modules .module import ModuleHandler
1111from .logger import configure_logging , get_logger
1212from .yaml import load_config
13- from structlog .typing import BindableLogger
14- from pathlib import Path
15-
16-
17- def parse_args (args : list [str ]) -> argparse .Namespace :
18- # Putting args-parser in seperate function to make this testable
19- arg_parser = ArgumentParser ("Rookify" )
20-
21- # --dry-run option
22- arg_parser .add_argument ("--dry-run" , action = "store_true" , dest = "dry_run_mode" )
23-
24- # --list-modules option
25- arg_parser .add_argument (
26- "--list-modules" , action = "store_true" , help = "List all modules"
27- )
28-
29- # Custom ReadAction to set 'all' if nothing is specified for --read-pickle
30- class ReadAction (argparse .Action ):
31- def __call__ (
32- self ,
33- parser : ArgumentParser ,
34- namespace : argparse .Namespace ,
35- values : Optional [Any ],
36- option_string : Optional [str ] = None ,
37- ) -> None :
38- setattr (namespace , self .dest , values if values is not None else "all" )
39-
40- # Custom ShowProgressAction to set 'all' if nothing is specified for --show-progress
41- class ShowProgressAction (argparse .Action ):
42- def __call__ (
43- self ,
44- parser : ArgumentParser ,
45- namespace : argparse .Namespace ,
46- values : Optional [Any ],
47- option_string : Optional [str ] = None ,
48- ) -> None :
49- setattr (namespace , self .dest , values if values is not None else "all" )
50-
51- arg_parser .add_argument (
52- "--read-pickle" ,
53- nargs = "?" ,
54- action = ReadAction ,
55- dest = "read_pickle" ,
56- metavar = "<section>" ,
57- help = "Show the content of the pickle file. Default argument is 'all', you can also specify a section you want to look at." ,
58- required = False ,
59- )
60-
61- arg_parser .add_argument (
62- "--show-progress" ,
63- nargs = "?" ,
64- action = ShowProgressAction ,
65- dest = "show_progress" ,
66- metavar = "<module>" ,
67- help = "Show progress of the modules. Default argument is 'all', you can also specify a module you want to get the progress status from." ,
68- required = False ,
69- )
70- return arg_parser .parse_args (args )
7113
7214
7315def load_pickler (pickle_file_name : str ) -> Any :
@@ -77,75 +19,26 @@ def load_pickler(pickle_file_name: str) -> Any:
7719 return states_data
7820
7921
80- def get_all_modules () -> list [str ]:
81- base_path = Path (__file__ ).resolve ().parent
82- module_path = Path (base_path ) / "modules"
83- module_names = []
84- for item in module_path .iterdir ():
85- if item .is_dir () and item .name != "__pycache__" :
86- module_names .append (item .name )
87- return module_names
88-
89-
90- def sort_pickle_file (unsorted_states_data : Dict [str , Any ]) -> Dict [str , Any ]:
91- # sort the pickle-file alfabetically
92- iterable_dict = iter (unsorted_states_data )
93- first_key = next (iterable_dict )
94- data_values = unsorted_states_data [first_key ]["data" ]
95- sorted_data_by_keys = {k : data_values [k ] for k in sorted (data_values )}
96- return sorted_data_by_keys
97-
98-
99- def read_pickle_file (
100- args : argparse .Namespace , pickle_file_name : str , log : BindableLogger
101- ) -> None :
102- states_data = load_pickler (pickle_file_name )
103- sorted_states_data = sort_pickle_file (states_data )
22+ def parse_args (args : list [str ]) -> argparse .Namespace :
23+ # Putting args-parser in seperate function to make this testable
24+ arg_parser = ArgumentParser ("Rookify" )
10425
105- # Check if a specific section should be listed
106- if args .read_pickle != "all" :
107- if args .read_pickle not in sorted_states_data .keys ():
108- log .error (f"The section { args .read_pickle } does not exist" )
109- else :
110- sorted_states_data = sorted_states_data [args .read_pickle ]
26+ # --dry-run option
27+ arg_parser .add_argument ("--dry-run" , action = "store_true" , dest = "dry_run_mode" )
11128
112- log .info (
113- 'Current state as retrieved from pickle-file: \n "{0}": {1}' .format (
114- args .read_pickle , json .dumps (sorted_states_data , indent = 4 )
115- )
29+ arg_parser .add_argument (
30+ "--show-states" ,
31+ action = "store_true" ,
32+ dest = "show_states" ,
33+ help = "Show states of the modules." ,
11634 )
11735
118-
119- def show_progress_from_state (
120- args : argparse .Namespace , pickle_file_name : str , log : BindableLogger
121- ) -> bool :
122- # states_data = load_pickler(pickle_file_name)
123- modules = get_all_modules ()
124-
125- # Check if a specific module should be targeted
126- if args .show_progress != "all" :
127- module = args .show_progress
128- if args .show_progress not in modules :
129- log .error (f"The module { module } does not exist" )
130- return False
131- log .info ("Show progress of the {0} module" .format (args .show_progress ))
132- return True
133- else :
134- log .info ("Show progress of {0} modules" .format (args .show_progress ))
135- return True
36+ return arg_parser .parse_args (args )
13637
13738
13839def main () -> None :
13940 args = parse_args (sys .argv [1 :])
14041
141- # Handle --list-modules
142- if args .list_modules :
143- modules = get_all_modules ()
144- print ("Available modules:\n " )
145- for module in modules :
146- print (f"- { module } " )
147- return
148-
14942 # Load configuration file
15043 try :
15144 config : Dict [str , Any ] = load_config ("config.yaml" )
@@ -154,49 +47,29 @@ def main() -> None:
15447
15548 # Configure logging
15649 try :
157- configure_logging (config ["logging" ])
50+ if args .show_states is True :
51+ configure_logging (
52+ {"level" : "ERROR" , "format" : {"renderer" : "console" , "time" : "iso" }}
53+ )
54+ else :
55+ configure_logging (config ["logging" ])
15856 except Exception as e :
15957 raise SystemExit (f"Error configuring logging: { e } " )
58+
16059 # Get Logger
16160 log = get_logger ()
16261
163- # Get Pickle File if configured in config.yaml
164- pickle_file_name = config ["general" ].get ("machine_pickle_file" )
165- if pickle_file_name is None :
166- log .info ("No pickle file was set in the configuration." )
167- else :
168- log .info (f"Pickle file set: { pickle_file_name } " )
62+ log .info ("Executing Rookify ..." )
16963
170- # Get Pickle File if configured in config.yaml
171- pickle_file_name = config ["general" ].get ("machine_pickle_file" )
172- if pickle_file_name is None :
173- log .info ("No pickle file was set in the configuration." )
174- else :
175- log .info (f"Pickle file set: { pickle_file_name } " )
176-
177- # If read_pickle is run and there is a picklefile, show the picklefiles contents.
178- # NOTE: preflight mode (--dry-run) has no effect here, because no module actions are required.
179- if args .read_pickle is not None and pickle_file_name is not None :
180- read_pickle_file (args , pickle_file_name , log )
181- return
182- elif args .read_pickle is not None and pickle_file_name is None :
183- log .info (
184- "No pickle file configured to read from. Check if the pickle file exists and is configured in config.yaml"
185- )
186- return
64+ machine = Machine (config ["general" ].get ("machine_pickle_file" ))
65+
66+ load_modules (machine , config )
18767
68+ if args .show_states is True :
69+ ModuleHandler .show_states (machine , config )
18870 else :
189- machine = Machine (config ["general" ].get ("machine_pickle_file" ))
190-
191- if args .show_progress is not None :
192- if show_progress_from_state (args , pickle_file_name , log ) is True :
193- load_modules (machine , config , show_progress = True )
194- # NOTE: this is always run in preflight-mode (migration should not be executed)
195- machine .execute (dry_run_mode = True )
196- return
197- else :
198- return
199- else :
200- load_modules (machine , config )
201- log .debug ("Executing Rookify" )
202- machine .execute (dry_run_mode = args .dry_run_mode )
71+ machine .execute (dry_run_mode = args .dry_run_mode )
72+
73+
74+ if __name__ == "__main__" :
75+ main ()
0 commit comments