Skip to content

Commit 0ecd90c

Browse files
committed
cleanup
1 parent 0172bad commit 0ecd90c

File tree

2 files changed

+331
-286
lines changed

2 files changed

+331
-286
lines changed

nodescraper/cli/cli.py

Lines changed: 9 additions & 286 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
###############################################################################
2626
import argparse
2727
import datetime
28-
import json
2928
import logging
3029
import os
3130
import platform
@@ -35,15 +34,21 @@
3534

3635
from nodescraper.cli.constants import DEFAULT_CONFIG, META_VAR_MAP
3736
from nodescraper.cli.dynamicparserbuilder import DynamicParserBuilder
37+
from nodescraper.cli.helper import (
38+
generate_reference_config,
39+
get_plugin_configs,
40+
get_system_info,
41+
log_system_info,
42+
parse_describe,
43+
parse_gen_plugin_config,
44+
)
3845
from nodescraper.cli.inputargtypes import ModelArgHandler, json_arg, log_path_arg
39-
from nodescraper.configbuilder import ConfigBuilder
4046
from nodescraper.configregistry import ConfigRegistry
4147
from nodescraper.constants import DEFAULT_LOGGER
4248
from nodescraper.enums import ExecutionStatus, SystemInteractionLevel, SystemLocation
43-
from nodescraper.models import PluginConfig, SystemInfo
49+
from nodescraper.models import SystemInfo
4450
from nodescraper.pluginexecutor import PluginExecutor
4551
from nodescraper.pluginregistry import PluginRegistry
46-
from nodescraper.resultcollators.tablesummary import TableSummary
4752

4853

