print all collisions found before failing

This commit is contained in:
Markus Hofbauer 2022-11-22 17:57:15 +01:00 committed by Markus Hofbauer
parent ccfdc8dd97
commit b456dc5342
2 changed files with 56 additions and 28 deletions

View file

@ -2,16 +2,14 @@
from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser
from pathlib import Path from pathlib import Path
from typing import List
from dataclasses import dataclass from dataclasses import dataclass
import itertools import itertools
import re import re
ERROR_MESSAGE_TEMPLATE = """Found alias collision ERROR_MESSAGE_TEMPLATE = (
Alias `%s` defined in `%s` already exists as alias `%s` in `%s`. "Alias `%s` defined in `%s` already exists as alias `%s` in `%s`."
Consider renaming your alias. )
"""
def dir_path(path_string: str) -> Path: def dir_path(path_string: str) -> Path:
@ -42,41 +40,62 @@ class Alias:
module: Path module: Path
def find_aliases_in_file(file: Path) -> List[Alias]: @dataclass(frozen=True)
class Collision:
existing_alias: Alias
new_alias: Alias
def find_aliases_in_file(file: Path) -> list[Alias]:
matches = re.findall(r"^alias (.*)='(.*)'", file.read_text(), re.M) matches = re.findall(r"^alias (.*)='(.*)'", file.read_text(), re.M)
return [Alias(match[0], match[1], file) for match in matches] return [Alias(match[0], match[1], file) for match in matches]
def find_all_aliases(path: Path) -> List: def find_all_aliases(path: Path) -> list:
files = list(path.rglob("*.zsh")) files = list(path.rglob("*.zsh"))
aliases = [find_aliases_in_file(file) for file in files] aliases = [find_aliases_in_file(file) for file in files]
return list(itertools.chain(*aliases)) return list(itertools.chain(*aliases))
def check_for_duplicates(aliases: List[Alias]) -> None: def check_for_duplicates(aliases: list[Alias]) -> list[Collision]:
elements = {} elements = {}
collisions = []
for alias in aliases: for alias in aliases:
if alias.alias in elements: if alias.alias in elements:
existing = elements[alias.alias] existing = elements[alias.alias]
raise ValueError( collisions.append(Collision(existing, alias))
ERROR_MESSAGE_TEMPLATE
% (
f"{alias.alias}={alias.value}",
alias.module.name,
f"{existing.alias}={existing.value}",
existing.module.name,
)
)
else: else:
elements[alias.alias] = alias elements[alias.alias] = alias
return collisions
def print_collisions(collisions: dict[Alias, Alias]) -> None:
if collisions:
print(f"Found {len(collisions)} alias collisions:\n")
for collision in collisions:
print(
ERROR_MESSAGE_TEMPLATE
% (
f"{collision.new_alias.alias}={collision.new_alias.value}",
collision.new_alias.module.name,
f"{collision.existing_alias.alias}={collision.existing_alias.value}",
collision.existing_alias.module.name,
)
)
print("\nConsider renaming your aliases.")
else:
print("Found no collisions")
def main(): def main():
"""main""" """main"""
args = parse_arguments() args = parse_arguments()
aliases = find_all_aliases(args.folder) aliases = find_all_aliases(args.folder)
check_for_duplicates(aliases) collisions = check_for_duplicates(aliases)
print("Found no collisions") print_collisions(collisions)
if collisions:
exit(-1)
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -7,6 +7,7 @@ from check_alias_collision import (
find_aliases_in_file, find_aliases_in_file,
check_for_duplicates, check_for_duplicates,
Alias, Alias,
Collision,
) )
@ -73,21 +74,29 @@ class CheckAliasCollisionTest(TestCase):
result = find_aliases_in_file(Path("conditional.zsh")) result = find_aliases_in_file(Path("conditional.zsh"))
self.assertListEqual([], result) self.assertListEqual([], result)
def test_check_for_duplicates__no_duplicates_should_not_raise(self) -> None: def test_check_for_duplicates__no_duplicates_should_return_empty_dict(self) -> None:
check_for_duplicates( result = check_for_duplicates(
[ [
Alias("g", "git", Path("git.zsh")), Alias("g", "git", Path("git.zsh")),
Alias("ga", "git add", Path("git.zsh")), Alias("ga", "git add", Path("git.zsh")),
Alias("gaa", "git add --all", Path("git.zsh")), Alias("gaa", "git add --all", Path("git.zsh")),
] ]
) )
self.assertTrue(True) self.assertListEqual(result, [])
def test_check_for_duplicates__duplicates_should_raise(self) -> None: def test_check_for_duplicates__duplicates_should_have_one_collision(self) -> None:
with self.assertRaises(ValueError): result = check_for_duplicates(
check_for_duplicates( [
[ Alias("gc", "git commit", Path("git.zsh")),
Alias("gc", "git clone", Path("git.zsh")),
]
)
self.assertListEqual(
result,
[
Collision(
Alias("gc", "git commit", Path("git.zsh")), Alias("gc", "git commit", Path("git.zsh")),
Alias("gc", "git clone", Path("git.zsh")), Alias("gc", "git clone", Path("git.zsh")),
] )
) ],
)