Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colorize the terminal with pretty colors #613

Closed
wants to merge 7 commits into from
Closed
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
6 changes: 3 additions & 3 deletions ci/test/dot
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ cd github-actions-demo

export PHONY_SECRET=foo

popper dot > dot_output
popper dot | sed -r "s/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" > dot_output

grep "digraph G" dot_output
grep "branch_filter -> deploy;" dot_output
Expand All @@ -33,7 +33,7 @@ export AWS_SECRET_ACCESS_KEY=foo
# Move main.workflow to somewhere else to test --recursive flag
mkdir dummy
mv .github/main.workflow dummy/.
popper dot --recursive > dot_output
popper dot --recursive | sed -r "s/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g"> dot_output

grep "digraph G" dot_output
grep "Build_and_Deploy -> Build_Docker_image;" dot_output
Expand All @@ -52,7 +52,7 @@ grep "Verify_EKS_deployment -> List_Public_IP;" dot_output

## testing --wfile feature
cd "$test_repo_path"
popper dot --wfile example-aws/dummy/main.workflow > dot_output
popper dot --wfile example-aws/dummy/main.workflow | sed -r "s/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" > dot_output

grep "digraph G" dot_output
grep "Build_and_Deploy -> Build_Docker_image;" dot_output
Expand Down
4 changes: 2 additions & 2 deletions ci/test/dry-run
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export PHONY_SECRET=foo
mapfile -t args < <(docker ps -aq)
docker rm "${args[@]}" || true

