gitbolt 0.0.0.dev25__tar.gz → 0.0.0.dev27__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/PKG-INFO +2 -2
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/pyproject.toml +3 -2
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/base.py +45 -34
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/utils/session.py +20 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/utils.py +45 -9
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt.egg-info/PKG-INFO +2 -2
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/LICENSE +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/README.md +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/setup.cfg +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/__init__.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/_internal_init.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/add.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/base.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/constants.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/exceptions.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/ls_tree.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/models.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/py.typed +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/pytest_plugin.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/__init__.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/_internal_init.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/add.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/constants.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/exceptions.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/impl/__init__.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/impl/simple.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/ls_tree.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/runner/__init__.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/runner/base.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/runner/simple.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/utils/__init__.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/utils/main_cmd.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/utils/models.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt/subprocess/worktree.py +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt.egg-info/SOURCES.txt +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt.egg-info/dependency_links.txt +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt.egg-info/entry_points.txt +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt.egg-info/requires.txt +0 -0
- {gitbolt-0.0.0.dev25 → gitbolt-0.0.0.dev27}/src/gitbolt.egg-info/top_level.txt +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitbolt
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev27
|
|
4
4
|
Summary: Fast, flexible and type-safe Git commands in Python.
|
|
5
|
-
Author-email: Suhas Krishna Srivastava <suhas.srivastava@vaastav.tech>
|
|
5
|
+
Author-email: Suhas Krishna Srivastava <suhas.srivastava@vaastav.tech>, Thamotharan R <thamotharan.r@vaastav.tech>
|
|
6
6
|
Maintainer-email: Suhas Krishna Srivastava <suhas.srivastava@vaastav.tech>
|
|
7
7
|
License-Expression: Apache-2.0
|
|
8
8
|
Project-URL: homepage, https://github.com/Vaastav-Technologies/py-gitbolt
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "gitbolt"
|
|
3
|
-
version = "0.0.0.
|
|
3
|
+
version = "0.0.0.dev27"
|
|
4
4
|
description = "Fast, flexible and type-safe Git commands in Python."
|
|
5
5
|
requires-python = ">=3.12"
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
authors = [
|
|
8
|
-
{name = "Suhas Krishna Srivastava", email = "suhas.srivastava@vaastav.tech"}
|
|
8
|
+
{name = "Suhas Krishna Srivastava", email = "suhas.srivastava@vaastav.tech"},
|
|
9
|
+
{name = "Thamotharan R", email = "thamotharan.r@vaastav.tech"}
|
|
9
10
|
]
|
|
10
11
|
maintainers = [
|
|
11
12
|
{name = "Suhas Krishna Srivastava", email = "suhas.srivastava@vaastav.tech"}
|
|
@@ -35,6 +35,7 @@ from gitbolt.models import GitOpts, GitLsTreeOpts, GitAddOpts, GitEnvVars
|
|
|
35
35
|
from gitbolt.subprocess.worktree import WorktreeCLIArgsBuilder
|
|
36
36
|
from gitbolt.utils import merge_git_opts, merge_git_envs
|
|
37
37
|
from gitbolt.subprocess.constants import GIT_CMD, VERSION_CMD, LS_TREE_CMD, ADD_CMD, WORKTREE_CMD, WORKTREE_ADD_CMD
|
|
38
|
+
from gitbolt.subprocess.utils.session import _close_session_popen
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
class GitCommand(Git, ABC):
|
|
@@ -50,6 +51,28 @@ class GitCommand(Git, ABC):
|
|
|
50
51
|
self._main_cmd_opts: GitOpts = {}
|
|
51
52
|
self._env_vars: GitEnvVars | None = None
|
|
52
53
|
self._cmd_str_repr: str | None = None
|
|
54
|
+
self._main_cmd_opt_builders: dict[str, Callable[[], list[str]]] = {
|
|
55
|
+
"C": self._main_cmd_cap_c_args,
|
|
56
|
+
"c": self._main_cmd_small_c_args,
|
|
57
|
+
"config_env": self._main_cmd_config_env_args,
|
|
58
|
+
"exec_path": self._main_cmd_exec_path_args,
|
|
59
|
+
"paginate": self._main_cmd_paginate_args,
|
|
60
|
+
"no_pager": self._main_cmd_no_pager_args,
|
|
61
|
+
"git_dir": self._main_cmd_git_dir_args,
|
|
62
|
+
"work_tree": self._main_cmd_work_tree_args,
|
|
63
|
+
"namespace": self._main_cmd_namespace_args,
|
|
64
|
+
"bare": self._main_cmd_bare_args,
|
|
65
|
+
"no_replace_objects": self._main_cmd_no_replace_objects_args,
|
|
66
|
+
"no_lazy_fetch": self._main_cmd_no_lazy_fetch_args,
|
|
67
|
+
"no_optional_locks": self._main_cmd_no_optional_locks_args,
|
|
68
|
+
"no_advice": self._main_cmd_no_advice_args,
|
|
69
|
+
"literal_pathspecs": self._main_cmd_literal_pathspecs_args,
|
|
70
|
+
"glob_pathspecs": self._main_cmd_glob_pathspecs_args,
|
|
71
|
+
"noglob_pathspecs": self._main_cmd_noglob_pathspecs_args,
|
|
72
|
+
"icase_pathspecs": self._main_cmd_icase_pathspecs_args,
|
|
73
|
+
"list_cmds": self._main_cmd_list_cmds_args,
|
|
74
|
+
"attr_source": self._main_cmd_attr_source_args,
|
|
75
|
+
}
|
|
53
76
|
|
|
54
77
|
@override
|
|
55
78
|
def __str__(self) -> str:
|
|
@@ -65,7 +88,7 @@ class GitCommand(Git, ABC):
|
|
|
65
88
|
|
|
66
89
|
>>> _b_git = _a_git.git_opts_override(C=[Path("a"), Path("b")], no_advice=True, no_replace_objects=True)
|
|
67
90
|
>>> assert str(_a_git) == GIT_CMD # _a_git never changed
|
|
68
|
-
>>> assert str(_b_git) == f"{GIT_CMD} -C a -C b --no-
|
|
91
|
+
>>> assert str(_b_git) == f"{GIT_CMD} -C a -C b --no-advice --no-replace-objects"
|
|
69
92
|
|
|
70
93
|
Adding git envs:
|
|
71
94
|
|
|
@@ -74,7 +97,7 @@ class GitCommand(Git, ABC):
|
|
|
74
97
|
>>> assert str(_c_git) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD}"
|
|
75
98
|
|
|
76
99
|
>>> _d_git = _c_git.git_opts_override(C=[Path("a"), Path("b")], no_advice=True, no_replace_objects=True, config_env=dict(conf1="val1", glob1="val2"))
|
|
77
|
-
>>> assert str(_d_git) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} -C a -C b --config-env conf1=val1 --config-env glob1=val2
|
|
100
|
+
>>> assert str(_d_git) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} -C a -C b --no-advice --no-replace-objects --config-env conf1=val1 --config-env glob1=val2"
|
|
78
101
|
|
|
79
102
|
Does not affect repr:
|
|
80
103
|
|
|
@@ -127,28 +150,14 @@ class GitCommand(Git, ABC):
|
|
|
127
150
|
|
|
128
151
|
:return: CLI args for git main cli command.
|
|
129
152
|
"""
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
+ self._main_cmd_work_tree_args()
|
|
139
|
-
+ self._main_cmd_namespace_args()
|
|
140
|
-
+ self._main_cmd_bare_args()
|
|
141
|
-
+ self._main_cmd_no_replace_objects_args()
|
|
142
|
-
+ self._main_cmd_no_lazy_fetch_args()
|
|
143
|
-
+ self._main_cmd_no_optional_locks_args()
|
|
144
|
-
+ self._main_cmd_no_advice_args()
|
|
145
|
-
+ self._main_cmd_literal_pathspecs_args()
|
|
146
|
-
+ self._main_cmd_glob_pathspecs_args()
|
|
147
|
-
+ self._main_cmd_noglob_pathspecs_args()
|
|
148
|
-
+ self._main_cmd_icase_pathspecs_args()
|
|
149
|
-
+ self._main_cmd_list_cmds_args()
|
|
150
|
-
+ self._main_cmd_attr_source_args()
|
|
151
|
-
)
|
|
153
|
+
args: list[str] = []
|
|
154
|
+
for opt_key in self._main_cmd_opts:
|
|
155
|
+
args.extend(self._main_cmd_args_for_opt_key(opt_key))
|
|
156
|
+
return args
|
|
157
|
+
|
|
158
|
+
def _main_cmd_args_for_opt_key(self, opt_key: str) -> list[str]:
|
|
159
|
+
builder = self._main_cmd_opt_builders.get(opt_key)
|
|
160
|
+
return builder() if builder else []
|
|
152
161
|
|
|
153
162
|
@override
|
|
154
163
|
def git_opts_override(self, **overrides: Unpack[GitOpts]) -> Self:
|
|
@@ -504,7 +513,9 @@ class GitSession(HasGitUnderneath[GitCommand], AbstractContextManager):
|
|
|
504
513
|
self.started_commands[unstarted_command_key] = unstarted_command().__enter__()
|
|
505
514
|
except Exception:
|
|
506
515
|
for k in reversed(processes_started_keys):
|
|
507
|
-
|
|
516
|
+
_close_session_popen(
|
|
517
|
+
self.started_commands[k], *sys.exc_info()
|
|
518
|
+
)
|
|
508
519
|
raise
|
|
509
520
|
processes_started_keys.append(unstarted_command_key)
|
|
510
521
|
self._commands = SimpleNamespace(**self.started_commands)
|
|
@@ -524,7 +535,7 @@ class GitSession(HasGitUnderneath[GitCommand], AbstractContextManager):
|
|
|
524
535
|
if self.__depth == 0:
|
|
525
536
|
process_done_keys: list[str] = []
|
|
526
537
|
for started_popen_key, started_popen in self.started_commands.items():
|
|
527
|
-
started_popen
|
|
538
|
+
_close_session_popen(started_popen, exc_type, exc_value, traceback)
|
|
528
539
|
process_done_keys.append(started_popen_key)
|
|
529
540
|
self._commands = None
|
|
530
541
|
for pk in process_done_keys:
|
|
@@ -686,7 +697,7 @@ class VersionCommand(Version, GitSubcmdCommand, Protocol):
|
|
|
686
697
|
|
|
687
698
|
>>> _b_git = _a_git.git_opts_override(C=[Path("a"), Path("b")], no_advice=True, no_replace_objects=True)
|
|
688
699
|
>>> assert str(_a_git.version_subcmd()) == f"{GIT_CMD} {VERSION_CMD}" # _a_git never changed
|
|
689
|
-
>>> assert str(_b_git.version_subcmd()) == f"{GIT_CMD} -C a -C b --no-
|
|
700
|
+
>>> assert str(_b_git.version_subcmd()) == f"{GIT_CMD} -C a -C b --no-advice --no-replace-objects {VERSION_CMD}"
|
|
690
701
|
|
|
691
702
|
Adding git envs:
|
|
692
703
|
|
|
@@ -695,7 +706,7 @@ class VersionCommand(Version, GitSubcmdCommand, Protocol):
|
|
|
695
706
|
>>> assert str(_c_git.version_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} {VERSION_CMD}"
|
|
696
707
|
|
|
697
708
|
>>> _d_git = _c_git.git_opts_override(C=[Path("a"), Path("b")], no_advice=True, no_replace_objects=True, config_env=dict(conf1="val1", glob1="val2"))
|
|
698
|
-
>>> assert str(_d_git.version_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} -C a -C b --config-env conf1=val1 --config-env glob1=val2
|
|
709
|
+
>>> assert str(_d_git.version_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} -C a -C b --no-advice --no-replace-objects --config-env conf1=val1 --config-env glob1=val2 {VERSION_CMD}"
|
|
699
710
|
|
|
700
711
|
Does not affect repr:
|
|
701
712
|
|
|
@@ -756,7 +767,7 @@ class LsTreeCommand(LsTree, GitSubcmdCommand, Protocol):
|
|
|
756
767
|
|
|
757
768
|
>>> _b_git = _a_git.git_opts_override(C=[Path("a"), Path("b")], no_advice=True, no_replace_objects=True)
|
|
758
769
|
>>> assert str(_a_git.ls_tree_subcmd()) == f"{GIT_CMD} {LS_TREE_CMD}" # _a_git never changed
|
|
759
|
-
>>> assert str(_b_git.ls_tree_subcmd()) == f"{GIT_CMD} -C a -C b --no-
|
|
770
|
+
>>> assert str(_b_git.ls_tree_subcmd()) == f"{GIT_CMD} -C a -C b --no-advice --no-replace-objects {LS_TREE_CMD}"
|
|
760
771
|
|
|
761
772
|
Adding git envs:
|
|
762
773
|
|
|
@@ -765,7 +776,7 @@ class LsTreeCommand(LsTree, GitSubcmdCommand, Protocol):
|
|
|
765
776
|
>>> assert str(_c_git.ls_tree_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} {LS_TREE_CMD}"
|
|
766
777
|
|
|
767
778
|
>>> _d_git = _c_git.git_opts_override(C=[Path("a"), Path("b")], no_advice=True, no_replace_objects=True, config_env=dict(conf1="val1", glob1="val2"))
|
|
768
|
-
>>> assert str(_d_git.ls_tree_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} -C a -C b --config-env conf1=val1 --config-env glob1=val2
|
|
779
|
+
>>> assert str(_d_git.ls_tree_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} -C a -C b --no-advice --no-replace-objects --config-env conf1=val1 --config-env glob1=val2 {LS_TREE_CMD}"
|
|
769
780
|
|
|
770
781
|
Does not affect repr:
|
|
771
782
|
|
|
@@ -871,7 +882,7 @@ class AddCommand(Add, GitSubcmdCommand, Protocol):
|
|
|
871
882
|
|
|
872
883
|
>>> _b_git = _a_git.git_opts_override(C=[Path("a"), Path("b")], no_advice=True, no_replace_objects=True)
|
|
873
884
|
>>> assert str(_a_git.add_subcmd()) == f"{GIT_CMD} {ADD_CMD}" # _a_git never changed
|
|
874
|
-
>>> assert str(_b_git.add_subcmd()) == f"{GIT_CMD} -C a -C b --no-
|
|
885
|
+
>>> assert str(_b_git.add_subcmd()) == f"{GIT_CMD} -C a -C b --no-advice --no-replace-objects {ADD_CMD}"
|
|
875
886
|
|
|
876
887
|
Adding git envs:
|
|
877
888
|
|
|
@@ -880,7 +891,7 @@ class AddCommand(Add, GitSubcmdCommand, Protocol):
|
|
|
880
891
|
>>> assert str(_c_git.add_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} {ADD_CMD}"
|
|
881
892
|
|
|
882
893
|
>>> _d_git = _c_git.git_opts_override(C=[Path("a"), Path("b")], no_advice=True, no_replace_objects=True, config_env=dict(conf1="val1", glob1="val2"))
|
|
883
|
-
>>> assert str(_d_git.add_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} -C a -C b --config-env conf1=val1 --config-env glob1=val2
|
|
894
|
+
>>> assert str(_d_git.add_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} -C a -C b --no-advice --no-replace-objects --config-env conf1=val1 --config-env glob1=val2 {ADD_CMD}"
|
|
884
895
|
|
|
885
896
|
Does not affect repr:
|
|
886
897
|
|
|
@@ -1193,7 +1204,7 @@ class WorktreeCommand(Worktree, GitSubcmdCommand, abc.ABC):
|
|
|
1193
1204
|
|
|
1194
1205
|
>>> _b_git = _a_git.git_opts_override(C=[Path("a"), Path("b")], no_advice=True, no_replace_objects=True)
|
|
1195
1206
|
>>> assert str(_a_git.worktree_subcmd()) == f"{GIT_CMD} {WORKTREE_CMD}" # _a_git never changed
|
|
1196
|
-
>>> assert str(_b_git.worktree_subcmd()) == f"{GIT_CMD} -C a -C b --no-
|
|
1207
|
+
>>> assert str(_b_git.worktree_subcmd()) == f"{GIT_CMD} -C a -C b --no-advice --no-replace-objects {WORKTREE_CMD}"
|
|
1197
1208
|
|
|
1198
1209
|
Adding git envs:
|
|
1199
1210
|
|
|
@@ -1202,7 +1213,7 @@ class WorktreeCommand(Worktree, GitSubcmdCommand, abc.ABC):
|
|
|
1202
1213
|
>>> assert str(_c_git.worktree_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} {WORKTREE_CMD}"
|
|
1203
1214
|
|
|
1204
1215
|
>>> _d_git = _c_git.git_opts_override(C=[Path("a"), Path("b")], no_advice=True, no_replace_objects=True, config_env=dict(conf1="val1", glob1="val2"))
|
|
1205
|
-
>>> assert str(_d_git.worktree_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} -C a -C b --config-env conf1=val1 --config-env glob1=val2
|
|
1216
|
+
>>> assert str(_d_git.worktree_subcmd()) == f"GIT_ADVICE=False GIT_AUTHOR_NAME=Suhas GIT_PAGER=vi {GIT_CMD} -C a -C b --no-advice --no-replace-objects --config-env conf1=val1 --config-env glob1=val2 {WORKTREE_CMD}"
|
|
1206
1217
|
|
|
1207
1218
|
Does not affect repr:
|
|
1208
1219
|
|
|
@@ -8,6 +8,7 @@ Create sessions for long-running commands and communicate with them using their
|
|
|
8
8
|
|
|
9
9
|
Much faster that subprocess creation for each input/output pair.
|
|
10
10
|
"""
|
|
11
|
+
import errno
|
|
11
12
|
import subprocess
|
|
12
13
|
from typing import Iterable, IO, cast
|
|
13
14
|
|
|
@@ -18,6 +19,25 @@ from gitbolt.subprocess.utils.models import GitRawActor, GitRawSignature, GPGGit
|
|
|
18
19
|
RawCommitBytesObj, RawBytesValsOfCommit
|
|
19
20
|
|
|
20
21
|
|
|
22
|
+
def _close_session_popen(popen: subprocess.Popen[bytes], exc_type, exc_value, traceback) -> None:
|
|
23
|
+
"""
|
|
24
|
+
Close a session ``Popen`` and ignore a broken pipe.
|
|
25
|
+
|
|
26
|
+
A git process started with a bad command can exit before the session does. Closing its stdin
|
|
27
|
+
then raises ``BrokenPipeError`` (common on macOS) or a matching ``OSError``.
|
|
28
|
+
"""
|
|
29
|
+
try:
|
|
30
|
+
popen.__exit__(exc_type, exc_value, traceback)
|
|
31
|
+
except BrokenPipeError:
|
|
32
|
+
return
|
|
33
|
+
except OSError as err:
|
|
34
|
+
if err.errno in {errno.EPIPE, errno.ECONNRESET}:
|
|
35
|
+
return
|
|
36
|
+
if getattr(err, "winerror", None) in {109, 232}:
|
|
37
|
+
return
|
|
38
|
+
raise
|
|
39
|
+
|
|
40
|
+
|
|
21
41
|
# region blob
|
|
22
42
|
def cat_file_blob_content(
|
|
23
43
|
cat_file_popen: subprocess.Popen[bytes], blob_hash: bytes, require_type: bytes | None = None
|
|
@@ -7,6 +7,7 @@ Utility functions related to processors specific to git commands.
|
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
+
from vt.utils.commons.commons.core_py import is_unset
|
|
10
11
|
|
|
11
12
|
from gitbolt.models import GitOpts, GitEnvVars
|
|
12
13
|
|
|
@@ -86,7 +87,7 @@ def merge_git_opts(primary: GitOpts, fallback: GitOpts) -> GitOpts:
|
|
|
86
87
|
fallbacks on the corresponding property from the ``fallback`` ``GitOpts`` object if that corresponding property
|
|
87
88
|
is ``None`` in the ``primary`` ``GitOpts`` object.
|
|
88
89
|
"""
|
|
89
|
-
return merge_typed_dicts(primary, fallback, GitOpts)
|
|
90
|
+
return merge_typed_dicts(primary, fallback, GitOpts, omit_unset_keys=True)
|
|
90
91
|
|
|
91
92
|
|
|
92
93
|
def merge_git_envs(primary: GitEnvVars, fallback: GitEnvVars) -> GitEnvVars:
|
|
@@ -164,16 +165,51 @@ def merge_git_envs(primary: GitEnvVars, fallback: GitEnvVars) -> GitEnvVars:
|
|
|
164
165
|
fallbacks on the corresponding property from the ``fallback`` ``GitEnvVars`` object if that corresponding property
|
|
165
166
|
is explicitly ``None`` in the ``primary`` ``GitEnvVars`` object.
|
|
166
167
|
"""
|
|
167
|
-
return merge_typed_dicts(primary, fallback, GitEnvVars)
|
|
168
|
+
return merge_typed_dicts(primary, fallback, GitEnvVars, omit_unset_keys=False)
|
|
168
169
|
|
|
169
170
|
|
|
170
171
|
# TODO: check for typing this function
|
|
171
|
-
def merge_typed_dicts(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
def merge_typed_dicts(
|
|
173
|
+
primary, fallback, the_typed_dict, *, omit_unset_keys: bool = False
|
|
174
|
+
):
|
|
175
|
+
"""
|
|
176
|
+
Merge typed dicts preserving insertion order of ``fallback`` then new keys from ``primary``.
|
|
177
|
+
|
|
178
|
+
Value resolution matches the previous annotation-order merge: primary wins, ``None`` in primary
|
|
179
|
+
falls back, ``Unset`` is kept for env merges and omitted from opts when ``omit_unset_keys`` is True.
|
|
180
|
+
"""
|
|
181
|
+
valid_keys = frozenset(the_typed_dict.__annotations__.keys())
|
|
182
|
+
|
|
183
|
+
keys_order: list[str] = []
|
|
184
|
+
seen: set[str] = set()
|
|
185
|
+
for k in fallback:
|
|
186
|
+
if k in valid_keys and k not in seen:
|
|
187
|
+
keys_order.append(k)
|
|
188
|
+
seen.add(k)
|
|
189
|
+
for k in primary:
|
|
190
|
+
if k in valid_keys and k not in seen:
|
|
191
|
+
keys_order.append(k)
|
|
192
|
+
seen.add(k)
|
|
193
|
+
|
|
194
|
+
merged: dict = {}
|
|
195
|
+
for k in keys_order:
|
|
196
|
+
if k in primary and is_unset(primary[k]):
|
|
197
|
+
if omit_unset_keys:
|
|
198
|
+
continue
|
|
199
|
+
merged[k] = primary[k]
|
|
200
|
+
continue
|
|
201
|
+
|
|
202
|
+
if k in primary:
|
|
203
|
+
val = primary[k]
|
|
204
|
+
if val is None:
|
|
205
|
+
val = fallback.get(k)
|
|
206
|
+
else:
|
|
207
|
+
val = fallback.get(k)
|
|
208
|
+
|
|
175
209
|
if val is None:
|
|
176
|
-
|
|
177
|
-
if
|
|
178
|
-
|
|
210
|
+
continue
|
|
211
|
+
if omit_unset_keys and is_unset(val):
|
|
212
|
+
continue
|
|
213
|
+
merged[k] = val
|
|
214
|
+
|
|
179
215
|
return merged
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitbolt
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev27
|
|
4
4
|
Summary: Fast, flexible and type-safe Git commands in Python.
|
|
5
|
-
Author-email: Suhas Krishna Srivastava <suhas.srivastava@vaastav.tech>
|
|
5
|
+
Author-email: Suhas Krishna Srivastava <suhas.srivastava@vaastav.tech>, Thamotharan R <thamotharan.r@vaastav.tech>
|
|
6
6
|
Maintainer-email: Suhas Krishna Srivastava <suhas.srivastava@vaastav.tech>
|
|
7
7
|
License-Expression: Apache-2.0
|
|
8
8
|
Project-URL: homepage, https://github.com/Vaastav-Technologies/py-gitbolt
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|