def test_ergo2bash(self): """ "ergo2bash not working properly for arguments" @lschumm https://github.com/ergonomica/ergonomica/issues/26 """ self.assertEqual( ergo2bash("a b c {d:t} {e:test}").replace(" ", " "), "a b c -d -e test")
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