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

suggested color changes for cherry-picker output #120

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
98 changes: 90 additions & 8 deletions cherry_picker/cherry_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import webbrowser

import click
from click.termui import _ansi_colors as color_names
import requests
from gidgethub import sansio

Expand All @@ -31,6 +32,8 @@
"check_sha": "7f777ed95a19224294949e1b4ce56bbffcb1fe9f",
"fix_commit_msg": True,
"default_branch": "main",
"bright": "red",
"dim": "0x808080",
}
)

Expand Down Expand Up @@ -77,7 +80,6 @@
""",
)


class BranchCheckoutException(Exception):
def __init__(self, branch_name):
self.branch_name = branch_name
Expand Down Expand Up @@ -109,6 +111,7 @@
config=DEFAULT_CONFIG,
chosen_config_path=None,
auto_pr=True,
use_color=True,
):
self.chosen_config_path = chosen_config_path
"""The config reference used in the current runtime.
Expand Down Expand Up @@ -137,6 +140,14 @@
self.push = push
self.auto_pr = auto_pr
self.prefix_commit = prefix_commit
self.dim = config["dim"]
self.bright = config["bright"]

if not use_color or os.environ.get("NO_COLOR") is not None:
self.dim = self.bright = None

Check warning on line 147 in cherry_picker/cherry_picker.py

View check run for this annotation

Codecov / codecov/patch

cherry_picker/cherry_picker.py#L147

Added line #L147 was not covered by tests

self.dim = normalize_color(self.dim)
self.bright = normalize_color(self.bright)

# the cached calculated value of self.upstream property
self._upstream = None
Expand Down Expand Up @@ -306,7 +317,7 @@
click.echo(self.run_cmd(cmd))
except subprocess.CalledProcessError as err:
click.echo(f"Error cherry-pick {self.commit_sha1}.")
click.echo(err.output)
click.secho(err.output, fg=self.dim)
raise CherryPickException(f"Error cherry-pick {self.commit_sha1}.")

def get_exit_message(self, branch):
Expand Down Expand Up @@ -387,7 +398,7 @@
return updated_commit_message

