Ejemplo n.º 1
0
def cli(prefix: str, path: PurePath, spec: Path, flags: List[str], logger: UI,
        description: str, transaction: Transaction, *args, **kwargs):
    # spec: Path
    with spec.open() as f:
        obj = json.load(f, object_pairs_hook=lambda pairs: pairs)
    try:
        try:
            array = [SpecObj(**dict(obj))]
        except TypeError:
            array = [SpecObj(**dict(o)) for o in obj]
    except TypeError:
        logger.exit(f'Each object in {spec} must have a '
                    f'"command" field and a "flags" field.')

    for i, obj in enumerate(array):
        new_path = path if len(array) == 1 else PurePath(path, str(i))

        def parse_flag(flag: Flag):
            values = flag.values if isinstance(flag.values,
                                               list) else [flag.values]
            null_keys = ['null', '', 'none', 'None']
            return [
                f'--{v}' if flag.key in null_keys else f'--{flag.key}="{v}"'
                for v in values
            ]

        flags = [[f] for f in flags]
        flags += list(map(parse_flag, obj.flags))
        new(path=new_path,
            prefix=prefix,
            command=obj.command,
            description=description,
            flags=flags,
            transaction=transaction)
Ejemplo n.º 2
0
def cli(prefix: str, paths: List[PurePath], commands: List[str],
        args: List[str], logger: UI, descriptions: List[str],
        transaction: Transaction, *_, **__):
    n = len(commands)
    if not len(paths) in [1, n]:
        logger.exit("There must either be 1 or n paths "
                    "where n is the number of subcommands.")

    if not (descriptions is None or len(descriptions) in [0, 1, n]):
        logger.exit("There must either be 1 or n descriptions "
                    "where n is the number of subcommands.")
    descriptions = descriptions or []
    iterator = enumerate(itertools.zip_longest(paths, commands, descriptions))
    for i, (path, command, description) in iterator:
        if path is None:
            if n == 1:
                path = PurePath(paths[0])
            else:
                path = PurePath(paths[0], str(i))
        if description is None:
            if descriptions:
                description = descriptions[0]

        new(
            command=Command(prefix, command, *args, path=path),
            description=description,
            path=path,
            transaction=transaction,
        )
Ejemplo n.º 3
0
def cli(prefix: str, paths: List[PurePath], commands: List[str],
        flags: List[str], logger: UI, descriptions: List[str],
        transaction: Transaction, *args, **kwargs):
    flags = list(map(parse_flag, flags))
    n = len(commands)
    if not len(paths) in [1, n]:
        logger.exit('There must either be 1 or n paths '
                    'where n is the number of commands.')

    if not len(descriptions) in [0, 1, n]:
        logger.exit('There must either be 1 or n descriptions '
                    'where n is the number of commands.')

    iterator = enumerate(itertools.zip_longest(paths, commands, descriptions))
    for i, (path, command, description) in iterator:
        if path is None:
            if n == 1:
                path = PurePath(paths[0])
            else:
                path = PurePath(paths[0], str(i))
        if len(descriptions) == 0:
            description = 'Description not given.'
        if len(descriptions) == 1:
            description = descriptions[0]

        new(path=path,
            prefix=prefix,
            command=command,
            description=description,
            flags=flags,
            transaction=transaction)
Ejemplo n.º 4
0
def cli(prefix: str, paths: List[PurePath], commands: List[str], flags: List[str],
        logger: UI, descriptions: List[str], transaction: Transaction, *args, **kwargs):
    paths = [p for p in paths if p]
    commands = [c for c in commands if c]
    if len(paths) == 0:
        logger.exit('Must provide at least one path.')
    if len(commands) == 0:
        logger.exit('Must provide at least one command.')
    if descriptions is None:
        descriptions = [''] * len(commands)
    elif len(descriptions) == 1:
        descriptions *= len(paths)
        if not len(paths) == len(commands):
            logger.exit('Number of paths must be the same as the number of commands')
    elif not len(paths) == len(commands) == len(descriptions):
        logger.exit(
            f'Got {len(paths)} paths, {len(commands)} commands, and {len(descriptions)} descriptions.'
            f'These numbers should all be the same so that they can be collated.')
    runs = defaultdict(list)
    for path, command, description in zip(paths, commands, descriptions):
        for parsed_flags in generate_runs(flags):
            runs[path].append((command, parsed_flags, description))

    for path in runs:
        for i, (command, flags, description) in enumerate(runs[path]):
            new_path = path
            if len(runs[path]) > 1:
                new_path = PurePath(path, str(i))
            new(path=new_path,
                prefix=prefix,
                command=command,
                description=description,
                flags=flags,
                transaction=transaction)
Ejemplo n.º 5
0
def cli(
    prefix: str,
    path: PurePath,
    spec: Path,
    args: List[str],
    logger: UI,
    description: str,
    transaction: Transaction,
    max_runs: int,
    *_,
    **__,
):
    # spec: Path
    if not spec.exists():
        logger.exit(f"{spec.absolute()} does not exist.")
    with spec.open() as f:
        obj = json.load(f, object_pairs_hook=lambda pairs: pairs)
    try:
        try:
            spec_objs = [SpecObj(**dict(obj))]
        except ValueError:
            spec_objs = [SpecObj(**dict(o)) for o in obj]
    except TypeError:
        logger.exit(f"Each object in {spec} must have a "
                    '"command" field and a "args" field.')

    def listify(x):
        if isinstance(x, list):
            return x
        return [x]

    def prepend(arg: str):
        if not arg or arg.startswith("-"):
            return arg
        return f"--{arg}"

    def arg_alternatives(key, values):
        for v in listify(values):
            if isinstance(v, list):
                value = " ".join([f'"{_v}"' for _v in v])
                yield [prepend(f"{key} {value}")]
            else:
                yield [prepend(f'{key}="{value}"') for value in listify(v)]

    def flag_alternatives(values):
        if values:
            for v in values:
                yield list(map(prepend, v))
        else:
            yield [None]

    def group_args(spec):
        for k, v in spec.args or []:
            yield list(arg_alternatives(k, v))
        yield list(flag_alternatives(spec.flags))

    def arg_assignments():
        for spec in spec_objs:
            for arg_set in itertools.product(*group_args(spec)):
                yield spec.command, [a for s in arg_set for a in s if a]

    assignments = list(arg_assignments())
    if max_runs is not None and len(assignments) > max_runs:
        random.shuffle(assignments)
        assignments = assignments[:max_runs]
    for i, (command, arg_set) in enumerate(assignments):
        new_path = path if len(assignments) == 1 else PurePath(path, str(i))
        command = Command(prefix, command, *arg_set, *args, path=new_path)
        new(
            path=new_path,
            command=command,
            description=description,
            transaction=transaction,
        )