4954
def build_parser(
@@ -257,111 +262,6 @@ def setup_logger(log_level: str = "INFO", log_path: str | None = None) -> loggin
257262
return logger
258263

259264

260-
def get_system_info(args: argparse.Namespace) -> SystemInfo:
261-
"""build system info object using args
262-
263-
Args:
264-
args (argparse.Namespace): parsed args
265-
266-
Raises:
267-
argparse.ArgumentTypeError: if system location arg is invalid
268-
269-
Returns:
270-
SystemInfo: system info instance
271-
"""
272-
273-
if args.system_config:
274-
system_info = args.system_config
275-
else:
276-
system_info = SystemInfo()
277-
278-
if args.sys_name:
279-
system_info.name = args.sys_name
280-
281-
if args.sys_sku:
282-
system_info.sku = args.sys_sku
283-
284-
if args.sys_platform:
285-
system_info.platform = args.sys_platform
286-
287-
if args.sys_location:
288-
try:
289-
location = getattr(SystemLocation, args.sys_location)
290-
except Exception as e:
291-
raise argparse.ArgumentTypeError("Invalid input for system location") from e
292-
293-
system_info.location = location
294-
295-
return system_info
296-
297-
298-
def get_plugin_configs(
299-
plugin_config_input: list[str],
300-
system_interaction_level: SystemInteractionLevel,
301-
built_in_configs: dict[str, PluginConfig],
302-
parsed_plugin_args: dict[str, argparse.Namespace],
303-
plugin_subparser_map: dict[str, tuple[argparse.ArgumentParser, dict]],
304-
) -> list[PluginConfig]:
305-
"""Build list of plugin configs based on input args
306-
307-
Args:
308-
plugin_config_input (list[str]): list of plugin config inputs, can be paths to JSON files or built-in config names
309-
system_interaction_level (SystemInteractionLevel): system interaction level, used to determine the type of actions that plugins can perform
310-
built_in_configs (dict[str, PluginConfig]): built-in plugin configs, mapping from config name to PluginConfig instance
311-
parsed_plugin_args (dict[str, argparse.Namespace]): parsed plugin arguments, mapping from plugin name to parsed args
312-
plugin_subparser_map (dict[str, tuple[argparse.ArgumentParser, dict]]): plugin subparser map, mapping from plugin name to tuple of parser and model type map
313-
314-
Raises:
315-
argparse.ArgumentTypeError: if system interaction level is invalid
316-
argparse.ArgumentTypeError: if no plugin config found for a given input
317-
318-
Returns:
319-
list[PluginConfig]: list of PluginConfig instances based on input args
320-
"""
321-
try:
322-
system_interaction_level = getattr(SystemInteractionLevel, system_interaction_level)
323-
except Exception as e:
324-
raise argparse.ArgumentTypeError("Invalid input for system interaction level") from e
325-
326-
base_config = PluginConfig(result_collators={str(TableSummary.__name__): {}})
327-
328-
base_config.global_args["system_interaction_level"] = system_interaction_level
329-
330-
plugin_configs = [base_config]
331-
332-
if plugin_config_input:
333-
for config in plugin_config_input:
334-
if os.path.exists(config):
335-
plugin_configs.append(ModelArgHandler(PluginConfig).process_file_arg(config))
336-
elif config in built_in_configs:
337-
plugin_configs.append(built_in_configs[config])
338-
else:
339-
raise argparse.ArgumentTypeError(f"No plugin config found for: {config}")
340-
341-
if parsed_plugin_args:
342-
plugin_input_config = PluginConfig()
343-
344-
for plugin, plugin_args in parsed_plugin_args.items():
345-
config = {}
346-
model_type_map = plugin_subparser_map[plugin][1]
347-
for arg, val in vars(plugin_args).items():
348-
if val is None:
349-
continue
350-
if arg in model_type_map:
351-
model = model_type_map[arg]
352-
if model in config:
353-
config[model][arg] = val
354-
else:
355-
config[model] = {arg: val}
356-
else:
357-
config[arg] = val
358-
plugin_input_config.plugins[plugin] = config
359-
360-
plugin_configs.append(plugin_input_config)
361-
362-
return plugin_configs
363-
364-
365265
def process_args(
366266
raw_arg_input: list[str], plugin_names: list[str]
367267
) -> tuple[list[str], dict[str, list[str]]]:
@@ -401,183 +301,6 @@ def process_args(
401301
return (top_level_args, plugin_arg_map)
402302

403303

404-
def build_config(
405-
config_reg: ConfigRegistry,
406-
plugin_reg: PluginRegistry,
407-
logger: logging.Logger,
408-
plugins: Optional[list[str]] = None,
409-
built_in_configs: Optional[list[str]] = None,
410-
) -> PluginConfig:
411-
"""build a plugin config
412-
413-
Args:
414-
config_reg (ConfigRegistry): config registry instance
415-
plugin_reg (PluginRegistry): plugin registry instance
416-
logger (logging.Logger): logger instance
417-
plugins (Optional[list[str]], optional): list of plugin names to include. Defaults to None.
418-
built_in_configs (Optional[list[str]], optional): list of built in config names to include. Defaults to None.
419-
420-
Returns:
421-
PluginConfig: plugin config obf
422-
"""
423-
configs = []
424-
if plugins:
425-
logger.info("Building config for plugins: %s", plugins)
426-
config_builder = ConfigBuilder(plugin_registry=plugin_reg)
427-
configs.append(config_builder.gen_config(plugins))
428-
429-
if built_in_configs:
430-
logger.info("Retrieving built in configs: %s", built_in_configs)
431-
for config in built_in_configs:
432-
if config not in config_reg.configs:
433-
logger.warning("No built in config found for name: %s", config)
434-
else:
435-
configs.append(config_reg.configs[config])
436-
437-
config = PluginExecutor.merge_configs(configs)
438-
return config
439-
440-
441-
def parse_describe(
442-
parsed_args: argparse.Namespace,
443-
plugin_reg: PluginRegistry,
444-
config_reg: ConfigRegistry,
445-
logger: logging.Logger,
446-
):
447-
"""parse 'describe' cmd line argument
448-
449-
Args:
450-
parsed_args (argparse.Namespace): parsed cmd line arguments
451-
plugin_reg (PluginRegistry): plugin registry instance
452-
config_reg (ConfigRegistry): config registry instance
453-
logger (logging.Logger): logger instance
454-
"""
455-
if not parsed_args.name:
456-
if parsed_args.type == "config":
457-
print("Available built-in configs:") # noqa: T201
458-
for name in config_reg.configs:
459-
print(f" {name}") # noqa: T201
460-
elif parsed_args.type == "plugin":
461-
print("Available plugins:") # noqa: T201
462-
for name in plugin_reg.plugins:
463-
print(f" {name}") # noqa: T201
464-
print(f"\nUsage: describe {parsed_args.type} <name>") # noqa: T201
465-
sys.exit(0)
466-
467-
if parsed_args.type == "config":
468-
if parsed_args.name not in config_reg.configs:
469-
logger.error("No config found for name: %s", parsed_args.name)
470-
sys.exit(1)
471-
config_model = config_reg.configs[parsed_args.name]
472-
print(f"Config Name: {parsed_args.name}") # noqa: T201
473-
print(f"Description: {getattr(config_model, 'desc', '')}") # noqa: T201
474-
print("Plugins:") # noqa: T201
475-
for plugin in getattr(config_model, "plugins", []):
476-
print(f"\t{plugin}") # noqa: T201
477-
478-
elif parsed_args.type == "plugin":
479-
if parsed_args.name not in plugin_reg.plugins:
480-
logger.error("No plugin found for name: %s", parsed_args.name)
481-
sys.exit(1)
482-
plugin_class = plugin_reg.plugins[parsed_args.name]
483-
print(f"Plugin Name: {parsed_args.name}") # noqa: T201
484-
print(f"Description: {getattr(plugin_class, '__doc__', '')}") # noqa: T201
485-
486-
sys.exit(0)
487-
488-
489-
def parse_gen_plugin_config(
490-
parsed_args: argparse.Namespace,
491-
plugin_reg: PluginRegistry,
492-
config_reg: ConfigRegistry,
493-
logger: logging.Logger,
494-
):
495-
"""parse 'gen_plugin_config' cmd line argument
496-
497-
Args:
498-
parsed_args (argparse.Namespace): parsed cmd line arguments
499-
plugin_reg (PluginRegistry): plugin registry instance
500-
config_reg (ConfigRegistry): config registry instance
501-
logger (logging.Logger): logger instance
502-
"""
503-
try:
504-
config = build_config(
505-
config_reg, plugin_reg, logger, parsed_args.plugins, parsed_args.built_in_configs
506-
)
507-
508-
config.name = parsed_args.config_name.split(".")[0]
509-
config.desc = "Auto generated config"
510-
output_path = os.path.join(parsed_args.output_path, parsed_args.config_name)
511-
with open(output_path, "w", encoding="utf-8") as out_file:
512-
out_file.write(config.model_dump_json(indent=2))
513-
514-
logger.info("Config saved to: %s", output_path)
515-
sys.exit(0)
516-
except Exception:
517-
logger.exception("Exception when building config")
518-
sys.exit(1)
519-
520-
521-
def log_system_info(log_path: str | None, system_info: SystemInfo, logger: logging.Logger):
522-
"""dump system info object to json log
523-
524-
Args:
525-
log_path (str): path to log folder
526-
system_info (SystemInfo): system object instance
527-
"""
528-
if log_path:
529-
try:
530-
with open(
531-
os.path.join(log_path, "system_info.json"), "w", encoding="utf-8"
532-
) as log_file:
533-
json.dump(
534-
system_info.model_dump(mode="json", exclude_none=True),
535-
log_file,
536-
indent=2,
537-
)
538-
except Exception as exp:
539-
logger.error(exp)
540-
541-
542-
def generate_reference_config(results, plugin_reg, logger, path):
543-
plugin_config = PluginConfig()
544-
plugins = {}
545-
for obj in results:
546-
data_model = obj.result_data.system_data
547-
548-
plugin = plugin_reg.plugins.get(obj.result_data.collection_result.parent)
549-
if not plugin.ANALYZER_ARGS:
550-
logger.warning(
551-
"Plugin: %s does not support reference config creation. No analyzer args defined.",
552-
obj.source,
553-
)
554-
continue
555-
556-
args = None
557-
try:
558-
args = plugin.ANALYZER_ARGS.build_from_model(data_model)
559-
except NotImplementedError as nperr:
560-
logger.info(nperr)
561-
continue
562-
args.build_from_model(data_model)
563-
plugins[obj.source] = {"analysis_args": {}}
564-
plugins[obj.source]["analysis_args"] = args.model_dump(exclude_none=True)
565-
plugin_config.plugins = plugins
566-
567-
if not path:
568-
path = os.path.join(os.getcwd(), "reference_config.json")
569-
try:
570-
with open(path, "w") as f:
571-
json.dump(
572-
plugin_config.model_dump(mode="json", exclude_none=True),
573-
f,
574-
indent=2,
575-
)
576-
logger.info("Reference config written to: %s", path)
577-
except Exception as exp:
578-
logger.error(exp)
579-
580-
581304
def main(arg_input: Optional[list[str]] = None):
582305
"""Main entry point for the CLI
583306

0 commit comments

Comments
 (0)