gitbolt 0.0.0.dev10__tar.gz → 0.0.0.dev12__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.dev10 → gitbolt-0.0.0.dev12}/PKG-INFO +22 -3
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/README.md +19 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/pyproject.toml +4 -4
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/__init__.py +2 -1
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/base.py +23 -7
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/base.py +66 -8
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/impl/simple.py +109 -18
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/ls_tree.py +30 -8
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt.egg-info/PKG-INFO +22 -3
- gitbolt-0.0.0.dev12/src/gitbolt.egg-info/requires.txt +8 -0
- gitbolt-0.0.0.dev10/src/gitbolt.egg-info/requires.txt +0 -8
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/LICENSE +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/setup.cfg +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/_internal_init.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/add.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/constants.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/exceptions.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/__init__.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/_internal_init.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/add.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/constants.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/exceptions.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/impl/__init__.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/runner/__init__.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/runner/base.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/runner/simple_impl.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/utils.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/ls_tree.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/models.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/py.typed +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/pytest_plugin.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/utils.py +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt.egg-info/SOURCES.txt +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt.egg-info/dependency_links.txt +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt.egg-info/entry_points.txt +0 -0
- {gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitbolt
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev12
|
|
4
4
|
Summary: Fast, flexible and type-safe Git commands in Python.
|
|
5
5
|
Author-email: Suhas Krishna Srivastava <suhas.srivastava@vaastav.tech>
|
|
6
6
|
Maintainer-email: Suhas Krishna Srivastava <suhas.srivastava@vaastav.tech>
|
|
@@ -26,8 +26,8 @@ Classifier: Typing :: Typed
|
|
|
26
26
|
Requires-Python: >=3.12
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
|
-
Requires-Dist: vt-err-hndlr>=0.0.
|
|
30
|
-
Requires-Dist: vt-commons>=0.0.1.
|
|
29
|
+
Requires-Dist: vt-err-hndlr>=0.0.0dev5
|
|
30
|
+
Requires-Dist: vt-commons>=0.0.1.dev9
|
|
31
31
|
Provides-Extra: pygit2
|
|
32
32
|
Requires-Dist: pygit2; extra == "pygit2"
|
|
33
33
|
Provides-Extra: test
|
|
@@ -64,6 +64,7 @@ Dynamic: license-file
|
|
|
64
64
|
* 🧪 **Terminal Functions:** Git subcommands are terminal functions.
|
|
65
65
|
* 🧼 **Idiomatic Python:** Write commands in idiomatic Python at compile-time and be confident they’ll execute smoothly at runtime.
|
|
66
66
|
* 🎀 **Add-ons:** Special features provided to ease programming with git. These can be added if required.
|
|
67
|
+
* 💻 **CLI-cmd:** Take commands from cli and run in `gitbolt`.
|
|
67
68
|
|
|
68
69
|
---
|
|
69
70
|
|
|
@@ -340,6 +341,24 @@ git.subcmd_unchecked.run(['--version']) # run the version option for git.
|
|
|
340
341
|
git.subcmd_unchecked.run(['version']) # run the version subcommand.
|
|
341
342
|
```
|
|
342
343
|
|
|
344
|
+
#### 💻 Run commands received from CLI
|
|
345
|
+
|
|
346
|
+
Introduced in `0.0.0dev11` is the ability to take commands from CLI and run it inside `gitbolt`.
|
|
347
|
+
|
|
348
|
+
While making a system it may be required to run cli commands as received from cli using gitbolt. An obvious example
|
|
349
|
+
would be to make a system that receives CLI commands and does certain modifications/additions inside `gitbolt` before
|
|
350
|
+
actually running them. An example:
|
|
351
|
+
|
|
352
|
+
```python
|
|
353
|
+
from gitbolt.git_subprocess.impl.simple import CLISimpleGitCommand
|
|
354
|
+
|
|
355
|
+
opts = ["--no-pager", "--namespace", "n1"] # options received from outside your program.
|
|
356
|
+
envs = dict(GIT_AUTHOR_NAME="ss") # env-vars received form outside your program.
|
|
357
|
+
git = CLISimpleGitCommand(opts=opts, envs=envs)
|
|
358
|
+
|
|
359
|
+
# these can later be overridden
|
|
360
|
+
git = git.git_opts_override(namespace="n2")
|
|
361
|
+
```
|
|
343
362
|
|
|
344
363
|
---
|
|
345
364
|
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
* 🧪 **Terminal Functions:** Git subcommands are terminal functions.
|
|
29
29
|
* 🧼 **Idiomatic Python:** Write commands in idiomatic Python at compile-time and be confident they’ll execute smoothly at runtime.
|
|
30
30
|
* 🎀 **Add-ons:** Special features provided to ease programming with git. These can be added if required.
|
|
31
|
+
* 💻 **CLI-cmd:** Take commands from cli and run in `gitbolt`.
|
|
31
32
|
|
|
32
33
|
---
|
|
33
34
|
|
|
@@ -304,6 +305,24 @@ git.subcmd_unchecked.run(['--version']) # run the version option for git.
|
|
|
304
305
|
git.subcmd_unchecked.run(['version']) # run the version subcommand.
|
|
305
306
|
```
|
|
306
307
|
|
|
308
|
+
#### 💻 Run commands received from CLI
|
|
309
|
+
|
|
310
|
+
Introduced in `0.0.0dev11` is the ability to take commands from CLI and run it inside `gitbolt`.
|
|
311
|
+
|
|
312
|
+
While making a system it may be required to run cli commands as received from cli using gitbolt. An obvious example
|
|
313
|
+
would be to make a system that receives CLI commands and does certain modifications/additions inside `gitbolt` before
|
|
314
|
+
actually running them. An example:
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
from gitbolt.git_subprocess.impl.simple import CLISimpleGitCommand
|
|
318
|
+
|
|
319
|
+
opts = ["--no-pager", "--namespace", "n1"] # options received from outside your program.
|
|
320
|
+
envs = dict(GIT_AUTHOR_NAME="ss") # env-vars received form outside your program.
|
|
321
|
+
git = CLISimpleGitCommand(opts=opts, envs=envs)
|
|
322
|
+
|
|
323
|
+
# these can later be overridden
|
|
324
|
+
git = git.git_opts_override(namespace="n2")
|
|
325
|
+
```
|
|
307
326
|
|
|
308
327
|
---
|
|
309
328
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "gitbolt"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.0dev12"
|
|
4
4
|
description = "Fast, flexible and type-safe Git commands in Python."
|
|
5
5
|
requires-python = ">=3.12"
|
|
6
6
|
readme = "README.md"
|
|
@@ -36,8 +36,8 @@ classifiers = [
|
|
|
36
36
|
"Typing :: Typed"
|
|
37
37
|
]
|
|
38
38
|
dependencies = [
|
|
39
|
-
"vt-err-hndlr >= 0.0.
|
|
40
|
-
"vt-commons >= 0.0.1.
|
|
39
|
+
"vt-err-hndlr >= 0.0.0dev5",
|
|
40
|
+
"vt-commons >= 0.0.1.dev9",
|
|
41
41
|
]
|
|
42
42
|
|
|
43
43
|
[project.optional-dependencies]
|
|
@@ -49,7 +49,7 @@ test = ['pytest']
|
|
|
49
49
|
# btw, this error doesn't show in the latest developer version. So, this error will go away with 1.17.0 relase
|
|
50
50
|
dev = ["mypy==1.15.0", "ruff"]
|
|
51
51
|
doc = ['sphinx', 'sphinx-argparse']
|
|
52
|
-
test = ["pytest", 'pytest-cov']
|
|
52
|
+
test = ["pytest", 'pytest-cov', "pytest-xdist"]
|
|
53
53
|
multitest = ['tox']
|
|
54
54
|
|
|
55
55
|
|
|
@@ -23,6 +23,7 @@ from gitbolt.constants import GIT_DIR as GIT_DIR
|
|
|
23
23
|
# endregion
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
# TODO: check failing test on macos
|
|
26
27
|
def get_git(git_root_dir: Path = Path.cwd()) -> Git:
|
|
27
28
|
"""
|
|
28
29
|
Get operational and programmatic ``Git``.
|
|
@@ -34,7 +35,7 @@ def get_git(git_root_dir: Path = Path.cwd()) -> Git:
|
|
|
34
35
|
>>> import subprocess
|
|
35
36
|
>>> import gitbolt
|
|
36
37
|
>>> git = gitbolt.get_git()
|
|
37
|
-
>>> assert git.version == subprocess.run(['git', 'version'], capture_output=True, text=True).stdout.strip()
|
|
38
|
+
>>> assert git.version().version() == subprocess.run(['git', 'version'], capture_output=True, text=True).stdout.strip()
|
|
38
39
|
|
|
39
40
|
:param git_root_dir: Path to the git repo root directory. Defaults to current working directory.
|
|
40
41
|
"""
|
|
@@ -230,8 +230,29 @@ class Version(GitSubCommand, Protocol):
|
|
|
230
230
|
Interface for ``git version`` command.
|
|
231
231
|
"""
|
|
232
232
|
|
|
233
|
+
class VersionInfo:
|
|
234
|
+
@abstractmethod
|
|
235
|
+
def version(self) -> str: ...
|
|
236
|
+
|
|
237
|
+
@abstractmethod
|
|
238
|
+
def semver(self) -> tuple: ...
|
|
239
|
+
|
|
240
|
+
class VersionWithBuildInfo(VersionInfo):
|
|
241
|
+
@abstractmethod
|
|
242
|
+
def build_options(self) -> dict[str, str]: ...
|
|
243
|
+
|
|
244
|
+
@overload
|
|
245
|
+
@abstractmethod
|
|
246
|
+
def version(self) -> VersionInfo: ...
|
|
247
|
+
|
|
248
|
+
@overload
|
|
233
249
|
@abstractmethod
|
|
234
|
-
def version(self, build_options:
|
|
250
|
+
def version(self, build_options: Literal[True]) -> VersionWithBuildInfo: ...
|
|
251
|
+
|
|
252
|
+
@abstractmethod
|
|
253
|
+
def version(
|
|
254
|
+
self, build_options: Literal[True, False] = False
|
|
255
|
+
) -> VersionInfo | VersionWithBuildInfo:
|
|
235
256
|
"""
|
|
236
257
|
All the parameters are mirrors of the parameters of ``git version`` CLI command
|
|
237
258
|
from `git version documentation <https://git-scm.com/docs/git-version>`_.
|
|
@@ -276,14 +297,12 @@ class Git(CanOverrideGitOpts, CanOverrideGitEnvs, Protocol):
|
|
|
276
297
|
Class designed analogous to documentation provided on `git documentation <https://git-scm.com/docs/git>`_.
|
|
277
298
|
"""
|
|
278
299
|
|
|
279
|
-
|
|
280
|
-
def version(self) -> str:
|
|
300
|
+
def version(self) -> Version.VersionInfo:
|
|
281
301
|
"""
|
|
282
302
|
:return: current git version.
|
|
283
303
|
"""
|
|
284
304
|
return self.version_subcmd.version()
|
|
285
305
|
|
|
286
|
-
@property
|
|
287
306
|
@abstractmethod
|
|
288
307
|
def exec_path(self) -> Path:
|
|
289
308
|
"""
|
|
@@ -291,7 +310,6 @@ class Git(CanOverrideGitOpts, CanOverrideGitEnvs, Protocol):
|
|
|
291
310
|
"""
|
|
292
311
|
...
|
|
293
312
|
|
|
294
|
-
@property
|
|
295
313
|
@abstractmethod
|
|
296
314
|
def html_path(self) -> Path:
|
|
297
315
|
"""
|
|
@@ -299,7 +317,6 @@ class Git(CanOverrideGitOpts, CanOverrideGitEnvs, Protocol):
|
|
|
299
317
|
"""
|
|
300
318
|
...
|
|
301
319
|
|
|
302
|
-
@property
|
|
303
320
|
@abstractmethod
|
|
304
321
|
def info_path(self) -> Path:
|
|
305
322
|
"""
|
|
@@ -307,7 +324,6 @@ class Git(CanOverrideGitOpts, CanOverrideGitEnvs, Protocol):
|
|
|
307
324
|
"""
|
|
308
325
|
...
|
|
309
326
|
|
|
310
|
-
@property
|
|
311
327
|
@abstractmethod
|
|
312
328
|
def man_path(self) -> Path:
|
|
313
329
|
"""
|
|
@@ -8,14 +8,17 @@ Git command interfaces with default implementation using subprocess calls.
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
10
|
from abc import abstractmethod, ABC
|
|
11
|
+
from collections.abc import Callable
|
|
11
12
|
from pathlib import Path
|
|
12
13
|
from subprocess import CompletedProcess
|
|
13
14
|
from typing import override, Protocol, Unpack, Self, overload, Literal, Any
|
|
14
15
|
|
|
15
16
|
from vt.utils.commons.commons.core_py import is_unset, not_none_not_unset
|
|
16
17
|
from vt.utils.commons.commons.op import RootDirOp
|
|
18
|
+
from vt.utils.errors.error_specs import ERR_INVALID_USAGE
|
|
17
19
|
|
|
18
20
|
from gitbolt import Git, Version, LsTree, GitSubCommand, HasGitUnderneath, Add
|
|
21
|
+
from gitbolt.exceptions import GitExitingException
|
|
19
22
|
from gitbolt.git_subprocess.add import AddCLIArgsBuilder, IndividuallyOverridableACAB
|
|
20
23
|
from gitbolt.git_subprocess.ls_tree import (
|
|
21
24
|
LsTreeCLIArgsBuilder,
|
|
@@ -239,25 +242,21 @@ class GitCommand(Git, ABC):
|
|
|
239
242
|
# endregion
|
|
240
243
|
|
|
241
244
|
@override
|
|
242
|
-
@property
|
|
243
245
|
def html_path(self) -> Path:
|
|
244
246
|
html_path_str = "--html-path"
|
|
245
247
|
return self._get_path(html_path_str)
|
|
246
248
|
|
|
247
249
|
@override
|
|
248
|
-
@property
|
|
249
250
|
def info_path(self) -> Path:
|
|
250
251
|
info_path_str = "--info-path"
|
|
251
252
|
return self._get_path(info_path_str)
|
|
252
253
|
|
|
253
254
|
@override
|
|
254
|
-
@property
|
|
255
255
|
def man_path(self) -> Path:
|
|
256
256
|
man_path_str = "--man-path"
|
|
257
257
|
return self._get_path(man_path_str)
|
|
258
258
|
|
|
259
259
|
@override
|
|
260
|
-
@property
|
|
261
260
|
def exec_path(self) -> Path:
|
|
262
261
|
exec_path_str = "--exec-path"
|
|
263
262
|
return self._get_path(exec_path_str)
|
|
@@ -324,7 +323,66 @@ class GitSubcmdCommand(GitSubCommand, HasGitUnderneath["GitCommand"], Protocol):
|
|
|
324
323
|
|
|
325
324
|
|
|
326
325
|
class VersionCommand(Version, GitSubcmdCommand, Protocol):
|
|
327
|
-
|
|
326
|
+
class _Cache:
|
|
327
|
+
def __init__(self):
|
|
328
|
+
self.version = None
|
|
329
|
+
self.semver = None
|
|
330
|
+
self.build_options = None
|
|
331
|
+
|
|
332
|
+
class VersionInfoForCmd(Version.VersionInfo):
|
|
333
|
+
def __init__(self, rosetta_supplier: Callable[[], str]):
|
|
334
|
+
self.rosetta_supplier = rosetta_supplier
|
|
335
|
+
self.rosetta: str | None = None
|
|
336
|
+
self._cache = VersionCommand._Cache()
|
|
337
|
+
|
|
338
|
+
@override
|
|
339
|
+
def version(self) -> str:
|
|
340
|
+
if self.rosetta is None:
|
|
341
|
+
self.rosetta = self.rosetta_supplier()
|
|
342
|
+
if self._cache.version is not None:
|
|
343
|
+
return self._cache.version
|
|
344
|
+
v_str = self.rosetta.splitlines()[0]
|
|
345
|
+
self._cache.version = v_str
|
|
346
|
+
return v_str
|
|
347
|
+
|
|
348
|
+
@override
|
|
349
|
+
def semver(self) -> tuple:
|
|
350
|
+
if self._cache.semver is not None:
|
|
351
|
+
return self._cache.semver
|
|
352
|
+
t_ver = self.version().split()[-1].split(".")
|
|
353
|
+
return tuple(t_ver)
|
|
354
|
+
|
|
355
|
+
@override
|
|
356
|
+
def __str__(self):
|
|
357
|
+
if self.rosetta is None:
|
|
358
|
+
self.rosetta = self.rosetta_supplier()
|
|
359
|
+
return self.rosetta
|
|
360
|
+
|
|
361
|
+
class VersionWithBuildInfoForCmd(VersionInfoForCmd, Version.VersionWithBuildInfo):
|
|
362
|
+
def __init__(
|
|
363
|
+
self, rosetta_supplier: Callable[[], str], splitter_expr: str = ": "
|
|
364
|
+
):
|
|
365
|
+
super().__init__(rosetta_supplier)
|
|
366
|
+
self.splitter_expr = splitter_expr
|
|
367
|
+
|
|
368
|
+
@override
|
|
369
|
+
def build_options(self) -> dict[str, str]:
|
|
370
|
+
if self.rosetta is None:
|
|
371
|
+
self.rosetta = self.rosetta_supplier()
|
|
372
|
+
if self._cache.build_options is not None:
|
|
373
|
+
return self._cache.build_options
|
|
374
|
+
if not self.rosetta.splitlines()[1:]:
|
|
375
|
+
errmsg = "Unable to populate build_options as possibly --build-options switch wasn't used."
|
|
376
|
+
raise GitExitingException(
|
|
377
|
+
errmsg, exit_code=ERR_INVALID_USAGE
|
|
378
|
+
) from ValueError(errmsg)
|
|
379
|
+
|
|
380
|
+
self._cache.build_options = {}
|
|
381
|
+
for b_str in self.rosetta.splitlines()[1:]:
|
|
382
|
+
if self.splitter_expr in b_str:
|
|
383
|
+
b_k, b_v = b_str.split(self.splitter_expr)
|
|
384
|
+
self._cache.build_options[b_k] = b_v
|
|
385
|
+
return self._cache.build_options
|
|
328
386
|
|
|
329
387
|
|
|
330
388
|
class LsTreeCommand(LsTree, GitSubcmdCommand, Protocol):
|
|
@@ -525,9 +583,9 @@ class UncheckedSubcmd(GitSubcmdCommand, RootDirOp, Protocol):
|
|
|
525
583
|
another_supplied_env = subprocess_run_kwargs.pop("env", None)
|
|
526
584
|
if another_supplied_env:
|
|
527
585
|
envs_vars.update(another_supplied_env)
|
|
528
|
-
cwd = subprocess_run_kwargs.pop("cwd",
|
|
529
|
-
capture_output = subprocess_run_kwargs.pop("capture_output",
|
|
530
|
-
check = subprocess_run_kwargs.pop("check",
|
|
586
|
+
cwd = subprocess_run_kwargs.pop("cwd", self.root_dir)
|
|
587
|
+
capture_output = subprocess_run_kwargs.pop("capture_output", True)
|
|
588
|
+
check = subprocess_run_kwargs.pop("check", True)
|
|
531
589
|
# Run the git command
|
|
532
590
|
result = self.underlying_git.runner.run_git_command(
|
|
533
591
|
main_cmd_args,
|
|
@@ -9,10 +9,11 @@ from __future__ import annotations
|
|
|
9
9
|
|
|
10
10
|
from abc import ABC
|
|
11
11
|
from pathlib import Path
|
|
12
|
-
from typing import override
|
|
12
|
+
from typing import override, Literal, overload
|
|
13
13
|
|
|
14
14
|
from vt.utils.commons.commons.op import RootDirOp
|
|
15
15
|
|
|
16
|
+
from gitbolt.base import Version
|
|
16
17
|
from gitbolt.add import AddArgsValidator
|
|
17
18
|
from gitbolt.git_subprocess import (
|
|
18
19
|
GitCommand,
|
|
@@ -43,22 +44,36 @@ class GitSubcmdCommandImpl(GitSubcmdCommand, ABC):
|
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
class VersionCommandImpl(VersionCommand, GitSubcmdCommandImpl):
|
|
47
|
+
@overload
|
|
48
|
+
def version(self) -> Version.VersionInfo: ...
|
|
49
|
+
|
|
50
|
+
@overload
|
|
51
|
+
def version(self, build_options: Literal[True]) -> Version.VersionWithBuildInfo: ...
|
|
52
|
+
|
|
46
53
|
@override
|
|
47
|
-
def version(
|
|
54
|
+
def version(
|
|
55
|
+
self, build_options: Literal[True, False] = False
|
|
56
|
+
) -> Version.VersionInfo | Version.VersionWithBuildInfo:
|
|
48
57
|
self._require_valid_args(build_options)
|
|
49
58
|
main_cmd_args = self.underlying_git.build_main_cmd_args()
|
|
50
59
|
sub_cmd_args = [VERSION_CMD]
|
|
51
60
|
env_vars = self.underlying_git.build_git_envs()
|
|
52
61
|
if build_options:
|
|
53
62
|
sub_cmd_args.append("--build-options")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
|
|
64
|
+
def rosetta_supplier():
|
|
65
|
+
return self.underlying_git.runner.run_git_command(
|
|
66
|
+
main_cmd_args,
|
|
67
|
+
sub_cmd_args,
|
|
68
|
+
check=True,
|
|
69
|
+
text=True,
|
|
70
|
+
capture_output=True,
|
|
71
|
+
env=env_vars,
|
|
72
|
+
).stdout.strip()
|
|
73
|
+
|
|
74
|
+
if build_options:
|
|
75
|
+
return VersionCommand.VersionWithBuildInfoForCmd(rosetta_supplier)
|
|
76
|
+
return VersionCommand.VersionInfoForCmd(rosetta_supplier)
|
|
62
77
|
|
|
63
78
|
def clone(self) -> "VersionCommandImpl":
|
|
64
79
|
return VersionCommandImpl(self.underlying_git)
|
|
@@ -196,9 +211,21 @@ class SimpleGitCommand(GitCommand, RootDirOp):
|
|
|
196
211
|
return add_subcmd
|
|
197
212
|
|
|
198
213
|
@override
|
|
199
|
-
def clone(self) ->
|
|
214
|
+
def clone(self) -> SimpleGitCommand:
|
|
200
215
|
# region obtain class instance
|
|
201
|
-
cloned =
|
|
216
|
+
cloned = self._subclass_clone()
|
|
217
|
+
# endregion
|
|
218
|
+
# region clone protected members
|
|
219
|
+
cloned._main_cmd_opts = self._main_cmd_opts
|
|
220
|
+
cloned._env_vars = self._env_vars
|
|
221
|
+
# endregion
|
|
222
|
+
return cloned
|
|
223
|
+
|
|
224
|
+
def _subclass_clone(self) -> SimpleGitCommand:
|
|
225
|
+
"""
|
|
226
|
+
:returns: clone as defined by the subclass.
|
|
227
|
+
"""
|
|
228
|
+
return SimpleGitCommand(
|
|
202
229
|
self.root_dir,
|
|
203
230
|
self.runner,
|
|
204
231
|
version_subcmd=self.version_subcmd,
|
|
@@ -206,12 +233,6 @@ class SimpleGitCommand(GitCommand, RootDirOp):
|
|
|
206
233
|
add_subcmd=self.add_subcmd,
|
|
207
234
|
subcmd_unchecked=self.subcmd_unchecked,
|
|
208
235
|
)
|
|
209
|
-
# endregion
|
|
210
|
-
# region clone protected members
|
|
211
|
-
cloned._main_cmd_opts = self._main_cmd_opts
|
|
212
|
-
cloned._env_vars = self._env_vars
|
|
213
|
-
# endregion
|
|
214
|
-
return cloned
|
|
215
236
|
|
|
216
237
|
@override
|
|
217
238
|
@property
|
|
@@ -223,3 +244,73 @@ class SimpleGitCommand(GitCommand, RootDirOp):
|
|
|
223
244
|
subcmd_unchecked = self._subcmd_unchecked.clone()
|
|
224
245
|
subcmd_unchecked._set_underlying_git(self)
|
|
225
246
|
return subcmd_unchecked
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class CLISimpleGitCommand(SimpleGitCommand):
|
|
250
|
+
"""
|
|
251
|
+
A simple git command that can run using CLI params.
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
def __init__(
|
|
255
|
+
self,
|
|
256
|
+
git_root_dir: Path = Path.cwd(),
|
|
257
|
+
runner: GitCommandRunner = SimpleGitCR(),
|
|
258
|
+
*,
|
|
259
|
+
opts: list[str] | None = None,
|
|
260
|
+
envs: dict[str, str] | None = None,
|
|
261
|
+
prefer_cli: bool = False,
|
|
262
|
+
version_subcmd: VersionCommand | None = None,
|
|
263
|
+
ls_tree_subcmd: LsTreeCommand | None = None,
|
|
264
|
+
add_subcmd: AddCommand | None = None,
|
|
265
|
+
subcmd_unchecked: UncheckedSubcmd | None = None,
|
|
266
|
+
):
|
|
267
|
+
"""
|
|
268
|
+
:param opts: main git cli options.
|
|
269
|
+
:param envs: main git cli env vars.
|
|
270
|
+
:param prefer_cli: cli opts and envs will be given priority over programmatically set opts and envs. Setting
|
|
271
|
+
this param to ``True`` will make cli opts and envs appear later in the opts and envs strings which will
|
|
272
|
+
make them override previously programmatically set opts and envs.
|
|
273
|
+
"""
|
|
274
|
+
super().__init__(
|
|
275
|
+
git_root_dir,
|
|
276
|
+
runner,
|
|
277
|
+
version_subcmd=version_subcmd,
|
|
278
|
+
ls_tree_subcmd=ls_tree_subcmd,
|
|
279
|
+
add_subcmd=add_subcmd,
|
|
280
|
+
subcmd_unchecked=subcmd_unchecked,
|
|
281
|
+
)
|
|
282
|
+
self._main_cmd_cli_opts = opts
|
|
283
|
+
self._cmd_cli_envs = envs
|
|
284
|
+
self.prefer_cli = prefer_cli
|
|
285
|
+
|
|
286
|
+
@override
|
|
287
|
+
def build_main_cmd_args(self) -> list[str]:
|
|
288
|
+
if self._main_cmd_cli_opts:
|
|
289
|
+
if self.prefer_cli:
|
|
290
|
+
return super().build_main_cmd_args() + self._main_cmd_cli_opts
|
|
291
|
+
else:
|
|
292
|
+
return self._main_cmd_cli_opts + super().build_main_cmd_args()
|
|
293
|
+
return super().build_main_cmd_args()
|
|
294
|
+
|
|
295
|
+
@override
|
|
296
|
+
def build_git_envs(self) -> dict[str, str]:
|
|
297
|
+
if self._cmd_cli_envs:
|
|
298
|
+
if self.prefer_cli:
|
|
299
|
+
return super().build_git_envs() | self._cmd_cli_envs
|
|
300
|
+
else:
|
|
301
|
+
return self._cmd_cli_envs | super().build_git_envs()
|
|
302
|
+
return super().build_git_envs()
|
|
303
|
+
|
|
304
|
+
@override
|
|
305
|
+
def _subclass_clone(self) -> CLISimpleGitCommand:
|
|
306
|
+
return CLISimpleGitCommand(
|
|
307
|
+
self.root_dir,
|
|
308
|
+
self.runner,
|
|
309
|
+
opts=self._main_cmd_cli_opts,
|
|
310
|
+
envs=self._cmd_cli_envs,
|
|
311
|
+
prefer_cli=self.prefer_cli,
|
|
312
|
+
version_subcmd=self.version_subcmd,
|
|
313
|
+
ls_tree_subcmd=self.ls_tree_subcmd,
|
|
314
|
+
add_subcmd=self.add_subcmd,
|
|
315
|
+
subcmd_unchecked=self.subcmd_unchecked,
|
|
316
|
+
)
|
|
@@ -108,9 +108,25 @@ class IndividuallyOverridableLTCAB(LsTreeCLIArgsBuilder):
|
|
|
108
108
|
* With --format::
|
|
109
109
|
|
|
110
110
|
>>> builder.build("HEAD", format_="%(objectname)")
|
|
111
|
-
['ls-tree', '--format
|
|
111
|
+
['ls-tree', '--format', '%(objectname)', 'HEAD']
|
|
112
|
+
|
|
112
113
|
>>> builder.build("HEAD", format_="")
|
|
113
|
-
['ls-tree', '--format
|
|
114
|
+
['ls-tree', '--format', '', 'HEAD']
|
|
115
|
+
|
|
116
|
+
>>> builder.build("HEAD", format_="''")
|
|
117
|
+
['ls-tree', '--format', "''", 'HEAD']
|
|
118
|
+
|
|
119
|
+
>>> builder.build("HEAD", format_='""')
|
|
120
|
+
['ls-tree', '--format', '""', 'HEAD']
|
|
121
|
+
|
|
122
|
+
>>> builder.build("HEAD", format_="%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)")
|
|
123
|
+
['ls-tree', '--format', '%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)', 'HEAD']
|
|
124
|
+
|
|
125
|
+
>>> builder.build("HEAD", format_="'%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)'")
|
|
126
|
+
['ls-tree', '--format', "'%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)'", 'HEAD']
|
|
127
|
+
|
|
128
|
+
>>> builder.build("HEAD", format_='"%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)"')
|
|
129
|
+
['ls-tree', '--format', '"%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)"', 'HEAD']
|
|
114
130
|
|
|
115
131
|
* With paths::
|
|
116
132
|
|
|
@@ -140,7 +156,7 @@ class IndividuallyOverridableLTCAB(LsTreeCLIArgsBuilder):
|
|
|
140
156
|
... format_="%(objectname) %(path)",
|
|
141
157
|
... path=["dir1", "dir2/file.txt"]
|
|
142
158
|
... )
|
|
143
|
-
['ls-tree', '-d', '-r', '-t', '-l', '-z', '--name-only', '--object-only', '--full-name', '--full-tree', '--abbrev=10', '--format
|
|
159
|
+
['ls-tree', '-d', '-r', '-t', '-l', '-z', '--name-only', '--object-only', '--full-name', '--full-tree', '--abbrev=10', '--format', '%(objectname) %(path)', 'HEAD', 'dir1', 'dir2/file.txt']
|
|
144
160
|
|
|
145
161
|
* Empty or falsy values, mostly will fail at validation::
|
|
146
162
|
|
|
@@ -344,11 +360,17 @@ class IndividuallyOverridableLTCAB(LsTreeCLIArgsBuilder):
|
|
|
344
360
|
>>> IndividuallyOverridableLTCAB().format_arg(None)
|
|
345
361
|
[]
|
|
346
362
|
>>> IndividuallyOverridableLTCAB().format_arg('%(objectname)')
|
|
347
|
-
['--format
|
|
348
|
-
>>> IndividuallyOverridableLTCAB().format_arg('')
|
|
349
|
-
['--format
|
|
350
|
-
""
|
|
351
|
-
|
|
363
|
+
['--format', '%(objectname)']
|
|
364
|
+
>>> IndividuallyOverridableLTCAB().format_arg('""')
|
|
365
|
+
['--format', '""']
|
|
366
|
+
>>> IndividuallyOverridableLTCAB().format_arg("''")
|
|
367
|
+
['--format', "''"]
|
|
368
|
+
>>> IndividuallyOverridableLTCAB().format_arg('%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)')
|
|
369
|
+
['--format', '%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)']
|
|
370
|
+
>>> IndividuallyOverridableLTCAB().format_arg('"%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)"')
|
|
371
|
+
['--format', '"%(objectmode) %(objecttype) %(objectname) %(objectsize:padded)%x09%(path)"']
|
|
372
|
+
"""
|
|
373
|
+
return ["--format", _format] if _format is not None else []
|
|
352
374
|
|
|
353
375
|
def tree_ish_arg(self, tree_ish: str) -> list[str]:
|
|
354
376
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitbolt
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev12
|
|
4
4
|
Summary: Fast, flexible and type-safe Git commands in Python.
|
|
5
5
|
Author-email: Suhas Krishna Srivastava <suhas.srivastava@vaastav.tech>
|
|
6
6
|
Maintainer-email: Suhas Krishna Srivastava <suhas.srivastava@vaastav.tech>
|
|
@@ -26,8 +26,8 @@ Classifier: Typing :: Typed
|
|
|
26
26
|
Requires-Python: >=3.12
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
|
-
Requires-Dist: vt-err-hndlr>=0.0.
|
|
30
|
-
Requires-Dist: vt-commons>=0.0.1.
|
|
29
|
+
Requires-Dist: vt-err-hndlr>=0.0.0dev5
|
|
30
|
+
Requires-Dist: vt-commons>=0.0.1.dev9
|
|
31
31
|
Provides-Extra: pygit2
|
|
32
32
|
Requires-Dist: pygit2; extra == "pygit2"
|
|
33
33
|
Provides-Extra: test
|
|
@@ -64,6 +64,7 @@ Dynamic: license-file
|
|
|
64
64
|
* 🧪 **Terminal Functions:** Git subcommands are terminal functions.
|
|
65
65
|
* 🧼 **Idiomatic Python:** Write commands in idiomatic Python at compile-time and be confident they’ll execute smoothly at runtime.
|
|
66
66
|
* 🎀 **Add-ons:** Special features provided to ease programming with git. These can be added if required.
|
|
67
|
+
* 💻 **CLI-cmd:** Take commands from cli and run in `gitbolt`.
|
|
67
68
|
|
|
68
69
|
---
|
|
69
70
|
|
|
@@ -340,6 +341,24 @@ git.subcmd_unchecked.run(['--version']) # run the version option for git.
|
|
|
340
341
|
git.subcmd_unchecked.run(['version']) # run the version subcommand.
|
|
341
342
|
```
|
|
342
343
|
|
|
344
|
+
#### 💻 Run commands received from CLI
|
|
345
|
+
|
|
346
|
+
Introduced in `0.0.0dev11` is the ability to take commands from CLI and run it inside `gitbolt`.
|
|
347
|
+
|
|
348
|
+
While making a system it may be required to run cli commands as received from cli using gitbolt. An obvious example
|
|
349
|
+
would be to make a system that receives CLI commands and does certain modifications/additions inside `gitbolt` before
|
|
350
|
+
actually running them. An example:
|
|
351
|
+
|
|
352
|
+
```python
|
|
353
|
+
from gitbolt.git_subprocess.impl.simple import CLISimpleGitCommand
|
|
354
|
+
|
|
355
|
+
opts = ["--no-pager", "--namespace", "n1"] # options received from outside your program.
|
|
356
|
+
envs = dict(GIT_AUTHOR_NAME="ss") # env-vars received form outside your program.
|
|
357
|
+
git = CLISimpleGitCommand(opts=opts, envs=envs)
|
|
358
|
+
|
|
359
|
+
# these can later be overridden
|
|
360
|
+
git = git.git_opts_override(namespace="n2")
|
|
361
|
+
```
|
|
343
362
|
|
|
344
363
|
---
|
|
345
364
|
|
|
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
|
{gitbolt-0.0.0.dev10 → gitbolt-0.0.0.dev12}/src/gitbolt/git_subprocess/runner/simple_impl.py
RENAMED
|
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
|