From 8fc3e7d975fb6c0f9b544cfd654f0fd2ce3c5073 Mon Sep 17 00:00:00 2001 From: lijunnzhang Date: Thu, 27 Jun 2024 16:06:26 +0800 Subject: [PATCH] refactor: imporve git proxy - add define file - support more prompt mode --- pigit/git/_cmds.py | 68 +++++++++-------------------------- pigit/git/define.py | 34 ++++++++++++++++++ pigit/git/proxy.py | 88 +++++++++++++++++++++++++++------------------ 3 files changed, 104 insertions(+), 86 deletions(-) create mode 100644 pigit/git/define.py diff --git a/pigit/git/_cmds.py b/pigit/git/_cmds.py index 025a2b4..98afc26 100644 --- a/pigit/git/_cmds.py +++ b/pigit/git/_cmds.py @@ -20,44 +20,10 @@ } """ -import enum -from typing import Callable, Dict, List, Union, Tuple, TypedDict - +from .define import GitCommandType, GitProxyOptionsGroup from ._cmd_func import * -@enum.unique -class GitCommandType(enum.Enum): - Branch = "Branch" - Commit = "Commit" - Conflict = "Conflict" - Fetch = "Fetch" - Index = "Index" - Log = "Log" - Merge = "Merge" - Push = "Push" - Remote = "Remote" - Stash = "Stash" - Tag = "Tag" - WorkingTree = "Working tree" - Submodule = "Submodule" - Setting = "Setting" - Extra = "Extra" # default - - -GitCommand = Union[str, Callable[[Union[List, Tuple]], None]] - - -class GitProxyOptions(TypedDict): - belong: GitCommandType - command: GitCommand - help: str - has_arguments: bool - - -GitProxyOptionsGroup = Dict[str, GitProxyOptions] - - # The custom git output format string. # git ... --pretty={0}.format(GIT_PRINT_FORMAT) _GIT_PRINT_FORMAT = ( @@ -66,8 +32,8 @@ class GitProxyOptions(TypedDict): '%C(bold)Commit: %C(blue)%cn <%ce> %C(reset)%C(cyan)%ci (%cr)%C(reset)%n%+B"' ) +# Branch(b) _branch_group: GitProxyOptionsGroup = { - # Branch "b": { "belong": GitCommandType.Branch, "command": "git branch", @@ -121,8 +87,8 @@ class GitProxyOptions(TypedDict): }, } +# Commit(c) _commit_group: GitProxyOptionsGroup = { - # Commit "c": { "belong": GitCommandType.Commit, "command": "git commit --verbose", @@ -186,8 +152,8 @@ class GitProxyOptions(TypedDict): }, } +# Conflict(C) _conflict_group: GitProxyOptionsGroup = { - # Conflict(C) "Cl": { "belong": GitCommandType.Conflict, "command": "git --no-pager diff --diff-filter=U --name-only", @@ -226,8 +192,8 @@ class GitProxyOptions(TypedDict): }, } +# Fetch(f) _fetch_group: GitProxyOptionsGroup = { - # Fetch(f) "f": { "belong": GitCommandType.Fetch, "command": "git fetch", @@ -272,8 +238,8 @@ class GitProxyOptions(TypedDict): }, } +# Index(i) _index_group: GitProxyOptionsGroup = { - # Index(i) "ia": { "belong": GitCommandType.Index, "command": add, @@ -330,8 +296,8 @@ class GitProxyOptions(TypedDict): }, } +# Log(l) _log_group: GitProxyOptionsGroup = { - # Log(l) "l": { "belong": GitCommandType.Log, "command": "git log --graph --all --decorate", @@ -370,8 +336,8 @@ class GitProxyOptions(TypedDict): }, } +# Merge(m) _merge_group: GitProxyOptionsGroup = { - # Merge(m) "m": { "belong": GitCommandType.Merge, "command": "git merge", @@ -418,8 +384,8 @@ class GitProxyOptions(TypedDict): }, } +# Push(p) _push_group: GitProxyOptionsGroup = { - # Push(p) "p": { "belong": GitCommandType.Push, "command": "git push", @@ -468,8 +434,8 @@ class GitProxyOptions(TypedDict): }, } +# Remote(R) _remote_group: GitProxyOptionsGroup = { - # Remote(R) "R": { "belong": GitCommandType.Remote, "command": "git remote", @@ -526,8 +492,8 @@ class GitProxyOptions(TypedDict): }, } -_stash_group: GitProxyOptionsGroup = { - # Stash(s) +# Stash(s) +_stash_group: GitProxyOptionsGroup = { "s": { "belong": GitCommandType.Stash, "command": "git stash", @@ -558,8 +524,8 @@ class GitProxyOptions(TypedDict): }, } +# Tag (t) _tag_group: GitProxyOptionsGroup = { - # Tag (t) "t": { "belong": GitCommandType.Tag, "command": "git tag", @@ -580,8 +546,8 @@ class GitProxyOptions(TypedDict): }, } +# Working tree(w) _working_tree_group: GitProxyOptionsGroup = { - # Working tree(w) "ws": { "belong": GitCommandType.WorkingTree, "command": "git status --short", @@ -657,8 +623,8 @@ class GitProxyOptions(TypedDict): }, } +# Submodule(S) _submodule_group: GitProxyOptionsGroup = { - # Submodule "Sc": { "belong": GitCommandType.Submodule, "command": "git clone --recursive", @@ -694,7 +660,7 @@ class GitProxyOptions(TypedDict): }, } -Git_Proxy_Cmds: Dict[str, GitProxyOptions] = { +Git_Proxy_Cmds: GitProxyOptionsGroup = { **_branch_group, **_commit_group, **_conflict_group, @@ -733,4 +699,4 @@ class GitProxyOptions(TypedDict): "help": "set user email.", "has_arguments": True, }, -} # type: dict[str,dict] +} diff --git a/pigit/git/define.py b/pigit/git/define.py new file mode 100644 index 0000000..252430a --- /dev/null +++ b/pigit/git/define.py @@ -0,0 +1,34 @@ +import enum +from typing import Callable, Dict, List, Tuple, TypedDict, Union + + +@enum.unique +class GitCommandType(enum.Enum): + Branch = "Branch" + Commit = "Commit" + Conflict = "Conflict" + Fetch = "Fetch" + Index = "Index" + Log = "Log" + Merge = "Merge" + Push = "Push" + Remote = "Remote" + Stash = "Stash" + Tag = "Tag" + WorkingTree = "Working tree" + Submodule = "Submodule" + Setting = "Setting" + Extra = "Extra" # default + + +GitCommand = Union[str, Callable[[Union[List, Tuple]], None]] + + +class GitProxyOptions(TypedDict): + belong: GitCommandType + command: GitCommand + help: str + has_arguments: bool + + +GitProxyOptionsGroup = Dict[str, GitProxyOptions] diff --git a/pigit/git/proxy.py b/pigit/git/proxy.py index a9336bf..6eb3ed7 100644 --- a/pigit/git/proxy.py +++ b/pigit/git/proxy.py @@ -12,39 +12,9 @@ from ._cmds import Git_Proxy_Cmds, GitCommandType -def get_extra_cmds(name: str, path: str) -> Dict: - """Get custom cmds. - - Load the `extra_cmds.py` file under PIGIT HOME, check whether `extra_cmds` - exists, and return it. If not have, return a empty dict. +PROMPT_WITH_TIPS = 1 # Prompt for possible commands and try again - Returns: - (dict[str,str]): extra cmds dict. - """ - import importlib.util - - extra_cmds = {} - - if os.path.isfile(path): - try: - # load a module form location. - spec = importlib.util.spec_from_file_location(name, path) - if spec is None: - raise ValueError("spec is None") - if spec.loader is None: - raise ValueError("spec.loader is None") - - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - except Exception: - logger(__name__).error(traceback_info(f"Can't load file '{path}'.")) - else: - try: - extra_cmds = module.extra_cmds # type: ignore - except AttributeError: - logger(__name__).error("Can't found dict name is 'extra_cmds'.") - - return extra_cmds +PROMPT_WITH_SAME_OUT = 2 # Output all possible command information that class GitProxy: @@ -54,9 +24,11 @@ def __init__( self, extra_cmds: Optional[dict] = None, prompt: bool = True, + prompt_type: int = PROMPT_WITH_SAME_OUT, display: bool = True, ) -> None: self.prompt = prompt + self.prompt_type = prompt_type self.display = display self.executor = Executor() @@ -163,9 +135,20 @@ def do(self, short_cmd: str, args: Optional[Union[List, Tuple]] = None) -> str: code, msg = self.process_command(short_cmd, args) if code == 1 and self.prompt: # check config. - predicted_command = similar_command(short_cmd, self.cmds.keys()) - if confirm(f":TIPS: The wanted command is `{predicted_command}`?[y/n]:"): - return self.do(predicted_command, args=args) + if self.prompt_type == PROMPT_WITH_TIPS: + predicted_command = similar_command(short_cmd, self.cmds.keys()) + if confirm(f":TIPS: The wanted command is `{predicted_command}`?[y/n]:"): + return self.do(predicted_command, args=args) + elif self.prompt_type == PROMPT_WITH_SAME_OUT: + msgs = [msg, "These are maybe you want:"] + + for key in self.cmds.keys(): + if not key.startswith(short_cmd): + continue + msg = self.generate_help_by_key(key) + msgs.append(msg) + + return "\n".join(msgs) return msg @@ -275,3 +258,38 @@ def get_types(cls) -> str: msgs.append(f"`{member.value}`<{color_str}>") return " ".join(msgs) + + +def get_extra_cmds(name: str, path: str) -> Dict: + """Get custom cmds. + + Load the `extra_cmds.py` file under PIGIT HOME, check whether `extra_cmds` + exists, and return it. If not have, return a empty dict. + + Returns: + (dict[str,str]): extra cmds dict. + """ + import importlib.util + + extra_cmds = {} + + if os.path.isfile(path): + try: + # load a module form location. + spec = importlib.util.spec_from_file_location(name, path) + if spec is None: + raise ValueError("spec is None") + if spec.loader is None: + raise ValueError("spec.loader is None") + + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + except Exception: + logger(__name__).error(traceback_info(f"Can't load file '{path}'.")) + else: + try: + extra_cmds = module.extra_cmds # type: ignore + except AttributeError: + logger(__name__).error("Can't found dict name is 'extra_cmds'.") + + return extra_cmds