gitman 3.5.3__tar.gz → 3.7__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.
- {gitman-3.5.3 → gitman-3.7}/PKG-INFO +4 -5
- {gitman-3.5.3 → gitman-3.7}/README.md +1 -1
- {gitman-3.5.3 → gitman-3.7}/gitman/cli.py +17 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/commands.py +15 -3
- {gitman-3.5.3 → gitman-3.7}/gitman/common.py +14 -14
- {gitman-3.5.3 → gitman-3.7}/gitman/exceptions.py +4 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/git.py +70 -7
- {gitman-3.5.3 → gitman-3.7}/gitman/models/config.py +48 -7
- {gitman-3.5.3 → gitman-3.7}/gitman/models/source.py +54 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/plugin.py +7 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/test_cli.py +15 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/test_plugin.py +5 -0
- {gitman-3.5.3 → gitman-3.7}/pyproject.toml +16 -11
- {gitman-3.5.3 → gitman-3.7}/LICENSE.md +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/__init__.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/__main__.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/decorators.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/hook-gitman.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/models/__init__.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/models/group.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/settings.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/shell.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/__init__.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/conftest.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/files/gdm-custom.yml +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/files/gdm-default.yml +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/files/gitman.yml +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/files/subdir/gitman.yml +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/files/subdir/subsubdir/gitman.yml +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/files/subdir/subsubdir/skip/subsubsubsubdir/gitman.yml +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/test_commands.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/test_common.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/test_git.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/test_models_config.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/test_models_group.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/test_models_source.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/test_shell.py +0 -0
- {gitman-3.5.3 → gitman-3.7}/gitman/tests/utils.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: gitman
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.7
|
|
4
4
|
Summary: A language-agnostic dependency manager using Git.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: git,version control,build systems,dependency management,submodules
|
|
7
7
|
Author: Jace Browning
|
|
8
8
|
Author-email: jacebrowning@gmail.com
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.9,<3.15
|
|
10
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
11
|
Classifier: Environment :: Console
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
@@ -15,7 +15,6 @@ Classifier: Natural Language :: English
|
|
|
15
15
|
Classifier: Operating System :: OS Independent
|
|
16
16
|
Classifier: Programming Language :: Python
|
|
17
17
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.9
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -27,7 +26,7 @@ Classifier: Topic :: Software Development :: Version Control
|
|
|
27
26
|
Classifier: Topic :: System :: Software Distribution
|
|
28
27
|
Requires-Dist: datafiles (>=2.3.1,<3.0.0)
|
|
29
28
|
Requires-Dist: minilog (>=2.3.1,<3.0.0)
|
|
30
|
-
Requires-Dist: universal-startfile (>=0.2,<0.
|
|
29
|
+
Requires-Dist: universal-startfile (>=0.2,<0.4)
|
|
31
30
|
Project-URL: Documentation, https://gitman.readthedocs.io
|
|
32
31
|
Project-URL: Homepage, https://pypi.org/project/gitman
|
|
33
32
|
Project-URL: Repository, https://github.com/jacebrowning/gitman
|
|
@@ -52,7 +51,7 @@ Gitman is a language-agnostic dependency manager using Git. It aims to serve as
|
|
|
52
51
|
|
|
53
52
|
### Requirements
|
|
54
53
|
|
|
55
|
-
- Python 3.
|
|
54
|
+
- Python 3.9+
|
|
56
55
|
- Git 2.8+ (with [stored credentials](http://gitman.readthedocs.io/en/latest/setup/git/))
|
|
57
56
|
|
|
58
57
|
### Installation
|
|
@@ -125,6 +125,13 @@ def main(args=None, function=None):
|
|
|
125
125
|
action="store_true",
|
|
126
126
|
dest="no_scripts",
|
|
127
127
|
)
|
|
128
|
+
sub.add_argument(
|
|
129
|
+
"-P",
|
|
130
|
+
"--no-patches",
|
|
131
|
+
help="skip patches after installation",
|
|
132
|
+
action="store_true",
|
|
133
|
+
dest="no_patches",
|
|
134
|
+
)
|
|
128
135
|
|
|
129
136
|
# Update parser
|
|
130
137
|
info = "update dependencies to the latest versions"
|
|
@@ -158,6 +165,13 @@ def main(args=None, function=None):
|
|
|
158
165
|
action="store_true",
|
|
159
166
|
dest="no_scripts",
|
|
160
167
|
)
|
|
168
|
+
sub.add_argument(
|
|
169
|
+
"-P",
|
|
170
|
+
"--no-patches",
|
|
171
|
+
help="skip patches after installation",
|
|
172
|
+
action="store_true",
|
|
173
|
+
dest="no_patches",
|
|
174
|
+
)
|
|
161
175
|
|
|
162
176
|
# List parser
|
|
163
177
|
info = "display the current version of each dependency"
|
|
@@ -277,6 +291,7 @@ def _get_command(function, namespace):
|
|
|
277
291
|
clean=namespace.clean,
|
|
278
292
|
skip_changes=namespace.skip_changes,
|
|
279
293
|
skip_scripts=namespace.no_scripts,
|
|
294
|
+
skip_patches=namespace.no_patches,
|
|
280
295
|
)
|
|
281
296
|
if namespace.command == "install":
|
|
282
297
|
kwargs.update(
|
|
@@ -350,6 +365,8 @@ def _run_command(function, args, kwargs):
|
|
|
350
365
|
except exceptions.ScriptFailure as exception:
|
|
351
366
|
_show_error(exception)
|
|
352
367
|
exit_message = "Run again with '--force' to ignore script errors"
|
|
368
|
+
except exceptions.PatchFailure as exception:
|
|
369
|
+
_show_error(exception)
|
|
353
370
|
except exceptions.InvalidConfig as exception:
|
|
354
371
|
_show_error(exception)
|
|
355
372
|
exit_message = "Adapt config and run again"
|
|
@@ -62,6 +62,7 @@ def install(
|
|
|
62
62
|
skip_changes=False,
|
|
63
63
|
skip_default_group=False,
|
|
64
64
|
skip_scripts=False,
|
|
65
|
+
skip_patches=False,
|
|
65
66
|
):
|
|
66
67
|
"""Install dependencies for a project.
|
|
67
68
|
|
|
@@ -70,10 +71,10 @@ def install(
|
|
|
70
71
|
- `*names`: optional list of dependency directory names to filter on
|
|
71
72
|
- `root`: specifies the path to the root working tree
|
|
72
73
|
- `depth`: number of levels of dependencies to traverse
|
|
73
|
-
- `force`: indicates uncommitted changes can be overwritten
|
|
74
|
-
script errors can be ignored
|
|
74
|
+
- `force`: indicates uncommitted changes can be overwritten,
|
|
75
|
+
script errors can be ignored and failed patches can be ignored
|
|
75
76
|
- `force_interactive`: indicates uncommitted changes can be interactively
|
|
76
|
-
overwritten
|
|
77
|
+
overwritten, script errors can be ignored and failed patches can be ignored
|
|
77
78
|
- `fetch`: indicates the latest branches should always be fetched
|
|
78
79
|
- `clean`: indicates untracked files should be deleted from dependencies
|
|
79
80
|
- `skip_changes`: indicates dependencies with uncommitted changes
|
|
@@ -81,6 +82,7 @@ def install(
|
|
|
81
82
|
- `skip_default_group`: indicates default_group should be skipped if
|
|
82
83
|
`*names` is empty
|
|
83
84
|
- `skip_scripts`: indicates scripts should be skipped
|
|
85
|
+
- `skip_patches`: indicates patches should be skipped
|
|
84
86
|
"""
|
|
85
87
|
log.info(
|
|
86
88
|
"%sInstalling dependencies: %s",
|
|
@@ -115,6 +117,10 @@ def install(
|
|
|
115
117
|
)
|
|
116
118
|
count += _count # type: ignore
|
|
117
119
|
|
|
120
|
+
if _count and not skip_patches:
|
|
121
|
+
common.show("Applying patches...", color="message", log=False)
|
|
122
|
+
common.newline()
|
|
123
|
+
config.apply_patches(*names, depth=depth, force=force)
|
|
118
124
|
if _count and not skip_scripts:
|
|
119
125
|
label = "nested scripts" if index else "scripts"
|
|
120
126
|
common.show(f"Running {label}...", color="message", log=False)
|
|
@@ -137,6 +143,7 @@ def update(
|
|
|
137
143
|
skip_changes=False,
|
|
138
144
|
skip_default_group=False,
|
|
139
145
|
skip_scripts=False,
|
|
146
|
+
skip_patches=False,
|
|
140
147
|
):
|
|
141
148
|
"""Update dependencies for a project.
|
|
142
149
|
|
|
@@ -157,6 +164,7 @@ def update(
|
|
|
157
164
|
- `skip_default_group`: indicates default_group should be skipped if
|
|
158
165
|
`*names` is empty
|
|
159
166
|
- `skip_scripts`: indicates scripts should be skipped
|
|
167
|
+
- `skip_patches`: indicates patches should be skipped
|
|
160
168
|
"""
|
|
161
169
|
log.info(
|
|
162
170
|
"%s dependencies%s: %s",
|
|
@@ -201,6 +209,10 @@ def update(
|
|
|
201
209
|
skip_changes=skip_changes or force_interactive,
|
|
202
210
|
)
|
|
203
211
|
|
|
212
|
+
if _count and not skip_patches:
|
|
213
|
+
common.show("Applying patches...", color="message", log=False)
|
|
214
|
+
common.newline()
|
|
215
|
+
config.apply_patches(*names, depth=depth, force=force)
|
|
204
216
|
if _count and not skip_scripts:
|
|
205
217
|
label = "nested scripts" if index else "scripts"
|
|
206
218
|
common.show(f"Running {label}...", color="message", log=False)
|
|
@@ -161,20 +161,20 @@ CYAN = "\033[36m"
|
|
|
161
161
|
WHITE = "\033[37m"
|
|
162
162
|
RESET = "\033[0m"
|
|
163
163
|
|
|
164
|
-
COLORS =
|
|
165
|
-
path
|
|
166
|
-
git_rev
|
|
167
|
-
git_dirty
|
|
168
|
-
git_changes
|
|
169
|
-
shell
|
|
170
|
-
shell_info
|
|
171
|
-
shell_output
|
|
172
|
-
shell_error
|
|
173
|
-
message
|
|
174
|
-
prompt
|
|
175
|
-
success
|
|
176
|
-
error
|
|
177
|
-
|
|
164
|
+
COLORS = {
|
|
165
|
+
"path": "",
|
|
166
|
+
"git_rev": BOLD + BLUE,
|
|
167
|
+
"git_dirty": BOLD + MAGENTA,
|
|
168
|
+
"git_changes": YELLOW,
|
|
169
|
+
"shell": BOLD + GREEN,
|
|
170
|
+
"shell_info": MAGENTA,
|
|
171
|
+
"shell_output": CYAN,
|
|
172
|
+
"shell_error": YELLOW,
|
|
173
|
+
"message": BOLD + WHITE,
|
|
174
|
+
"prompt": BOLD + WHITE,
|
|
175
|
+
"success": BOLD + GREEN,
|
|
176
|
+
"error": BOLD + RED,
|
|
177
|
+
}
|
|
178
178
|
|
|
179
179
|
|
|
180
180
|
def style(msg, name=None, *, _color_support=False):
|
|
@@ -37,7 +37,7 @@ def clone(
|
|
|
37
37
|
user_params = []
|
|
38
38
|
|
|
39
39
|
if type == "git-svn":
|
|
40
|
-
# just the
|
|
40
|
+
# just the preparation for the svn deep clone / checkout here
|
|
41
41
|
# clone will be made in update function to simplify source.py).
|
|
42
42
|
os.makedirs(path)
|
|
43
43
|
return
|
|
@@ -78,6 +78,38 @@ def clone(
|
|
|
78
78
|
git("clone", "--reference-if-able", reference, repo, normpath, *user_params)
|
|
79
79
|
|
|
80
80
|
|
|
81
|
+
def create_branch_local(type, name: str, base_ref: str = "HEAD", recreate: bool = True):
|
|
82
|
+
"""Create a local branch.
|
|
83
|
+
|
|
84
|
+
:param recreate: delete and create if already exists
|
|
85
|
+
"""
|
|
86
|
+
if type == "git-svn":
|
|
87
|
+
return # ignore creating branch in case of git-svn
|
|
88
|
+
|
|
89
|
+
assert type == "git"
|
|
90
|
+
|
|
91
|
+
# Check if branch exists and delete
|
|
92
|
+
if recreate and _local_branch_exists(name):
|
|
93
|
+
git("branch", "-D", name, _show=False)
|
|
94
|
+
|
|
95
|
+
# Create branch
|
|
96
|
+
git("branch", name, base_ref, _show=False)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def checkout(type, branch_name: str):
|
|
100
|
+
"""Checkout a specific branch.
|
|
101
|
+
|
|
102
|
+
:param branch_name: branch name for the checkout
|
|
103
|
+
"""
|
|
104
|
+
if type == "git-svn":
|
|
105
|
+
return # ignore checkout in the case of git-svn
|
|
106
|
+
|
|
107
|
+
assert type == "git"
|
|
108
|
+
|
|
109
|
+
# Checkout branch
|
|
110
|
+
git("checkout", branch_name)
|
|
111
|
+
|
|
112
|
+
|
|
81
113
|
def is_sha(rev):
|
|
82
114
|
"""Heuristically determine whether a revision corresponds to a commit SHA.
|
|
83
115
|
|
|
@@ -152,7 +184,7 @@ def rebuild(type, repo): # pylint: disable=unused-argument
|
|
|
152
184
|
|
|
153
185
|
assert type == "git"
|
|
154
186
|
|
|
155
|
-
common.show("Rebuilding
|
|
187
|
+
common.show("Rebuilding missing git repo...", color="message")
|
|
156
188
|
git("init", _show=True)
|
|
157
189
|
git("remote", "add", "origin", repo, _show=True)
|
|
158
190
|
common.show("Rebuilt git repo...", color="message")
|
|
@@ -163,8 +195,7 @@ def changes(type, include_untracked=False, display_status=True, _show=False):
|
|
|
163
195
|
status = False
|
|
164
196
|
|
|
165
197
|
if type == "git-svn":
|
|
166
|
-
# ignore changes in case of git-svn
|
|
167
|
-
return status
|
|
198
|
+
return status # ignore changes in case of git-svn
|
|
168
199
|
|
|
169
200
|
assert type == "git"
|
|
170
201
|
|
|
@@ -194,6 +225,26 @@ def changes(type, include_untracked=False, display_status=True, _show=False):
|
|
|
194
225
|
return status
|
|
195
226
|
|
|
196
227
|
|
|
228
|
+
def am(patch, _skip=False):
|
|
229
|
+
"""Apply a patch.
|
|
230
|
+
|
|
231
|
+
:param patch: the patch to be applied
|
|
232
|
+
:param _skip: skip patch if applying fails
|
|
233
|
+
"""
|
|
234
|
+
try:
|
|
235
|
+
git("am", "--3way", patch, _show=True)
|
|
236
|
+
except ShellError as e:
|
|
237
|
+
if _skip:
|
|
238
|
+
# Check if current git am is stuck
|
|
239
|
+
rebase_dir = git("rev-parse", "--git-path", "rebase-apply", _show=False)
|
|
240
|
+
if rebase_dir and os.path.isdir(rebase_dir[0]):
|
|
241
|
+
try:
|
|
242
|
+
git("am", "--skip", _show=True, _ignore=True)
|
|
243
|
+
except ShellError:
|
|
244
|
+
pass
|
|
245
|
+
raise ShellError from e
|
|
246
|
+
|
|
247
|
+
|
|
197
248
|
def update(
|
|
198
249
|
type, repo, path, *, clean=True, fetch=False, rev=None
|
|
199
250
|
): # pylint: disable=redefined-outer-name,unused-argument
|
|
@@ -241,14 +292,17 @@ def get_url(type):
|
|
|
241
292
|
return git("config", "--get", "remote.origin.url", _show=False)[0]
|
|
242
293
|
|
|
243
294
|
|
|
244
|
-
def get_hash(type, _show=False):
|
|
295
|
+
def get_hash(type, short=False, _show=False):
|
|
245
296
|
"""Get the current working tree's hash."""
|
|
246
297
|
if type == "git-svn":
|
|
247
298
|
return "".join(filter(str.isdigit, gitsvn("info", _show=_show)[4]))
|
|
248
299
|
|
|
249
300
|
assert type == "git"
|
|
250
|
-
|
|
251
|
-
|
|
301
|
+
args = ["rev-parse"]
|
|
302
|
+
if short:
|
|
303
|
+
args.append("--short")
|
|
304
|
+
args.append("HEAD")
|
|
305
|
+
return git(*args, _show=_show, _stream=False)[0]
|
|
252
306
|
|
|
253
307
|
|
|
254
308
|
def get_tag():
|
|
@@ -283,6 +337,15 @@ def get_object_rev(object_name):
|
|
|
283
337
|
return commit_sha
|
|
284
338
|
|
|
285
339
|
|
|
340
|
+
def _local_branch_exists(name) -> bool:
|
|
341
|
+
"""Check if a local branch exists."""
|
|
342
|
+
try:
|
|
343
|
+
git("rev-parse", "--verify", name, _show=False)
|
|
344
|
+
return True
|
|
345
|
+
except ShellError:
|
|
346
|
+
return False
|
|
347
|
+
|
|
348
|
+
|
|
286
349
|
def _get_sha_from_rev(rev):
|
|
287
350
|
"""Get a rev-parse string's hash."""
|
|
288
351
|
if "@{" in rev:
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import os
|
|
2
|
-
import sys
|
|
3
2
|
from typing import Iterator, List, Optional
|
|
4
3
|
|
|
5
4
|
import log
|
|
@@ -188,6 +187,52 @@ class Config:
|
|
|
188
187
|
|
|
189
188
|
return count
|
|
190
189
|
|
|
190
|
+
@preserve_cwd
|
|
191
|
+
def apply_patches(
|
|
192
|
+
self,
|
|
193
|
+
*names: str,
|
|
194
|
+
depth: Optional[int] = None,
|
|
195
|
+
force: bool = False,
|
|
196
|
+
) -> int:
|
|
197
|
+
"""Apply patches for the specified dependencies."""
|
|
198
|
+
if depth == 0:
|
|
199
|
+
log.info("Skipped directory: %s", self.location_path)
|
|
200
|
+
return 0
|
|
201
|
+
|
|
202
|
+
sources = self._get_sources()
|
|
203
|
+
sources_filter = self._get_sources_filter(
|
|
204
|
+
*names, sources=sources, skip_default_group=False
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
shell.cd(self.location_path)
|
|
208
|
+
common.newline()
|
|
209
|
+
common.indent()
|
|
210
|
+
|
|
211
|
+
count = 0
|
|
212
|
+
for source in sources:
|
|
213
|
+
if source.name in sources_filter:
|
|
214
|
+
shell.cd(source.name)
|
|
215
|
+
|
|
216
|
+
config = load_config(search=False)
|
|
217
|
+
if config:
|
|
218
|
+
common.indent()
|
|
219
|
+
remaining_depth = None if depth is None else max(0, depth - 1)
|
|
220
|
+
if remaining_depth:
|
|
221
|
+
common.newline()
|
|
222
|
+
count += config.apply_patches(depth=remaining_depth, force=force)
|
|
223
|
+
common.dedent()
|
|
224
|
+
|
|
225
|
+
source.apply_patches(
|
|
226
|
+
topdir=os.path.normpath(self.location_path), skip=force
|
|
227
|
+
)
|
|
228
|
+
count += 1
|
|
229
|
+
|
|
230
|
+
shell.cd(self.location_path, _show=False)
|
|
231
|
+
|
|
232
|
+
common.dedent()
|
|
233
|
+
|
|
234
|
+
return count
|
|
235
|
+
|
|
191
236
|
@classmethod
|
|
192
237
|
def _split_name_and_rev(cls, name_rev):
|
|
193
238
|
true_name = name_rev
|
|
@@ -450,12 +495,8 @@ def find_nested_configs(
|
|
|
450
495
|
|
|
451
496
|
|
|
452
497
|
def _resolve_current_directory():
|
|
453
|
-
start = os.getcwd()
|
|
454
|
-
|
|
455
|
-
log.warn("Python 3.8+ is required to resolve virtual drives on Windows")
|
|
456
|
-
else:
|
|
457
|
-
start = os.path.realpath(start)
|
|
458
|
-
os.chdir(start)
|
|
498
|
+
start = os.path.realpath(os.getcwd())
|
|
499
|
+
os.chdir(start)
|
|
459
500
|
return start
|
|
460
501
|
|
|
461
502
|
|
|
@@ -30,6 +30,7 @@ class Source:
|
|
|
30
30
|
| `sparse_paths` | Controls partial checkout | No | `[]` |
|
|
31
31
|
| `links` | Creates symlinks within a project | No | `[]` |
|
|
32
32
|
| `scripts` | Shell commands to run after checkout | No | `[]` |
|
|
33
|
+
| `patches` | patches to be applied after checkout | No | `[]` |
|
|
33
34
|
|
|
34
35
|
### Params
|
|
35
36
|
|
|
@@ -62,6 +63,17 @@ class Source:
|
|
|
62
63
|
- cabal install
|
|
63
64
|
```
|
|
64
65
|
|
|
66
|
+
### Patches
|
|
67
|
+
|
|
68
|
+
Patches that are applied after checkout. For example:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
repo: "https://github.com/koalaman/shellcheck"
|
|
72
|
+
patches:
|
|
73
|
+
- patchdir/0001-add-something.patch
|
|
74
|
+
- patchdir/0002-add-more.patch
|
|
75
|
+
```
|
|
76
|
+
|
|
65
77
|
"""
|
|
66
78
|
|
|
67
79
|
repo: str = ""
|
|
@@ -74,6 +86,7 @@ class Source:
|
|
|
74
86
|
links: List[Link] = field(default_factory=list)
|
|
75
87
|
|
|
76
88
|
scripts: List[str] = field(default_factory=list)
|
|
89
|
+
patches: List[str] = field(default_factory=list)
|
|
77
90
|
|
|
78
91
|
DIRTY = "<dirty>"
|
|
79
92
|
UNKNOWN = "<unknown>"
|
|
@@ -235,6 +248,46 @@ class Source:
|
|
|
235
248
|
raise exceptions.ScriptFailure(msg)
|
|
236
249
|
common.newline()
|
|
237
250
|
|
|
251
|
+
def apply_patches(self, topdir: str, skip: bool = False):
|
|
252
|
+
log.info("Applying patches...")
|
|
253
|
+
|
|
254
|
+
# Enter the working tree
|
|
255
|
+
if not git.valid():
|
|
256
|
+
raise self._invalid_repository
|
|
257
|
+
|
|
258
|
+
# Check for patches
|
|
259
|
+
if not self.patches or not self.patches[0]:
|
|
260
|
+
common.show("(no patches to apply)", color="shell_info")
|
|
261
|
+
common.newline()
|
|
262
|
+
return
|
|
263
|
+
|
|
264
|
+
# Create a branch from the current hash to apply patches
|
|
265
|
+
try:
|
|
266
|
+
hash = git.get_hash(self.type, short=True, _show=False)
|
|
267
|
+
patched_branch = hash + "-patched"
|
|
268
|
+
git.create_branch_local(self.type, patched_branch)
|
|
269
|
+
git.checkout(self.type, patched_branch)
|
|
270
|
+
log.info("Working on local branch{} for patching.".format(patched_branch))
|
|
271
|
+
except exceptions.ShellError as exc:
|
|
272
|
+
msg = "Patch preparation failed! Could not create branch {}".format(
|
|
273
|
+
patched_branch
|
|
274
|
+
)
|
|
275
|
+
raise exceptions.PatchFailure(msg) from exc
|
|
276
|
+
|
|
277
|
+
# Apply all patches
|
|
278
|
+
for patch in self.patches:
|
|
279
|
+
try:
|
|
280
|
+
# Convert patch to absolute path
|
|
281
|
+
patch_path = os.path.abspath(os.path.join(topdir, patch))
|
|
282
|
+
git.am(patch_path, skip)
|
|
283
|
+
except exceptions.ShellError as exc:
|
|
284
|
+
if skip:
|
|
285
|
+
log.debug("Ignored error from patch '%s'", patch)
|
|
286
|
+
else:
|
|
287
|
+
msg = "Failed to apply patch '{}' in {}".format(patch, os.getcwd())
|
|
288
|
+
raise exceptions.PatchFailure(msg) from exc
|
|
289
|
+
common.newline()
|
|
290
|
+
|
|
238
291
|
def identify(
|
|
239
292
|
self,
|
|
240
293
|
allow_dirty: bool = True,
|
|
@@ -318,6 +371,7 @@ class Source:
|
|
|
318
371
|
rev=rev,
|
|
319
372
|
links=self.links,
|
|
320
373
|
scripts=self.scripts,
|
|
374
|
+
patches=self.patches,
|
|
321
375
|
sparse_paths=self.sparse_paths,
|
|
322
376
|
)
|
|
323
377
|
return source
|
|
@@ -69,6 +69,13 @@ def main(args=None):
|
|
|
69
69
|
action="store_true",
|
|
70
70
|
dest="no_scripts",
|
|
71
71
|
)
|
|
72
|
+
parser.add_argument(
|
|
73
|
+
"-P",
|
|
74
|
+
"--no-patches",
|
|
75
|
+
help="skip patches after installation",
|
|
76
|
+
action="store_true",
|
|
77
|
+
dest="no_patches",
|
|
78
|
+
)
|
|
72
79
|
|
|
73
80
|
# Update option
|
|
74
81
|
group.add_argument(
|
|
@@ -78,6 +78,7 @@ class TestInstall:
|
|
|
78
78
|
clean=False,
|
|
79
79
|
skip_changes=False,
|
|
80
80
|
skip_scripts=False,
|
|
81
|
+
skip_patches=False,
|
|
81
82
|
skip_default_group=False,
|
|
82
83
|
)
|
|
83
84
|
|
|
@@ -95,6 +96,7 @@ class TestInstall:
|
|
|
95
96
|
clean=False,
|
|
96
97
|
skip_changes=False,
|
|
97
98
|
skip_scripts=False,
|
|
99
|
+
skip_patches=False,
|
|
98
100
|
skip_default_group=False,
|
|
99
101
|
)
|
|
100
102
|
|
|
@@ -112,6 +114,7 @@ class TestInstall:
|
|
|
112
114
|
clean=False,
|
|
113
115
|
skip_changes=False,
|
|
114
116
|
skip_scripts=False,
|
|
117
|
+
skip_patches=False,
|
|
115
118
|
skip_default_group=False,
|
|
116
119
|
)
|
|
117
120
|
|
|
@@ -129,6 +132,7 @@ class TestInstall:
|
|
|
129
132
|
clean=False,
|
|
130
133
|
skip_changes=False,
|
|
131
134
|
skip_scripts=False,
|
|
135
|
+
skip_patches=False,
|
|
132
136
|
skip_default_group=False,
|
|
133
137
|
)
|
|
134
138
|
|
|
@@ -146,6 +150,7 @@ class TestInstall:
|
|
|
146
150
|
clean=True,
|
|
147
151
|
skip_changes=False,
|
|
148
152
|
skip_scripts=False,
|
|
153
|
+
skip_patches=False,
|
|
149
154
|
skip_default_group=False,
|
|
150
155
|
)
|
|
151
156
|
|
|
@@ -165,6 +170,7 @@ class TestInstall:
|
|
|
165
170
|
clean=False,
|
|
166
171
|
skip_changes=False,
|
|
167
172
|
skip_scripts=False,
|
|
173
|
+
skip_patches=False,
|
|
168
174
|
skip_default_group=False,
|
|
169
175
|
)
|
|
170
176
|
|
|
@@ -182,6 +188,7 @@ class TestInstall:
|
|
|
182
188
|
clean=False,
|
|
183
189
|
skip_changes=False,
|
|
184
190
|
skip_scripts=False,
|
|
191
|
+
skip_patches=False,
|
|
185
192
|
skip_default_group=False,
|
|
186
193
|
)
|
|
187
194
|
|
|
@@ -212,6 +219,7 @@ class TestUpdate:
|
|
|
212
219
|
lock=None,
|
|
213
220
|
skip_changes=False,
|
|
214
221
|
skip_scripts=False,
|
|
222
|
+
skip_patches=False,
|
|
215
223
|
)
|
|
216
224
|
|
|
217
225
|
@patch("gitman.commands.update")
|
|
@@ -229,6 +237,7 @@ class TestUpdate:
|
|
|
229
237
|
lock=None,
|
|
230
238
|
skip_changes=False,
|
|
231
239
|
skip_scripts=False,
|
|
240
|
+
skip_patches=False,
|
|
232
241
|
)
|
|
233
242
|
|
|
234
243
|
@patch("gitman.commands.update")
|
|
@@ -246,6 +255,7 @@ class TestUpdate:
|
|
|
246
255
|
lock=False,
|
|
247
256
|
skip_changes=False,
|
|
248
257
|
skip_scripts=False,
|
|
258
|
+
skip_patches=False,
|
|
249
259
|
)
|
|
250
260
|
|
|
251
261
|
@patch("gitman.commands.update")
|
|
@@ -263,6 +273,7 @@ class TestUpdate:
|
|
|
263
273
|
lock=None,
|
|
264
274
|
skip_changes=True,
|
|
265
275
|
skip_scripts=False,
|
|
276
|
+
skip_patches=False,
|
|
266
277
|
)
|
|
267
278
|
|
|
268
279
|
@patch("gitman.commands.update")
|
|
@@ -280,6 +291,7 @@ class TestUpdate:
|
|
|
280
291
|
lock=None,
|
|
281
292
|
skip_changes=False,
|
|
282
293
|
skip_scripts=False,
|
|
294
|
+
skip_patches=False,
|
|
283
295
|
)
|
|
284
296
|
|
|
285
297
|
@patch("gitman.commands.update")
|
|
@@ -297,6 +309,7 @@ class TestUpdate:
|
|
|
297
309
|
lock=None,
|
|
298
310
|
skip_changes=False,
|
|
299
311
|
skip_scripts=False,
|
|
312
|
+
skip_patches=False,
|
|
300
313
|
)
|
|
301
314
|
|
|
302
315
|
@patch("gitman.commands.update")
|
|
@@ -316,6 +329,7 @@ class TestUpdate:
|
|
|
316
329
|
lock=None,
|
|
317
330
|
skip_changes=False,
|
|
318
331
|
skip_scripts=False,
|
|
332
|
+
skip_patches=False,
|
|
319
333
|
)
|
|
320
334
|
|
|
321
335
|
@patch("gitman.commands.update")
|
|
@@ -333,6 +347,7 @@ class TestUpdate:
|
|
|
333
347
|
lock=None,
|
|
334
348
|
skip_changes=False,
|
|
335
349
|
skip_scripts=False,
|
|
350
|
+
skip_patches=False,
|
|
336
351
|
)
|
|
337
352
|
|
|
338
353
|
|
|
@@ -23,6 +23,7 @@ class TestMain:
|
|
|
23
23
|
force_interactive=False,
|
|
24
24
|
skip_changes=False,
|
|
25
25
|
skip_scripts=False,
|
|
26
|
+
skip_patches=False,
|
|
26
27
|
skip_default_group=False,
|
|
27
28
|
),
|
|
28
29
|
call.install().__bool__(), # command status check
|
|
@@ -46,6 +47,7 @@ class TestMain:
|
|
|
46
47
|
lock=True,
|
|
47
48
|
skip_changes=False,
|
|
48
49
|
skip_scripts=False,
|
|
50
|
+
skip_patches=False,
|
|
49
51
|
),
|
|
50
52
|
call.update().__bool__(), # command status check
|
|
51
53
|
] == mock_commands.mock_calls
|
|
@@ -68,6 +70,7 @@ class TestMain:
|
|
|
68
70
|
lock=True,
|
|
69
71
|
skip_changes=False,
|
|
70
72
|
skip_scripts=False,
|
|
73
|
+
skip_patches=False,
|
|
71
74
|
),
|
|
72
75
|
call.update().__bool__(), # command status check
|
|
73
76
|
] == mock_commands.mock_calls
|
|
@@ -90,6 +93,7 @@ class TestMain:
|
|
|
90
93
|
lock=False,
|
|
91
94
|
skip_changes=False,
|
|
92
95
|
skip_scripts=False,
|
|
96
|
+
skip_patches=False,
|
|
93
97
|
),
|
|
94
98
|
call.update().__bool__(), # command status check
|
|
95
99
|
] == mock_commands.mock_calls
|
|
@@ -112,6 +116,7 @@ class TestMain:
|
|
|
112
116
|
lock=True,
|
|
113
117
|
skip_changes=True,
|
|
114
118
|
skip_scripts=False,
|
|
119
|
+
skip_patches=False,
|
|
115
120
|
),
|
|
116
121
|
call.update().__bool__(), # command status check
|
|
117
122
|
] == mock_commands.mock_calls
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
|
|
3
3
|
name = "gitman"
|
|
4
|
-
version = "3.
|
|
4
|
+
version = "3.7"
|
|
5
5
|
description = "A language-agnostic dependency manager using Git."
|
|
6
6
|
|
|
7
7
|
license = "MIT"
|
|
@@ -30,10 +30,11 @@ classifiers = [
|
|
|
30
30
|
"Operating System :: OS Independent",
|
|
31
31
|
"Programming Language :: Python",
|
|
32
32
|
"Programming Language :: Python :: 3",
|
|
33
|
-
"Programming Language :: Python :: 3.8",
|
|
34
33
|
"Programming Language :: Python :: 3.9",
|
|
35
34
|
"Programming Language :: Python :: 3.10",
|
|
36
35
|
"Programming Language :: Python :: 3.11",
|
|
36
|
+
"Programming Language :: Python :: 3.12",
|
|
37
|
+
"Programming Language :: Python :: 3.13",
|
|
37
38
|
"Topic :: Software Development",
|
|
38
39
|
"Topic :: Software Development :: Build Tools",
|
|
39
40
|
"Topic :: Software Development :: Version Control",
|
|
@@ -42,28 +43,28 @@ classifiers = [
|
|
|
42
43
|
|
|
43
44
|
[tool.poetry.dependencies]
|
|
44
45
|
|
|
45
|
-
python = "^3.
|
|
46
|
+
python = "^3.9,<3.15"
|
|
46
47
|
|
|
47
48
|
datafiles = "^2.3.1"
|
|
48
49
|
minilog = "^2.3.1"
|
|
49
|
-
universal-startfile = "
|
|
50
|
+
universal-startfile = ">=0.2,<0.4"
|
|
50
51
|
|
|
51
52
|
[tool.poetry.group.dev.dependencies]
|
|
52
53
|
|
|
53
54
|
# Formatters
|
|
54
|
-
black = "
|
|
55
|
-
isort = "
|
|
55
|
+
black = ">=24.8,<26.0"
|
|
56
|
+
isort = ">=5.13,<7.0"
|
|
56
57
|
|
|
57
58
|
# Linters
|
|
58
59
|
mypy = "^1.3"
|
|
59
60
|
pydocstyle = "*"
|
|
60
|
-
pylint = "~
|
|
61
|
+
pylint = "~3.3"
|
|
61
62
|
types-freezegun = "*"
|
|
62
63
|
types-setuptools = "*"
|
|
63
64
|
|
|
64
65
|
# Testing
|
|
65
66
|
pytest = "^8.3"
|
|
66
|
-
pytest-cov = "
|
|
67
|
+
pytest-cov = ">=5,<8"
|
|
67
68
|
pytest-describe = "^2.2"
|
|
68
69
|
pytest-expecter = "^3.0"
|
|
69
70
|
pytest-random = "*"
|
|
@@ -74,16 +75,20 @@ coveragespace = "^6.1"
|
|
|
74
75
|
|
|
75
76
|
# Documentation
|
|
76
77
|
mkdocs = "^1.2.3"
|
|
77
|
-
mkdocstrings = "
|
|
78
|
+
mkdocstrings = ">=0.18.1,<0.31.0"
|
|
78
79
|
pygments = "^2.15.0"
|
|
79
80
|
jinja2 = "~3.1.6"
|
|
80
81
|
|
|
81
82
|
# Tooling
|
|
82
|
-
pyinstaller = "^
|
|
83
|
+
pyinstaller = "^6.15"
|
|
83
84
|
sniffer = "*"
|
|
84
85
|
macfsevents = { version = "*", platform = "darwin" }
|
|
85
86
|
pync = { version = "*", platform = "darwin" }
|
|
86
|
-
rope = "
|
|
87
|
+
rope = ">=0.14,<1.15"
|
|
88
|
+
|
|
89
|
+
[tool.poetry.requires-plugins]
|
|
90
|
+
|
|
91
|
+
poetry-plugin-export = ">=1.8"
|
|
87
92
|
|
|
88
93
|
[tool.poetry.scripts]
|
|
89
94
|
|
|
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
|
{gitman-3.5.3 → gitman-3.7}/gitman/tests/files/subdir/subsubdir/skip/subsubsubsubdir/gitman.yml
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
|