def usage(self): usage = styled('{bright}{} {}', self.parent.prog, self.name) for argument in self.arguments: usage += styled(' {fg.blue}<{}>', argument.dest) if self.options: usage += styled(' {fg.yellow}[options]') usage += styled('{reset}') return usage
def _format_action(self, action): help = super(Contextual, self)._format_action(action) sep = ' ' * self._indent_increment parts = help.split(sep) left = styled('{bright}{}{reset}', sep.join(parts[:-1])) right = parts[-1] return sep.join([left, right])
def format_status(self, status): return styled( self.template, icon=ICONS[self.status], identifier=self.task.identifier + style.reset, description=self.task.description, sep=' - ' )
def on_action_before(ctx): print() print(ctx.action.description + '\n') if ctx.kwargs or ctx.args: args_data = [(k, v) for k, v in ctx.kwargs.items()] if ctx.args: args_data.append(('extra_args', ctx.args)) args_section = format_section( styled('{bright}{fg.yellow}Options{reset}'), data=args_data, lcolor=style.bright ) print(args_section + '\n') ctx_keys = ['action'] + ctx.keys ctx_data = [] for k in ctx_keys: v = ctx[k] if not v: continue if k in ctx.entry_keys: ctx_data.append((k, v.name)) else: ctx_data.append((k, v)) ctx_section = format_section( ACTION_CONTEXT_TITLE, data=ctx_data, lcolor=style.bright ) print(ctx_section + '\n') print('Status Key') key_tmpl = ' {} {:<8}' for status, icon in list(ICONS.items())[:5]: print(key_tmpl.format(icon, status), end='') print() for status, icon in list(ICONS.items())[5:]: print(key_tmpl.format(icon, status), end='') print('\n') console = stout.Console() console.init() stout.set_console(console) for group, tasks in ctx.task_groups.items(): print(group.description) for task in tasks: w = TaskLine(task, console) CONSOLE_WIDGETS[task.identifier] = w console.add_widget(w) print() progress = ProgressBar('Tasks', len(ctx.tasks), console) CONSOLE_WIDGETS['progress'] = progress console.add_widget(progress)
def run(self, args, *extra_args): try: action = self.action(*extra_args, **args.__dict__) action.run() except ActionControlFlowError as e: msg = styled( '{bright}{fg.red}Control Flow Error:{fg.reset} {}' ' raised critical error {fg.red}{}{reset}', self.action.identifier, e.__class__.__name__) print(msg) except ArgumentError as e: msg = styled('{bright}{fg.red}Argument Error:{fg.reset} {}', e) print(msg) except Exception as e: msg = styled( '{bright}{fg.red}Action Error:{fg.reset} {}' ' raised unexpected error {fg.red}{}{reset}\n', self.action.identifier, e.__class__.__name__) print(msg) traceback.print_exc()
def run(self, args, *extra_args): section = format_section('', [ ('', ''), ('name', construct.__title__), ('version', construct.__version__), ('url', construct.__url__), ('package', os.path.dirname(construct.__file__)), ('config', os.environ.get('CONSTRUCT_CONFIG', 'default')), ], lcolor=styled('{bright}')) print(section)
def format_context(): ctx = construct.get_context() ctx_data = [] for k in ctx.keys: v = ctx[k] if not v: continue if k in ctx.entry_keys: ctx_data.append((k, v.name)) else: ctx_data.append((k, v)) return format_section(CONTEXT_TITLE, ctx_data, lcolor=styled('{bright}'))
def format_section(title, data, indent='', lcolor=reset, rcolor=reset): '''Format a section''' if isinstance(data, dict): data = list(data.items()) width = max(max([len(k) for k, v in data]), 12) line = indent + ' {lc}{:<{w}}{reset} {rc}{}{reset}' lines = [] if title: lines.append(indent + title) for key, value in data: lines.append(styled(line, key, value, w=width, lc=lcolor, rc=rcolor)) return '\n'.join(lines)
def run(self, args, *extra_args): import fsfs ctx = construct.get_context() if not args.tags and args.name: query = dict(selector=args.name, root=args.root, skip_root=True) entry = construct.quick_select(**query) else: query = dict(root=args.root, name=args.name, tags=args.tags, direction=args.direction, depth=args.depth or (3 if ctx.project else 2), skip_root=True) # Get a better match, not just the first hit entries = list(construct.search(**query)) if not entries: error('Could not find entry...') sys.exit(1) if len(entries) == 1: entry = entries[0] else: # The shortest entry has to be the closest to our query entry = min(entries, key=lambda e: len(e.path)) if not entry: error('Could not find entry...') sys.exit(1) path = entry.path if args.name: parts = args.name.split('/') for part in parts: highlight = styled('{bright}{fg.yellow}{}{reset}', part) path = path.replace(part, highlight) print(path) scrim = get_scrim() scrim.pushd(os.path.abspath(entry.path))
def format_bar(self): info = self.info_template.format( label=self.label, i=self.i, max=self.max ) info_width = len(info) bar_width = self.width - info_width if self.i == 0: percent = 0 else: percent = self.i / self.max lfill_width = int(bar_width * percent) rfill_width = bar_width - lfill_width return styled( info + self.bar_template, color=self.get_color(percent), lfill=self.lfill_char * lfill_width, rfill=self.rfill_char * rfill_width )
def run(self, args, *extra_args): ctx = construct.get_context() query = dict( root=args.root, name=args.name, tags=args.tags, direction=args.direction, depth=args.depth or (3 if ctx.project else 1), ) entries = construct.search(**query) i = 0 for i, entry in enumerate(entries): path = entry.path if args.name: parts = args.name.split('/') for part in parts: highlight = styled('{bright}{fg.yellow}{}{reset}', part) path = path.replace(part, highlight) print(path) if i == 0: print(('Found 0 result.'))
def setup_parser(): '''Build the root parser''' usage = styled( '{bright}construct ' '{fg.blue}<command|action>{fg.reset} ' '{fg.yellow}[options]{reset}' ) parser = argparse.ArgumentParser( 'construct', usage=usage, formatter_class=Root, add_help=False, ) parser._optionals.title = OPTIONS_TITLE parser.add_argument( '-h', '--help', help='show this help message and exit', action='store_true', dest='-h' ) parser.add_argument( '-v', '--verbose', help='verbose output', action='store_true', dest='-v' ) parser.add_argument( 'command', help=argparse.SUPPRESS, action='store', nargs='?' ) return parser
def format_error(self, exc_info): # Insert error message exc_type, exc_value, exc_tb = exc_info err = styled(self.error_template, exc_type.__name__, exc_value) return err
from platform import platform from construct.cli.utils import styled from collections import OrderedDict from construct.constants import ( WAITING, PENDING, RUNNING, SUCCESS, FAILED, SKIPPED, PAUSED, DISABLED, ENABLED, ) ACTION_CONTEXT_TITLE = styled('{normal}Action Context{reset}') ACTIONS_TITLE = styled('{bright}{fg.blue}Actions{reset}') ARGUMENTS_TITLE = styled('{bright}{fg.blue}Arguments{reset}') ARTIFACTS_TITLE = styled('{bright}{fg.green}Artifacts{reset}') COMMANDS_TITLE = styled('{bright}{fg.blue}Commands{reset}') CONTEXT_TITLE = styled('{normal}Current Context{reset}') OPTIONS_TITLE = styled('{bright}{fg.yellow}Options{reset}') STATUS_LABELS = { WAITING: styled('{dim}WAITING{reset}'), PENDING: styled('{dim}PENDING{reset}'), RUNNING: styled('{fg.green}RUNNING{reset}'), SUCCESS: styled('{bright}{fg.green}SUCCESS{reset}'), FAILED: styled('{bright}{fg.red}FAILED{reset}'), SKIPPED: styled('{fg.cyan}SKIPPED{reset}'), PAUSED: styled('{fg.red}PAUSED{reset}'),
def format_actions(): actions = construct.actions.collect() return format_section(ACTIONS_TITLE, [(a.identifier, a.description) for a in construct.actions], lcolor=styled('{bright}'))
def format_commands(): from construct.cli.commands import commands return format_section(COMMANDS_TITLE, [(c.name, c.short_description) for c in commands], lcolor=styled('{bright}'))