dry_num_lines=$(popper run --dry-run | grep -c 'DRYRUN')
dry_num_lines=$(popper run --dry-run | sed -r "s/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | grep -c 'DRYRUN')

# 5 actions, at least one line per action
test "$dry_num_lines" -gt 5
Expand Down Expand Up @@ -75,7 +75,7 @@ action "custom action" {
}
EOF

dry_num_lines=$(popper run --dry-run | grep -c 'DRYRUN')
dry_num_lines=$(popper run --dry-run | sed -r "s/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | grep -c 'DRYRUN')

# 3 actions, atleast one line per action
test "$dry_num_lines" -gt 3
6 changes: 3 additions & 3 deletions ci/test/quiet
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ action "custom action" {
}
EOF

output_lines_without_quiet=$(popper run | wc -l)
output_lines_with_quiet=$(popper run --quiet | wc -l)
output_lines_without_quiet=$(popper run | sed -r "s/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | wc -l)
output_lines_with_quiet=$(popper run --quiet | sed -r "s/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | wc -l)

test "$output_lines_without_quiet" -gt "$output_lines_with_quiet"
test "$output_lines_without_quiet" -gt "$output_lines_with_quiet"
2 changes: 1 addition & 1 deletion ci/test/recursive
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ do
create_workflow "$i"
done

popper run --recursive >> out
popper run --recursive | sed -r "s/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" >> out
mapfile -t files < <(grep "^Found .*" out | cut -f6 -d' ' | cut -d'/' -f4-)

counter=0
Expand Down
4 changes: 3 additions & 1 deletion ci/test/singularity
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,6 @@ if [[ $PY_VERSION != *"Python 2.7"* ]]; then

popper run --parallel

fi
fi
popper run
popper run --quiet
2 changes: 1 addition & 1 deletion cli/popper/commands/cmd_dot.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def cli(ctx, wfile, recursive):
graph = add(parent_action, cur_action, wf['action'], graph)
graph = ''.join(list(set(graph)))
graph = "digraph G {\n" + graph + "}\n"
pu.info(graph)
pu.info(msg=graph, colorize=False)


# Recursively go through "needs" and add corresponding actions to graph
Expand Down
12 changes: 7 additions & 5 deletions cli/popper/commands/cmd_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ def run_pipeline(action, wfile, workspace, reuse,
popper.cli.interrupt_params = pipeline

if reuse:
pu.info(
pu.warn(
"\n " +
"WARNING: using --reuse ignores any changes made to an action" +
"using --reuse ignores any changes made to an action" +
"\n " +
"or to an action block in the workflow.\n\n"
)
Expand All @@ -105,16 +105,18 @@ def run_pipeline(action, wfile, workspace, reuse,
if sys.version_info[0] < 3:
pu.fail('--parallel is only supported on Python3')

pu.info(
pu.warn(
"\n " +
"WARNING: using --parallel may result in interleaved ouput." +
"using --parallel may result in interleaved ouput." +
"\n " +
"You may use --quiet flag to avoid confusion.\n\n"
)

pipeline.run(action, reuse, parallel)

if action:
pu.info('\nAction "{}" finished successfully.\n\n'.format(action))
pu.info(
prefix='\nAction "{}" finished successfully.\n\n'.format(action),
msg='')
else:
pu.info('\nWorkflow finished successfully.\n\n')
31 changes: 16 additions & 15 deletions cli/popper/gha.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ def download_actions(self):

if not self.dry_run:
if not infoed:
pu.info('[popper] cloning actions from repositories\n')
pu.info(msg=' cloning actions from repositories\n',
action='[popper]')
infoed = True

scm.clone(url, user, repo, repo_parent_dir, version,
Expand Down Expand Up @@ -475,10 +476,9 @@ def docker_rm(self):
self.container.remove(force=True)

def docker_create(self, img):
pu.info('{}[{}] docker create {} {}\n'.format(
self.msg_prefix,
self.action['name'], img, ' '.join(self.action.get('args', ''))
))
pu.info(msg=' docker create {} {}\n'.format(
img, ' '.join(self.action.get('args', ''))),
prefix=self.msg_prefix, action='['+self.action['name']+']')
if self.dry_run:
return
env_vars = self.action.get('env', {})
Expand All @@ -491,7 +491,7 @@ def docker_create(self, img):
env_vars.update({'HOME': os.environ['HOME']})
volumes = [self.workspace, os.environ['HOME'], '/var/run/docker.sock']
if self.debug:
pu.info('DEBUG: Invoking docker_create() method\n')
pu.info(' Invoking docker_create() method\n', prefix='DEBUG:')
self.container = self.docker_client.containers.create(
image=img,
command=self.action.get('args', None),
Expand All @@ -504,8 +504,8 @@ def docker_create(self, img):
)

def docker_start(self):
pu.info('{}[{}] docker start \n'.format(self.msg_prefix,
self.action['name']))
pu.info(prefix=self.msg_prefix, action='['+self.action['name']+']',
msg=' docker start \n')
if self.dry_run:
return 0
self.container.start()
Expand All @@ -515,7 +515,8 @@ def docker_start(self):
if sleep_time < 10:
sleep_time *= 2
if self.debug:
pu.info('DEBUG: sleeping for {}\n'.format(sleep_time))
pu.info(msg=' sleeping for {}\n'.format(sleep_time),
prefix='DEBUG:')
else:
pu.info('.')

Expand All @@ -532,15 +533,15 @@ def b(t):
return self.container.wait()['StatusCode']

def docker_pull(self, img):
pu.info('{}[{}] docker pull {}\n'.format(self.msg_prefix,
self.action['name'], img))
pu.info(msg=' docker pull {}\n'.format(img),
prefix=self.msg_prefix, action='['+self.action['name']+']')
if self.dry_run:
return
self.docker_client.images.pull(repository=img)

def docker_build(self, tag, path):
pu.info('{}[{}] docker build -t {} {}\n'.format(
self.msg_prefix, self.action['name'], tag, path))
pu.info(prefix=self.msg_prefix, action='['+self.action['name']+']',
msg=' docker build -t {} {}\n'.format(tag, path))
if self.dry_run:
return
self.docker_client.images.build(path=path, tag=tag, rm=True, pull=True)
Expand Down Expand Up @@ -704,8 +705,8 @@ def run(self, reuse=False):

os.environ.update(self.action.get('env', {}))

pu.info('{}[{}] {}\n'.format(self.msg_prefix, self.action['name'],
' '.join(cmd)))
pu.info(msg=' {}\n'.format(' '.join(cmd)), prefix=self.msg_prefix,
action='['+self.action['name']+']')

_, ecode = pu.exec_cmd(
' '.join(cmd), verbose=(not self.quiet), debug=self.debug,
Expand Down
51 changes: 34 additions & 17 deletions cli/popper/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,34 @@
import threading
import time
from subprocess import PIPE, STDOUT, CalledProcessError, Popen, check_output

import click
import popper.cli



def fail(msg):
def fail(msg, colorize=True):
"""Prints the error message on the terminal."""
click.secho('ERROR: ' + msg, fg='red', bold=True, err=True, nl=False)
click.echo(click.style('ERROR: ', bg='red', fg='white') +
click.style(msg, bold=True),
err=True, nl=False, color=True)
sys.exit(1)


def warn(msg):
click.secho('WARNING: ' + msg, bold=True, fg='red', err=True, nl=False)
def warn(msg, colorize=True):
click.echo(click.style('WARNING: ', bg='yellow', fg='black', bold=True) +
click.style(msg, fg='yellow', bold=True),
err=True, nl=False, color=True)


def info(msg, **styles):
def info(msg, prefix='', action='', colorize=True):
"""Prints the message on the terminal."""
click.secho(msg, nl=False, **styles)
click.echo(click.style(prefix, fg='green', bold=True) +
click.style(action, fg='blue', bold=True) +
click.style(msg), nl=False, color=colorize)


def print_yaml(msg, **styles):
"""Prints the messages in YAML's block format'\033[0m' +. """
click.secho(yaml.safe_dump(msg, default_flow_style=False), **styles)


def exec_cmd(cmd, verbose=False, debug=False, ignore_error=False,
Expand Down Expand Up @@ -55,15 +64,17 @@ def b(t):
if not verbose and not log_file:
out = ""
if debug:
info('DEBUG: Using subprocess.check_output() for {}\n'.format(cmd))
info(prefix='DEBUG:',
msg=' Using subprocess.check_output() for {}\n'.format(cmd))
try:
out = check_output(cmd, shell=True, stderr=PIPE,
universal_newlines=True)
ecode = 0
except CalledProcessError as ex:
ecode = ex.returncode
if debug:
info('DEBUG: Catched exception: {}\n'.format(ex))
info(prefix='DEBUG:',
msg='Catched exception: {}\n'.format(ex))
if not ignore_error:
fail("Command '{}' failed: {}\n".format(cmd, ex))
return b(out).strip(), ecode
Expand All @@ -76,31 +87,35 @@ def b(t):
if log_file:
if verbose:
if debug:
info('\nDEBUG: Creating file for combined stdout/stderr\n')
info(prefix='\nDEBUG:',
msg='Creating file for combined stdout/stderr\n')
outf = open(log_file + '.log', 'w')
else:
if debug:
info('\nDEBUG: Creating separate files for stdout/stderr\n')
info(prefix='\nDEBUG:',
msg=' Creating separate files for stdout/stderr\n')
outf = open(log_file + '.out', 'w')
errf = open(log_file + '.err', 'w')

try:
if verbose:
if debug:
info('DEBUG: subprocess.Popen() with combined stdout/stderr\n')
info(prefix='DEBUG:',
msg=' subprocess.Popen() with combined stdout/stderr\n')
p = Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True,
universal_newlines=True, preexec_fn=os.setsid)
else:
if debug:
info('DEBUG: subprocess.Popen() with separate stdout/stderr\n')
info(prefix='DEBUG:',
msg=' subprocess.Popen() with separate stdout/stderr\n')
p = Popen(cmd, stdout=outf, stderr=errf, shell=True,
universal_newlines=True, preexec_fn=os.setsid)

if add_to_process_list:
popper.cli.process_list.append(p.pid)

if debug:
info('DEBUG: Reading process output\n')
info(prefix='\nDEBUG:', msg=' Reading process output\n')

while ecode is None:

Expand All @@ -121,15 +136,17 @@ def b(t):
num_times_point_at_current_sleep_time += 1

if debug:
info('DEBUG: sleeping for {}\n'.format(sleep_time))
info(prefix='DEBUG:',
msg=' sleeping for {}\n'.format(sleep_time))
else:
info('.')

time.sleep(sleep_time)

ecode = p.poll()
if debug:
info('DEBUG: Code returned by process: {}\n'.format(ecode))
info(prefix='DEBUG:',
msg=' Code returned by process: {}\n'.format(ecode))

except CalledProcessError as ex:
msg = "Command '{}' failed: {}\n".format(cmd, ex)
Expand Down