Add 'create' directive to create directories
[dotbot.git] / dotbot / cli.py
blob2680acf17a68fcf19991d76e72dc8ec3bc1dd714
1 import os, glob
3 from argparse import ArgumentParser
4 from .config import ConfigReader, ReadingError
5 from .dispatcher import Dispatcher, DispatchError
6 from .messenger import Messenger
7 from .messenger import Level
8 from .util import module
10 import dotbot
11 import yaml
13 def add_options(parser):
14 parser.add_argument('-Q', '--super-quiet', action='store_true',
15 help='suppress almost all output')
16 parser.add_argument('-q', '--quiet', action='store_true',
17 help='suppress most output')
18 parser.add_argument('-v', '--verbose', action='store_true',
19 help='enable verbose output')
20 parser.add_argument('-d', '--base-directory',
21 help='execute commands from within BASEDIR',
22 metavar='BASEDIR')
23 parser.add_argument('-c', '--config-file',
24 help='run commands given in CONFIGFILE', metavar='CONFIGFILE')
25 parser.add_argument('-p', '--plugin', action='append', dest='plugins', default=[],
26 help='load PLUGIN as a plugin', metavar='PLUGIN')
27 parser.add_argument('--disable-built-in-plugins',
28 action='store_true', help='disable built-in plugins')
29 parser.add_argument('--plugin-dir', action='append', dest='plugin_dirs', default=[],
30 metavar='PLUGIN_DIR', help='load all plugins in PLUGIN_DIR')
31 parser.add_argument('--no-color', dest='no_color', action='store_true',
32 help='disable color output')
33 parser.add_argument('--version', action='store_true',
34 help='show program\'s version number and exit')
36 def read_config(config_file):
37 reader = ConfigReader(config_file)
38 return reader.get_config()
40 def main():
41 log = Messenger()
42 try:
43 parser = ArgumentParser()
44 add_options(parser)
45 options = parser.parse_args()
46 if options.version:
47 print('Dotbot version %s (yaml: %s)' % (dotbot.__version__, yaml.__version__))
48 exit(0)
49 if options.super_quiet:
50 log.set_level(Level.WARNING)
51 if options.quiet:
52 log.set_level(Level.INFO)
53 if options.verbose:
54 log.set_level(Level.DEBUG)
55 if options.no_color:
56 log.use_color(False)
57 plugin_directories = list(options.plugin_dirs)
58 if not options.disable_built_in_plugins:
59 from .plugins import Clean, Create, Link, Shell
60 plugin_paths = []
61 for directory in plugin_directories:
62 for plugin_path in glob.glob(os.path.join(directory, '*.py')):
63 plugin_paths.append(plugin_path)
64 for plugin_path in options.plugins:
65 plugin_paths.append(plugin_path)
66 for plugin_path in plugin_paths:
67 abspath = os.path.abspath(plugin_path)
68 module.load(abspath)
69 if not options.config_file:
70 log.error('No configuration file specified')
71 exit(1)
72 tasks = read_config(options.config_file)
73 if not isinstance(tasks, list):
74 raise ReadingError('Configuration file must be a list of tasks')
75 if options.base_directory:
76 base_directory = options.base_directory
77 else:
78 # default to directory of config file
79 base_directory = os.path.dirname(os.path.realpath(options.config_file))
80 os.chdir(base_directory)
81 dispatcher = Dispatcher(base_directory)
82 success = dispatcher.dispatch(tasks)
83 if success:
84 log.info('\n==> All tasks executed successfully')
85 else:
86 raise DispatchError('\n==> Some tasks were not executed successfully')
87 except (ReadingError, DispatchError) as e:
88 log.error('%s' % e)
89 exit(1)
90 except KeyboardInterrupt:
91 log.error('\n==> Operation aborted')
92 exit(1)