diff --git a/tools/alias_collision/check_alias_collision.py b/tools/alias_collision/check_alias_collision.py index 9da18112d..785824ca3 100644 --- a/tools/alias_collision/check_alias_collision.py +++ b/tools/alias_collision/check_alias_collision.py @@ -2,54 +2,19 @@ from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser from pathlib import Path -from dataclasses import dataclass +from dataclasses import dataclass, asdict from typing import List, Dict import itertools import re +import json ERROR_MESSAGE_TEMPLATE = ( "Alias `%s` defined in `%s` already exists as alias `%s` in `%s`." ) -# TODO: We want that list to be empty -KNOWN_COLLISIONS = [ - "bcubc", - "pbl", - "gcd", - "h", - "brs", - "github", - "stackoverflow", - "zcl", - "afs", - "allpkgs", - "mydeb", - "jh", - "n", - "a", - "p", - "sf", - "sp", - "hs", - "db", - "rn", - "rs", - "ru", - "sc", - "sd", - "sd", - "sp", - "c", - "dr", - "rake", - "rubies", - "h", - "ma", - "map", - "mis", - "m", -] +# TODO: We want that list to be empty and get rid of this file +KNOWN_COLLISIONS = Path(__file__).resolve().parent / "known_collisions.json" def dir_path(path_string: str) -> Path: @@ -69,6 +34,12 @@ def parse_arguments(): type=dir_path, help="Folder to check", ) + parser.add_argument( + "--known-collisions", + type=Path, + default=KNOWN_COLLISIONS, + help="Json-serialized list of known collisions", + ) return parser.parse_args() @@ -86,8 +57,15 @@ class Collision: existing_alias: Alias new_alias: Alias - def is_new_collision(self, known_collisions: List[str]) -> bool: - return self.new_alias.alias not in known_collisions + def is_new_collision(self, known_collision_aliases: List[str]) -> bool: + return self.new_alias.alias not in known_collision_aliases + + @classmethod + def from_dict(cls, collision_dict: Dict) -> "Collision": + return cls( + Alias(**collision_dict["existing_alias"]), + Alias(**collision_dict["new_alias"]), + ) def find_aliases_in_file(file: Path) -> List[Alias]: @@ -95,6 +73,11 @@ def find_aliases_in_file(file: Path) -> List[Alias]: return [Alias(match[0], match[1], file) for match in matches] +def load_known_collisions(collision_file: Path) -> List[Collision]: + collision_list = json.loads(collision_file.read_text()) + return [Collision.from_dict(collision_dict) for collision_dict in collision_list] + + def find_all_aliases(path: Path) -> list: aliases = [find_aliases_in_file(file) for file in path.rglob("*.zsh")] return list(itertools.chain(*aliases)) @@ -130,19 +113,26 @@ def print_collisions(collisions: Dict[Alias, Alias]) -> None: print("Found no collisions") -def main(): +def main() -> int: """main""" args = parse_arguments() aliases = find_all_aliases(args.folder) collisions = check_for_duplicates(aliases) + + known_collisions = load_known_collisions(args.known_collisions) + known_collision_aliases = [ + collision.new_alias.alias for collision in known_collisions + ] + new_collisions = [ collision for collision in collisions - if collision.is_new_collision(KNOWN_COLLISIONS) + if collision.is_new_collision(known_collision_aliases) ] + print_collisions(new_collisions) - return -1 if collisions else 0 + return -1 if new_collisions else 0 if __name__ == "__main__": - main() + exit(main()) diff --git a/tools/alias_collision/known_collisions.json b/tools/alias_collision/known_collisions.json new file mode 100644 index 000000000..d8c5f3903 --- /dev/null +++ b/tools/alias_collision/known_collisions.json @@ -0,0 +1,422 @@ +[ + { + "existing_alias": { + "alias": "bcubc", + "value": "brew upgrade --cask && brew cleanup", + "module": "plugins/brew/brew.plugin.zsh" + }, + "new_alias": { + "alias": "bcubc", + "value": "brew upgrade --cask && brew cleanup", + "module": "plugins/brew/brew.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "pbl", + "value": "podman build", + "module": "plugins/podman/podman.plugin.zsh" + }, + "new_alias": { + "alias": "pbl", + "value": "perlbrew list", + "module": "plugins/perl/perl.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "gcd", + "value": "git checkout $(git_develop_branch)", + "module": "plugins/git/git.plugin.zsh" + }, + "new_alias": { + "alias": "gcd", + "value": "git checkout $(git config gitflow.branch.develop)", + "module": "plugins/git-flow/git-flow.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "h", + "value": "history", + "module": "plugins/history/history.plugin.zsh" + }, + "new_alias": { + "alias": "h", + "value": "history", + "module": "plugins/common-aliases/common-aliases.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "brs", + "value": "bin/bridgetown start", + "module": "plugins/bridgetown/bridgetown.plugin.zsh" + }, + "new_alias": { + "alias": "brs", + "value": "web_search brave", + "module": "plugins/web-search/web-search.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "github", + "value": "frontend github", + "module": "plugins/frontend-search/frontend-search.plugin.zsh" + }, + "new_alias": { + "alias": "github", + "value": "web_search github", + "module": "plugins/web-search/web-search.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "stackoverflow", + "value": "frontend stackoverflow", + "module": "plugins/frontend-search/frontend-search.plugin.zsh" + }, + "new_alias": { + "alias": "stackoverflow", + "value": "web_search stackoverflow", + "module": "plugins/web-search/web-search.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "zcl", + "value": "sudo zypper clean", + "module": "plugins/suse/suse.plugin.zsh" + }, + "new_alias": { + "alias": "zcl", + "value": "sudo zypper cl", + "module": "plugins/suse/suse.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "afs", + "value": "apt-file search --regexp", + "module": "plugins/ubuntu/ubuntu.plugin.zsh" + }, + "new_alias": { + "alias": "afs", + "value": "apt-file search --regexp", + "module": "plugins/debian/debian.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "allpkgs", + "value": "dpkg --get-selections | grep -v deinstall", + "module": "plugins/ubuntu/ubuntu.plugin.zsh" + }, + "new_alias": { + "alias": "allpkgs", + "value": "aptitude search -F \"%p\" --disable-columns ~i", + "module": "plugins/debian/debian.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "mydeb", + "value": "time dpkg-buildpackage -rfakeroot -us -uc", + "module": "plugins/ubuntu/ubuntu.plugin.zsh" + }, + "new_alias": { + "alias": "mydeb", + "value": "time dpkg-buildpackage -rfakeroot -us -uc", + "module": "plugins/debian/debian.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "jh", + "value": "juju help", + "module": "plugins/juju/juju.plugin.zsh" + }, + "new_alias": { + "alias": "jh", + "value": "jhbuild", + "module": "plugins/jhbuild/jhbuild.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "n", + "value": "nanoc", + "module": "plugins/nanoc/nanoc.plugin.zsh" + }, + "new_alias": { + "alias": "n", + "value": "\"$GREP\" -Rvi", + "module": "plugins/singlechar/singlechar.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "a", + "value": "ansible ", + "module": "plugins/ansible/ansible.plugin.zsh" + }, + "new_alias": { + "alias": "a", + "value": "echo >>", + "module": "plugins/singlechar/singlechar.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "p", + "value": "ps -f", + "module": "plugins/common-aliases/common-aliases.plugin.zsh" + }, + "new_alias": { + "alias": "p", + "value": "\"$PAGER\"", + "module": "plugins/singlechar/singlechar.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "sf", + "value": "`_symfony_console`", + "module": "plugins/symfony2/symfony2.plugin.zsh" + }, + "new_alias": { + "alias": "sf", + "value": "\"$ROOT\" \"$GREP\" -Rli", + "module": "plugins/singlechar/singlechar.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "sp", + "value": "web_search startpage", + "module": "plugins/web-search/web-search.plugin.zsh" + }, + "new_alias": { + "alias": "sp", + "value": "\"$ROOT\" \"$PAGER\"", + "module": "plugins/singlechar/singlechar.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "hs", + "value": "history | grep", + "module": "plugins/history/history.plugin.zsh" + }, + "new_alias": { + "alias": "hs", + "value": "hanami server", + "module": "plugins/hanami/hanami.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "db", + "value": "deno bundle", + "module": "plugins/deno/deno.plugin.zsh" + }, + "new_alias": { + "alias": "db", + "value": "dotnet build", + "module": "plugins/dotnet/dotnet.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "rn", + "value": "react-native", + "module": "plugins/react-native/react-native.plugin.zsh" + }, + "new_alias": { + "alias": "rn", + "value": "rails notes", + "module": "plugins/rails/rails.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "rs", + "value": "repo sync", + "module": "plugins/repo/repo.plugin.zsh" + }, + "new_alias": { + "alias": "rs", + "value": "rails server", + "module": "plugins/rails/rails.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "ru", + "value": "repo upload", + "module": "plugins/repo/repo.plugin.zsh" + }, + "new_alias": { + "alias": "ru", + "value": "rails runner", + "module": "plugins/rails/rails.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "sc", + "value": "\"$ROOT\" cat", + "module": "plugins/singlechar/singlechar.plugin.zsh" + }, + "new_alias": { + "alias": "sc", + "value": "ruby script/console", + "module": "plugins/rails/rails.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "sd", + "value": "\"$ROOT\" \"$WGET\"", + "module": "plugins/singlechar/singlechar.plugin.zsh" + }, + "new_alias": { + "alias": "sd", + "value": "ruby script/destroy", + "module": "plugins/rails/rails.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "sd", + "value": "\"$ROOT\" \"$WGET\"", + "module": "plugins/singlechar/singlechar.plugin.zsh" + }, + "new_alias": { + "alias": "sd", + "value": "ruby script/server --debugger", + "module": "plugins/rails/rails.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "sp", + "value": "web_search startpage", + "module": "plugins/web-search/web-search.plugin.zsh" + }, + "new_alias": { + "alias": "sp", + "value": "ruby script/plugin", + "module": "plugins/rails/rails.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "c", + "value": "cat", + "module": "plugins/singlechar/singlechar.plugin.zsh" + }, + "new_alias": { + "alias": "c", + "value": "composer", + "module": "plugins/composer/composer.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "dr", + "value": "dotnet run", + "module": "plugins/dotnet/dotnet.plugin.zsh" + }, + "new_alias": { + "alias": "dr", + "value": "docker container run", + "module": "plugins/docker/docker.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "rake", + "value": "_rake_command", + "module": "plugins/rails/rails.plugin.zsh" + }, + "new_alias": { + "alias": "rake", + "value": "noglob rake", + "module": "plugins/rake/rake.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "rubies", + "value": "rvm list rubies", + "module": "plugins/rvm/rvm.plugin.zsh" + }, + "new_alias": { + "alias": "rubies", + "value": "chruby", + "module": "plugins/chruby/chruby.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "h", + "value": "history", + "module": "plugins/history/history.plugin.zsh" + }, + "new_alias": { + "alias": "h", + "value": "helm", + "module": "plugins/helm/helm.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "ma", + "value": "mongocli atlas", + "module": "plugins/mongocli/mongocli.plugin.zsh" + }, + "new_alias": { + "alias": "ma", + "value": "meteor add", + "module": "plugins/meteor/meteor.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "map", + "value": "web_search duckduckgo \\!m", + "module": "plugins/web-search/web-search.plugin.zsh" + }, + "new_alias": { + "alias": "map", + "value": "meteor add-platform", + "module": "plugins/meteor/meteor.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "mis", + "value": "microk8s.istio", + "module": "plugins/microk8s/microk8s.plugin.zsh" + }, + "new_alias": { + "alias": "mis", + "value": "meteor install-sdk", + "module": "plugins/meteor/meteor.plugin.zsh" + } + }, + { + "existing_alias": { + "alias": "m", + "value": "man", + "module": "plugins/singlechar/singlechar.plugin.zsh" + }, + "new_alias": { + "alias": "m", + "value": "meteor run", + "module": "plugins/meteor/meteor.plugin.zsh" + } + } +] diff --git a/tools/alias_collision/tests/test_check_alias_collision.py b/tools/alias_collision/tests/test_check_alias_collision.py index 57ca17ed2..c6a3802ee 100644 --- a/tools/alias_collision/tests/test_check_alias_collision.py +++ b/tools/alias_collision/tests/test_check_alias_collision.py @@ -10,6 +10,7 @@ from check_alias_collision import ( check_for_duplicates, Alias, Collision, + load_known_collisions, ) @@ -26,6 +27,23 @@ is-at-least 2.8 "$git_version" \ || alias gfa='git fetch --all --prune' """ +ONE_KNOWN_COLLISION = """ +[ + { + "existing_alias": { + "alias": "gcd", + "value": "git checkout $(git_develop_branch)", + "module": "plugins/git/git.plugin.zsh" + }, + "new_alias": { + "alias": "gcd", + "value": "git checkout $(git config gitflow.branch.develop)", + "module": "plugins/git-flow/git-flow.plugin.zsh" + } + } +] +""" + def test_dir_path__is_dir__input_path(fs: FakeFilesystem) -> None: fs.create_dir("test") @@ -127,3 +145,22 @@ def test_is_new_collision__new_alias_in_known_collisions__should_return_false() new_alias = Alias("ga", "git add", Path("git.zsh")) collision = Collision(Alias("gd", "git diff", Path("git.zsh")), new_alias) assert collision.is_new_collision(known_collisions) is False + + +def test_load_known_collisions__empty_file__should_return_empty_list( + fs: FakeFilesystem, +) -> None: + empty_list = Path("empty.json") + fs.create_file(empty_list, contents="[]") + result = load_known_collisions(empty_list) + assert [] == result + + +def test_load_known_collisions__one_collision__should_return_one_collision( + fs: FakeFilesystem, +) -> None: + known_collisions_file = Path("known_collisions.json") + fs.create_file(known_collisions_file, contents=ONE_KNOWN_COLLISION) + result = load_known_collisions(known_collisions_file) + assert 1 == len(result) + assert "gcd" == result[0].existing_alias.alias