def pause_after_committing(self, cherry_pick_branch):
click.echo(
click.secho(
f"""
Finished cherry-pick {self.commit_sha1} into {cherry_pick_branch} \U0001F600
--no-push option used.
Expand All @@ -397,7 +408,8 @@

To abort the cherry-pick and cleanup:
$ cherry_picker --abort
"""
""",
fg=self.bright,
)
self.set_paused_state()

Expand Down Expand Up @@ -468,8 +480,8 @@
if self.dry_run:
click.echo(f" dry-run: Create new PR: {url}")
else:
click.echo("Backport PR URL:")
click.echo(url)
click.secho("Backport PR URL:", fg=self.bright)
click.secho(url, fg=self.bright)

Check warning on line 484 in cherry_picker/cherry_picker.py

View check run for this annotation

Codecov / codecov/patch

cherry_picker/cherry_picker.py#L483-L484

Added lines #L483 - L484 were not covered by tests
webbrowser.open_new_tab(url)

def delete_branch(self, branch):
Expand Down Expand Up @@ -530,9 +542,9 @@
commit_message = self.amend_commit_message(cherry_pick_branch)
except subprocess.CalledProcessError as cpe:
click.echo(cpe.output)
click.echo(self.get_exit_message(maint_branch))
click.secho(self.get_exit_message(maint_branch), fg=self.bright)
except CherryPickException:
click.echo(self.get_exit_message(maint_branch))
click.secho(self.get_exit_message(maint_branch), fg=self.bright)
self.set_paused_state()
raise
else:
Expand Down Expand Up @@ -776,6 +788,19 @@
)
@click.argument("commit_sha1", nargs=1, default="")
@click.argument("branches", nargs=-1)
@click.option(
"--color/--no-color",
"color",
is_flag=True,
default=True,
help=(
"If color display is enabled (the default), cherry-picker will use color to"
" distinguish its output from that of 'git cherry-pick'. Color display can"
" also be suppressed by setting NO_COLOR environment variable to non-empty value."
),
)
@click.argument("bright", nargs=1)
@click.argument("dim", nargs=1)
@click.pass_context
def cherry_pick_cli(
ctx,
Expand All @@ -789,6 +814,9 @@
config_path,
commit_sha1,
branches,
color,
bright,
dim,
):
"""cherry-pick COMMIT_SHA1 into target BRANCHES."""

Expand All @@ -807,6 +835,7 @@
auto_pr=auto_pr,
config=config,
chosen_config_path=chosen_config_path,
use_color=color,
)
except InvalidRepoException:
click.echo(f"You're not inside a {config['repo']} repo right now! \U0001F645")
Expand Down Expand Up @@ -1071,5 +1100,58 @@
return WORKFLOW_STATES.__members__[state_str]


def normalize_color(color):
"""Produce colors in Click's format from strings.

Supported formats are:

* color names understood by Click. See:
https://click.palletsprojects.com/en/8.1.x/api/#click.style
* RGB values of the form 0xRRGGBB or 0xRGB.
* Tuple of ints (base 10), must have leading and trailing parens,
and values separated by commas, e.g., "( 44, 88, 255)".

"""

if color is None:
return color

Check warning on line 1117 in cherry_picker/cherry_picker.py

View check run for this annotation

Codecov / codecov/patch

cherry_picker/cherry_picker.py#L1117

Added line #L1117 was not covered by tests

color = color.strip().lower()

if color.lower().startswith("0x"):
# Assume it's a hex string and convert it to Click's tuple of ints
# form. It's kind of surprising Click doesn't support hex strings
# directly.
if len(color) == 8:
# assume six-digit hex, 0xRRGGBB
return (
int(color[2:4], 16),
int(color[4:6], 16),
int(color[6:8], 16),
)
elif len(color) == 5:

Check warning on line 1132 in cherry_picker/cherry_picker.py

View check run for this annotation

Codecov / codecov/patch

cherry_picker/cherry_picker.py#L1132

Added line #L1132 was not covered by tests
# assume three-digit hex, 0xRGB
return (

Check warning on line 1134 in cherry_picker/cherry_picker.py

View check run for this annotation

Codecov / codecov/patch

cherry_picker/cherry_picker.py#L1134

Added line #L1134 was not covered by tests
int(color[2], 16) * 16,
int(color[3], 16) * 16,
int(color[4], 16) * 16,
)
else:
raise ValueError(f"unrecognized hex string: {color!r}")

Check warning on line 1140 in cherry_picker/cherry_picker.py

View check run for this annotation

Codecov / codecov/patch

cherry_picker/cherry_picker.py#L1140

Added line #L1140 was not covered by tests

if color[0] == "(" and color[-1] == ")":
# let's hope it's a tuple of ints...
try:
red, green, blue = [int(x.strip()) for x in color[1:-1].split(",")]
except ValueError as exc:
raise ValueError(f"unrecognized tuple of ints string: {color!r}") from exc
return (red, green, blue)

Check warning on line 1148 in cherry_picker/cherry_picker.py

View check run for this annotation

Codecov / codecov/patch

cherry_picker/cherry_picker.py#L1144-L1148

Added lines #L1144 - L1148 were not covered by tests

# fallback is to assume it's a color name supported by click.
if color in color_names:
return color
raise ValueError(f"unrecognized color: '{color!r}'")

Check warning on line 1153 in cherry_picker/cherry_picker.py

View check run for this annotation

Codecov / codecov/patch

cherry_picker/cherry_picker.py#L1153

Added line #L1153 was not covered by tests


if __name__ == "__main__":
cherry_pick_cli()
6 changes: 6 additions & 0 deletions cherry_picker/test_cherry_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ def test_load_full_config(tmp_git_repo_dir, git_add, git_commit):
"team": "python",
"fix_commit_msg": True,
"default_branch": "devel",
"bright": "red",
"dim": "0x808080",
},
)

Expand All @@ -479,6 +481,8 @@ def test_load_partial_config(tmp_git_repo_dir, git_add, git_commit):
"team": "python",
"fix_commit_msg": True,
"default_branch": "main",
"bright": "red",
"dim": "0x808080",
},
)

Expand Down Expand Up @@ -507,6 +511,8 @@ def test_load_config_no_head_sha(tmp_git_repo_dir, git_add, git_commit):
"team": "python",
"fix_commit_msg": True,
"default_branch": "devel",
"bright": "red",
"dim": "0x808080",
},
)

Expand Down
Loading