Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
check: lint test
check: format lint test clean

SOURCE_FILES=pybash test_pybash.py

Expand Down
35 changes: 19 additions & 16 deletions pybash/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def fstring_interpolate(token_string: str, parsed_command: str) -> str:
return parsed_command.replace('"" + f"""', 'f"""').replace('""" + ""', '"""')

@staticmethod
def direct_interpolate(string: str) -> str:
def direct_interpolate(token_string: str) -> str:
"""Process {{ static interpolations }} and substitute.
Static interpolations are denotated by a {{ }} with a variable or a function call inside.
Substitution happens directly on the parsed command string. Therefore, certain characters
Expand All @@ -64,21 +64,24 @@ def direct_interpolate(string: str) -> str:
string (str): String to interpolate

Returns:
str: Interpolated string
str: Interpolated or given token string
"""

# validate interpolation
invalid_chars = [' ', '"', "'"]
matches = re.findall(r'{{(.+?)}}', string)
if matches and any(any(bad_char in match for bad_char in invalid_chars) for match in matches):
matches = re.findall(r'{{(.+?)}}', token_string)
if not matches:
return token_string

if any(any(bad_char in match for bad_char in invalid_chars) for match in matches):
raise InvalidInterpolation

interpolated = re.sub(r'{{(.+?)}}', r'" + \1 + "', string)
return interpolated.replace('"" + ', '').replace(' + ""', '')
interpolated = re.sub(r'{{(.+?)}}', r'" + \1 + "', token_string)
return interpolated.replace(',"" + ', ',').replace(' + ""', '')


class Shelled(Processor):
# $ls .github/*
# >ls .github/*
command_char = ">"

def transform(self) -> token_utils.Token:
Expand All @@ -88,7 +91,7 @@ def transform(self) -> token_utils.Token:


class Execed(Processor):
# >ls -la
# $ls -la
def transform(self) -> token_utils.Token:
pipeline_command = Pipeline(self.command).parse_command()
if pipeline_command != self.command:
Expand All @@ -100,7 +103,7 @@ def transform(self) -> token_utils.Token:


class Variablized(Processor):
# a = >cat test.txt
# a = $cat test.txt
def parse(self) -> None:
self.parsed_line = shlex.split(self.token.line)
self.start_index = Commander.get_start_index(self.parsed_line)
Expand All @@ -119,7 +122,7 @@ def transform(self) -> None:


class Wrapped(Processor):
# print(>cat test.txt)
# print($cat test.txt)
def parse(self) -> None:
self.parsed_line = shlex.split(self.token.line)
self.raw_line = [tok for tok in self.token.line.split(' ') if tok]
Expand Down Expand Up @@ -189,17 +192,17 @@ def chain_iredirect_command(
fvar = f"fout{idx}"
cmd = ""
if piper == '>':
# >sort < test.txt > test2.txt
# $sort < test.txt > test2.txt
cmd = cls.write_to_file(
command, pipeline, reader='cmd1.stdout.read()', start_index=first_idx + 1, fmode="wb"
)
elif piper == '>>':
# >sort < test.txt >> test2.txt
# $sort < test.txt >> test2.txt
cmd = cls.write_to_file(
command, pipeline, reader='cmd1.stdout.read()', start_index=first_idx + 1, fmode="ab"
)
elif piper == '|':
# >sort < test.txt | grep "HELLO"
# $sort < test.txt | grep "HELLO"
cmd = cls.get_piper(piper)(
command, pipeline, start_index=first_idx + 1, stdin="cmd1.stdout", chained=True
)
Expand Down Expand Up @@ -353,15 +356,15 @@ def get_bash_command(
Returns:
list: parsed command list
"""
# find which arg index the > is at
# find which arg index the $ is at
if not start_index:
start_index = Commander.get_start_index(parsed_line)

# strip everything before that index-- not part of the command
command = parsed_line[start_index:]

# > may be at the beginning or somewhere in the middle of this arg
# examples: >ls, print(>cat => strip up to and including >
# $ may be at the beginning or somewhere in the middle of this arg
# examples: $ls, print(>cat => strip up to and including >
command[0] = command[0][command[0].index(command_char) + 1 :].strip()
if command[0] == '':
del command[0]
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "PyBash"
version = "0.3.3"
version = "0.3.4"
description = ">execute bash commands from python easily"
authors = ["Jay <jay.github0@gmail.com>"]
readme = "README.md"
Expand Down
6 changes: 6 additions & 0 deletions test_pybash.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ def test_fstring_interpolate():
== 'subprocess.run(["kubectl","get","pods",f"""{"--" + "-".join([\'show\', \'labels\'])}""","-n",f"""{ namespace }"""])\n'
)
assert run_bash("$git f{options['h']}") == 'subprocess.run(["git",f"""{options[\'h\']}"""])\n'
assert run_bash("$f{HOME_DIR}/bin/python -sE") == 'subprocess.run([f"""{HOME_DIR}""" + "/bin/python","-sE"])\n'


def test_interpolate_combo():
assert run_bash("$echo 'f{PODS} 123' {{ARGS}}") == 'subprocess.run(["echo",f"""{PODS}""" + " 123",ARGS])\n'
assert run_bash("$git {{COMMAND}} f{ARGS} -v") == 'subprocess.run(["git",COMMAND,f"""{ARGS}""","-v"])\n'


def test_invalid_interpolate():
Expand Down