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

Enhance the output of the Perun #174

Merged
merged 25 commits into from
Feb 12, 2024
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Polished output of the perun add
log: reworked the minor_info little;
common_kit: fix bug.
tfiedor committed Feb 9, 2024
commit 6b5d33bfa12e498b1d7397152bdd51cc90a7d43b
37 changes: 29 additions & 8 deletions perun/logic/commands.py
Original file line number Diff line number Diff line change
@@ -227,11 +227,16 @@ def add(
:param bool force: if set to true, then the add will be forced, i.e. the check for origin will
not be performed.
"""
perun_log.major_info("Adding profiles")
added_profile_count = 0
for profile_name in profile_names:
# Test if the given profile exists (This should hold always, or not?)
reg_rel_path = os.path.relpath(profile_name)
if not os.path.exists(profile_name):
perun_log.error(f"profile {profile_name} does not exists", recoverable=True)
perun_log.minor_info(
perun_log.path_style(f"{reg_rel_path}"), status=perun_log.failed_highlight("failed")
)
perun_log.minor_info("profile does not exists", indent_level=2, end="\n")
continue

# Load profile content
@@ -240,9 +245,17 @@ def add(
unpacked_profile = store.load_profile_from_file(profile_name, True, unsafe_load=True)

if not force and unpacked_profile["origin"] != minor_version:
error_msg = f"cannot add profile '{profile_name}' to minor index of '{minor_version}':"
error_msg += f"profile originates from minor version '{unpacked_profile['origin']}'"
perun_log.error(error_msg, recoverable=True)
perun_log.minor_info(
perun_log.path_style(f"{reg_rel_path}"), status=perun_log.failed_highlight("failed")
)
perun_log.minor_info(
"current version", status=f"{perun_log.highlight(minor_version)}", indent_level=2
)
perun_log.minor_info(
"origin version",
status=f"{perun_log.highlight(unpacked_profile['origin'])}",
indent_level=2,
)
continue

# Remove origin from file
@@ -270,15 +283,22 @@ def add(
if not keep_profile:
os.remove(profile_name)

perun_log.minor_info(
perun_log.path_style(f"{reg_rel_path}"),
status=perun_log.success_highlight("registered"),
)
added_profile_count += 1

profile_names_len = len(profile_names)
perun_log.minor_info(
"Registration succeeded for",
status=f"{perun_log.success_highlight(common_kit.str_to_plural(added_profile_count, 'profile'))}",
)
if added_profile_count != profile_names_len:
perun_log.error(
f"could not register {common_kit.str_to_plural(added_profile_count, 'profile')}"
f" in index: {added_profile_count - profile_names_len} failed"
failed_profile_count = common_kit.str_to_plural(
profile_names_len - added_profile_count, "profile"
)
perun_log.info(f"successfully registered {added_profile_count} profiles in index")
perun_log.error(f"Registration failed for - {failed_profile_count}")


@vcs_kit.lookup_minor_version
@@ -415,6 +435,7 @@ def log(minor_version: str, short: bool = False, **_: Any) -> None:
minor_version_maxima = calculate_maximal_lengths_for_object_list(
minor_versions, MinorVersion.valid_fields()
)

# Update manually the maxima for the printed supported profile types, each requires two
# characters and 9 stands for " profiles" string

3 changes: 0 additions & 3 deletions perun/logic/index.py
Original file line number Diff line number Diff line change
@@ -598,9 +598,6 @@ def register_in_index(
)
write_entry_to_index(index_filename, entry)

reg_rel_path = os.path.relpath(registered_file)
perun_log.info(f"'{reg_rel_path}' successfully registered in minor version index")


def remove_from_index(
base_dir: str, minor_version: str, removed_file_generator: Collection[str]
2 changes: 1 addition & 1 deletion perun/utils/common/common_kit.py
Original file line number Diff line number Diff line change
@@ -151,7 +151,7 @@ def str_to_plural(count: int, verb: str) -> str:
:param int count: number of the verbs
:param str verb: name of the verb we are creating a plural for
"""
return str(count) + " " + verb + "s" if count != 1 else verb
return str(count) + " " + (verb + "s" if count != 1 else verb)


def format_counter_number(count: int, max_number: int) -> str:
29 changes: 27 additions & 2 deletions perun/utils/log.py
Original file line number Diff line number Diff line change
@@ -322,12 +322,16 @@ def major_info(msg: str, colour: ColorChoiceType = "blue") -> None:
info("")


def minor_info(msg: str, sep: str = "-", indent_level: int = 1, end: str = ""):
def minor_info(msg: str, status: str = "", sep: str = "-", indent_level: int = 1, end: str = ""):
"""Prints minor information, formatted with indent and starting with -

Note, that there are some sanitizations happening
Note, that there are some sanitizations happening:
1. If we want to end the info in new line, we add the punctuations;
2. If we want to add some status, we add the separator
3. If we want to add some status, we add the separaror and also the ending

:param msg: printed message, which will be stripped from whitespace and capitalized
:param status: status of the info
:param sep: separator used to separate the info with its results
:param indent_level: indent of the information
:param end: ending of the message
@@ -337,6 +341,9 @@ def minor_info(msg: str, sep: str = "-", indent_level: int = 1, end: str = ""):
msg += "."
elif end == "" and sep != "" and msg[-1] != sep:
msg += f" {sep} "
if status != "":
msg += status
end = "\n"
info(" " * indent_level * 2 + " - " + msg, end)


@@ -402,6 +409,24 @@ def highlight(highlighted_str: str) -> str:
return in_color(highlighted_str, "blue", attribute_style=["bold"])


def success_highlight(highlighted_str: str) -> str:
"""Highlights of the string that is considered successful

:param highlighted_str: string that will be highlighted
:return: highlighted string
"""
return in_color(highlighted_str, "green", attribute_style=["bold"])


def failed_highlight(highlighted_str: str) -> str:
"""Highlights of the string that is considered failure

:param highlighted_str: string that will be highlighted
:return: highlighted string
"""
return in_color(highlighted_str, "red", attribute_style=["bold"])


def in_color(
output: str, color: ColorChoiceType = "white", attribute_style: Optional[AttrChoiceType] = None
) -> str:
6 changes: 4 additions & 2 deletions tests/test_add.py
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
# Perun Imports
from perun.logic import store, index, commands
from perun.utils import timestamps
from perun.utils.common import common_kit
from perun.utils.exceptions import (
NotPerunRepositoryException,
UnsupportedModuleException,
@@ -264,8 +265,9 @@ def test_add_wrong_profile(pcs_full, error_profile_pool, capsys):
after_count = test_utils.count_contents_on_path(pcs_full.get_path())
assert before_count == after_count

_, err = capsys.readouterr()
assert "notexisting.perf does not exist" in err
out, err = capsys.readouterr()
assert "Profile does not exist" in out
assert "Registration failed for - 1 profile" in common_kit.escape_ansi(err)


def test_add_existing(pcs_full, valid_profile_pool, capsys):
20 changes: 14 additions & 6 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -1438,7 +1438,9 @@ def test_add_massaged_head(pcs_full_no_prof, valid_profile_pool):
runner = CliRunner()
result = runner.invoke(cli.add, ["0@p", "--minor=HEAD"])
asserts.predicate_from_cli(result, result.exit_code == 0)
asserts.predicate_from_cli(result, f"'{first_tagged}' successfully registered" in result.output)
asserts.predicate_from_cli(
result, f"{first_tagged} - registered" in common_kit.escape_ansi(result.output)
)

runner = CliRunner()
result = runner.invoke(cli.add, ["0@p", r"--minor=HEAD^{d"])
@@ -1480,19 +1482,25 @@ def test_add_tag(monkeypatch, pcs_full_no_prof, valid_profile_pool):
runner = CliRunner()
result = runner.invoke(cli.add, ["0@p"])
asserts.predicate_from_cli(result, result.exit_code == 0)
asserts.predicate_from_cli(result, f"'{first_sha}' successfully registered" in result.output)
asserts.predicate_from_cli(
result, f"{first_sha} - registered" in common_kit.escape_ansi(result.output)
)

runner = CliRunner()
result = runner.invoke(cli.add, ["0@p"])
asserts.predicate_from_cli(result, result.exit_code == 1)
asserts.predicate_from_cli(result, f"originates from minor version '{parent}'" in result.output)
asserts.predicate_from_cli(
result, f"Origin version - {parent}" in common_kit.escape_ansi(result.output)
)

# Check that force work as intented
monkeypatch.setattr("click.confirm", lambda _: True)
runner = CliRunner()
result = runner.invoke(cli.add, ["--force", "0@p"])
asserts.predicate_from_cli(result, result.exit_code == 0)
asserts.predicate_from_cli(result, f"'{second_sha}' successfully registered" in result.output)
asserts.predicate_from_cli(
result, f"{second_sha} - registered" in common_kit.escape_ansi(result.output)
)

result = runner.invoke(cli.add, ["10@p"])
asserts.predicate_from_cli(result, result.exit_code == 2)
@@ -1518,13 +1526,13 @@ def test_add_tag_range(pcs_with_root, valid_profile_pool):
result = runner.invoke(cli.add, ["10@p-0@p"])
asserts.predicate_from_cli(result, result.exit_code == 0)
asserts.predicate_from_cli(
result, "successfully registered 0 profiles in index" in result.output
result, "Registration succeeded for - 0 profiles" in common_kit.escape_ansi(result.output)
)

result = runner.invoke(cli.add, ["0@p-10@p"])
asserts.predicate_from_cli(result, result.exit_code == 0)
asserts.predicate_from_cli(
result, "successfully registered 2 profiles in index" in result.output
result, "Registration succeeded for - 2 profiles" in common_kit.escape_ansi(result.output)
)

# Nothing should remain!