Skip to content

Commit

Permalink
refactor: imporve git proxy
Browse files Browse the repository at this point in the history
- add define file
- support more prompt mode
  • Loading branch information
lijunnzhang committed Jun 27, 2024
1 parent 544078d commit 8fc3e7d
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 86 deletions.
68 changes: 17 additions & 51 deletions pigit/git/_cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = (
Expand All @@ -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",
Expand Down Expand Up @@ -121,8 +87,8 @@ class GitProxyOptions(TypedDict):
},
}

# Commit(c)
_commit_group: GitProxyOptionsGroup = {
# Commit
"c": {
"belong": GitCommandType.Commit,
"command": "git commit --verbose",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -226,8 +192,8 @@ class GitProxyOptions(TypedDict):
},
}

# Fetch(f)
_fetch_group: GitProxyOptionsGroup = {
# Fetch(f)
"f": {
"belong": GitCommandType.Fetch,
"command": "git fetch",
Expand Down Expand Up @@ -272,8 +238,8 @@ class GitProxyOptions(TypedDict):
},
}

# Index(i)
_index_group: GitProxyOptionsGroup = {
# Index(i)
"ia": {
"belong": GitCommandType.Index,
"command": add,
Expand Down Expand Up @@ -330,8 +296,8 @@ class GitProxyOptions(TypedDict):
},
}

# Log(l)
_log_group: GitProxyOptionsGroup = {
# Log(l)
"l": {
"belong": GitCommandType.Log,
"command": "git log --graph --all --decorate",
Expand Down Expand Up @@ -370,8 +336,8 @@ class GitProxyOptions(TypedDict):
},
}

# Merge(m)
_merge_group: GitProxyOptionsGroup = {
# Merge(m)
"m": {
"belong": GitCommandType.Merge,
"command": "git merge",
Expand Down Expand Up @@ -418,8 +384,8 @@ class GitProxyOptions(TypedDict):
},
}

# Push(p)
_push_group: GitProxyOptionsGroup = {
# Push(p)
"p": {
"belong": GitCommandType.Push,
"command": "git push",
Expand Down Expand Up @@ -468,8 +434,8 @@ class GitProxyOptions(TypedDict):
},
}

# Remote(R)
_remote_group: GitProxyOptionsGroup = {
# Remote(R)
"R": {
"belong": GitCommandType.Remote,
"command": "git remote",
Expand Down Expand Up @@ -526,8 +492,8 @@ class GitProxyOptions(TypedDict):
},
}

_stash_group: GitProxyOptionsGroup = {
# Stash(s)
# Stash(s)
_stash_group: GitProxyOptionsGroup = {
"s": {
"belong": GitCommandType.Stash,
"command": "git stash",
Expand Down Expand Up @@ -558,8 +524,8 @@ class GitProxyOptions(TypedDict):
},
}

# Tag (t)
_tag_group: GitProxyOptionsGroup = {
# Tag (t)
"t": {
"belong": GitCommandType.Tag,
"command": "git tag",
Expand All @@ -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",
Expand Down Expand Up @@ -657,8 +623,8 @@ class GitProxyOptions(TypedDict):
},
}

# Submodule(S)
_submodule_group: GitProxyOptionsGroup = {
# Submodule
"Sc": {
"belong": GitCommandType.Submodule,
"command": "git clone --recursive",
Expand Down Expand Up @@ -694,7 +660,7 @@ class GitProxyOptions(TypedDict):
},
}

Git_Proxy_Cmds: Dict[str, GitProxyOptions] = {
Git_Proxy_Cmds: GitProxyOptionsGroup = {
**_branch_group,
**_commit_group,
**_conflict_group,
Expand Down Expand Up @@ -733,4 +699,4 @@ class GitProxyOptions(TypedDict):
"help": "set user email.",
"has_arguments": True,
},
} # type: dict[str,dict]
}
34 changes: 34 additions & 0 deletions pigit/git/define.py
Original file line number Diff line number Diff line change
@@ -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]
88 changes: 53 additions & 35 deletions pigit/git/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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()
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

0 comments on commit 8fc3e7d

Please sign in to comment.