Esempio n. 1
0
def ergo2bash(string):
    tokens = tokenize(string)
    command = tokens[0][0]
    args = " ".join(tokens[0][1:])
    switches = tokens[1]
    bash_switches = ""
    for item in switches:
        name, val = item.split(":", 1)
        if val in ["t", "true"]:
            bash_switches += " -%s " % name
        else:
            bash_switches += " -%s %s" % (name, val)
    return "%s %s %s" % (command, args, bash_switches)
Esempio n. 2
0
def get_error_message(BLOCK):
    """Print an error message for a block."""
    tokenized_block = tokenize(BLOCK)
    operator = get_operator(BLOCK)
    if get_operator(BLOCK) and get_operator(BLOCK) not in operators:
        return "[ergo: OperatorError]: No such operator '%s'." % get_operator(
            BLOCK)
    elif (tokenized_block[0][0] not in verbs) and not operator:
        bad_command = tokenized_block[0][0]
        correction = difflib.get_close_matches(bad_command, verbs.keys(), 1,
                                               0.55)
        s = "[ergo: CommandError]: No such command '%s'." % bad_command
        try:
            return s + "\n" + " " * 22 + "Did you mean %s?" % (correction[0])
        except IndexError:
            return s
    # when this command is called, this means that its passed through all operators
    else:
        return False
    return True
Esempio n. 3
0
def ergo(stdin, depth=0):
    """Main ergonomica runtime."""

    global debug
    debug = []

    stdout = []

    ENV.ergo = ergo

    pipe = StaticPipeline()

    # macros
    for item in ENV.macros:
        stdin = stdin.replace(item, ENV.macros[item])

    num_blocks = len(stdin.split("->"))
    blocks = stdin.split("->")
    tokenized_blocks = [tokenize(block) for block in stdin.split("->")]

    debug.append("BLOCKS: " + str(blocks))
    debug.append("TOKENIZED_BLOCKS: " + str(tokenized_blocks))

    for i in range(0, len(blocks)):
        try:
            if i == 1:
                debug.append("1st iteration.")
            else:
                debug.append("%sth iteration." % (i))

            debug.append("Cleaning pipe...")

            # clean pipe
            pipe.prune()

            debug.append("Current pipe contents:")
            debug.append("pipe.args: " + str(pipe.args))
            debug.append("pipe.kwargs: " + str(pipe.kwargs))

            # update loop variables
            num_blocks -= 1

            # macros
            for item in ENV.macros:
                blocks[i] = blocks[i].replace(item, ENV.macros[item])

            # evaluate $(exp) & replace
            matches = re.findall(r"\$\((.*)\)", blocks[i])
            for match in matches:
                try:
                    blocks[i] = blocks[i].replace("$(%s)" % (match),
                                                  " ".join(ergo(match)))
                except TypeError:
                    blocks[i] = blocks[i].replace("$(%s)" % (match),
                                                  str(ergo(match)))

            # regenerate tokenized blocks
            tokenized_blocks[i] = tokenize(blocks[i])

            # more parse info
            statement = get_statement(blocks[i])
            evaluated_operator = run_operator(blocks[i], pipe)

            if blocks[i].strip() == "":
                debug.append("Empty command. Skipping.")

            elif evaluated_operator is not False:
                debug.append("Operator %s evaluated." %
                             (get_operator(blocks[i])))
                stdout = evaluated_operator

            elif statement == "run":
                lines = [
                    open(_file, "r").read().split("\n")
                    for _file in tokenized_blocks[i][0][1:]
                ]
                flattened_lines = [
                    item for sublist in lines for item in sublist
                ]
                stdout = map(ergo, flattened_lines)

            elif statement == "if":
                res = " ".join(tokenize(stdin.split(":", 1)[0])[0][1:])
                debug.append("STATEMENT-IF: conditional=%s command=%s" %
                             (res.strip(), stdin.split(":", 1)[1].strip()))
                if ergo(res.strip()):
                    stdout = ergo(stdin.split(":", 1)[1].strip())
                else:
                    continue

            elif statement == "while":
                res = " ".join(tokenize(stdin.split(":", 1)[0])[0][1:])
                while ergo(res.strip()):
                    stdout = ergo(stdin.split(":", 1)[1].strip())

            elif statement == "for":
                res = " ".join(tokenize(stdin.split(":")[0])[0][1:])
                stdout = []
                for item in ergo(res.strip()):
                    out = stdin.split(":", 1)[1]
                    out = out.replace(str(depth) + "{}", item)
                    stdout += ergo(out.strip(), depth + 1)

            else:
                if blocks[i] in ENV.aliases:
                    stdout = ergo(ENV.aliases[blocks[i]])
                else:
                    try:
                        func = get_func(tokenized_blocks[i], verbs)
                        args, kwargs = get_args_kwargs(tokenized_blocks[i],
                                                       pipe)
                        stdout = func(ENV, args, kwargs)
                    except KeyError as error:  #not in ergonomica path
                        if not str(handle_runtime_error(
                                blocks[i],
                                error)).startswith("[ergo: CommandError]"):
                            raise error
                        try:
                            stdout = run_bash(ENV, ergo2bash(blocks[i]), pipe)
                        except OSError:
                            raise error

            # filter out none values
            try:
                if isinstance(stdout, list):
                    stdout = [x for x in stdout if x != None]
            except TypeError:
                stdout = []

        except Exception:
            _, error, _ = sys.exc_info()
            stdout = [handle_runtime_error(blocks[i], error)]

        handled_stdout = handle_stdout(stdout, pipe, num_blocks)
        if handled_stdout is not None:
            return handled_stdout