Skip to content

Commit 35584e0

Browse files
Merge branch 'feature/ghi-#7-cli' into develop
2 parents 7bee974 + 3f34e72 commit 35584e0

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

‎snowsaw/cli.py‎

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
"""
2+
The snowsaw CLI.
3+
4+
This is the main entry point of the public API.
5+
"""
6+
from argparse import ArgumentParser
7+
import glob
8+
import os
9+
10+
from .config import ConfigReader, ReadingError
11+
from .dispatcher import Dispatcher, DispatchError
12+
from .logging import Level
13+
from .logging import Logger
14+
from .util import module
15+
16+
17+
def add_options(parser):
18+
"""
19+
Adds all options to the specified parser.
20+
21+
:param parser: The parser to add all options to
22+
:return: None
23+
"""
24+
parser.add_argument('-Q', '--super-quiet', dest='super_quiet', action='store_true', help='suppress almost all output')
25+
parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', help='suppress most output')
26+
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='enable verbose output')
27+
parser.add_argument('-s', '--snowblocks-directory', nargs=1, dest='snowblocks_directory',
28+
help='base snowblock directory to run all tasks of', metavar='SNOWBLOCKSDIR', required=True)
29+
parser.add_argument('-c', '--config-file', nargs=1, dest='config_file', help='run tasks for the specified snowblock', metavar='CONFIGFILE')
30+
parser.add_argument('-p', '--plugin', action='append', dest='plugins', default=[], help='load PLUGIN as a plugin', metavar='PLUGIN')
31+
parser.add_argument('--disable-core-plugins', dest='disable_core_plugins', action='store_true', help='disable all core plugins')
32+
parser.add_argument('--plugin-dir', action='append', dest='plugin_dirs', default=[], metavar='PLUGIN_DIR', help='load all plugins in PLUGIN_DIR')
33+
34+
35+
def read_config(config_file):
36+
"""
37+
Reads the specified configuration file.
38+
39+
:param config_file: The configuration file to read
40+
:return: The read configuration data
41+
"""
42+
reader = ConfigReader(config_file)
43+
return reader.get_config()
44+
45+
46+
def main():
47+
"""
48+
Processes all parsed options and hands it over to the dispatcher for each snowblock.
49+
50+
:return: True if all tasks have been executed successfully, False otherwise
51+
"""
52+
log = Logger()
53+
try:
54+
parser = ArgumentParser()
55+
snowblock_config_filename = "snowblock.json"
56+
add_options(parser)
57+
options = parser.parse_args()
58+
59+
if options.super_quiet:
60+
log.set_level(Level.WARNING)
61+
if options.quiet:
62+
log.set_level(Level.INFO)
63+
if options.verbose:
64+
log.set_level(Level.DEBUG)
65+
66+
plugin_directories = list(options.plugin_dirs)
67+
if not options.disable_core_plugins:
68+
plugin_directories.append(os.path.join(os.path.dirname(__file__), "plugins"))
69+
plugin_paths = []
70+
for directory in plugin_directories:
71+
for plugin_path in glob.glob(os.path.join(directory, "*.py")):
72+
plugin_paths.append(plugin_path)
73+
for plugin_path in options.plugins:
74+
plugin_paths.append(plugin_path)
75+
for plugin_path in plugin_paths:
76+
abspath = os.path.abspath(plugin_path)
77+
module.load(abspath)
78+
79+
if options.config_file:
80+
snowblocks = [os.path.basename(os.path.dirname(options.config_file[0]))]
81+
else:
82+
snowblocks = [snowblock for snowblock in os.listdir(options.snowblocks_directory[0])
83+
if os.path.isdir(os.path.join(options.snowblocks_directory[0], snowblock))]
84+
85+
for snowblock in snowblocks:
86+
if os.path.isfile(os.path.join(snowblock, snowblock_config_filename)):
87+
log.info("❄ {}".format(snowblock))
88+
tasks = read_config(os.path.join(snowblock, snowblock_config_filename))
89+
90+
if not isinstance(tasks, list):
91+
raise ReadingError("Configuration file must be a list of tasks")
92+
93+
dispatcher = Dispatcher(snowblock)
94+
success = dispatcher.dispatch(tasks)
95+
if success:
96+
log.info("==> All tasks executed successfully\n")
97+
else:
98+
raise DispatchError("\n==> Some tasks were not executed successfully")
99+
else:
100+
log.lowinfo("Skipped snowblock \"{}\": No configuration file found".format(snowblock))
101+
except (ReadingError, DispatchError) as e:
102+
log.error("{}".format(e))
103+
exit(1)
104+
except KeyboardInterrupt:
105+
log.error("\n==> Operation aborted")
106+
exit(1)

0 commit comments

Comments
 (0)