batchfetch 1.3.2__tar.gz → 1.3.4__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.
- {batchfetch-1.3.2 → batchfetch-1.3.4}/PKG-INFO +2 -2
- {batchfetch-1.3.2 → batchfetch-1.3.4}/README.md +1 -1
- {batchfetch-1.3.2 → batchfetch-1.3.4}/batchfetch/__init__.py +1 -1
- {batchfetch-1.3.2 → batchfetch-1.3.4}/batchfetch/batchfetch_base.py +8 -9
- {batchfetch-1.3.2 → batchfetch-1.3.4}/batchfetch/batchfetch_cli.py +38 -12
- {batchfetch-1.3.2 → batchfetch-1.3.4}/batchfetch/batchfetch_git.py +1 -1
- {batchfetch-1.3.2 → batchfetch-1.3.4}/batchfetch/helpers.py +25 -2
- {batchfetch-1.3.2 → batchfetch-1.3.4}/batchfetch.egg-info/PKG-INFO +2 -2
- {batchfetch-1.3.2 → batchfetch-1.3.4}/setup.py +2 -2
- {batchfetch-1.3.2 → batchfetch-1.3.4}/LICENSE +0 -0
- {batchfetch-1.3.2 → batchfetch-1.3.4}/batchfetch.egg-info/SOURCES.txt +0 -0
- {batchfetch-1.3.2 → batchfetch-1.3.4}/batchfetch.egg-info/dependency_links.txt +0 -0
- {batchfetch-1.3.2 → batchfetch-1.3.4}/batchfetch.egg-info/entry_points.txt +0 -0
- {batchfetch-1.3.2 → batchfetch-1.3.4}/batchfetch.egg-info/requires.txt +0 -0
- {batchfetch-1.3.2 → batchfetch-1.3.4}/batchfetch.egg-info/top_level.txt +0 -0
- {batchfetch-1.3.2 → batchfetch-1.3.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: batchfetch
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.4
|
|
4
4
|
Summary: Efficiently clone and pull multiple Git repositories.
|
|
5
5
|
Home-page: https://github.com/jamescherti/batchfetch
|
|
6
6
|
Author: James Cherti
|
|
@@ -213,7 +213,7 @@ batchfetch
|
|
|
213
213
|
|
|
214
214
|
## License
|
|
215
215
|
|
|
216
|
-
Copyright (C) 2024 [James Cherti](https://www.jamescherti.com)
|
|
216
|
+
Copyright (C) 2024-2025 [James Cherti](https://www.jamescherti.com)
|
|
217
217
|
|
|
218
218
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
219
219
|
|
|
@@ -193,7 +193,7 @@ batchfetch
|
|
|
193
193
|
|
|
194
194
|
## License
|
|
195
195
|
|
|
196
|
-
Copyright (C) 2024 [James Cherti](https://www.jamescherti.com)
|
|
196
|
+
Copyright (C) 2024-2025 [James Cherti](https://www.jamescherti.com)
|
|
197
197
|
|
|
198
198
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
199
199
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2024 James Cherti
|
|
3
|
+
# Copyright (C) 2024-2025 James Cherti
|
|
4
4
|
# URL: https://github.com/jamescherti/batchfetch
|
|
5
5
|
#
|
|
6
6
|
# This program is free software: you can redistribute it and/or modify it under
|
|
@@ -88,9 +88,6 @@ class TaskBase:
|
|
|
88
88
|
if key in self.options:
|
|
89
89
|
return self.options[key]
|
|
90
90
|
|
|
91
|
-
if key in self.global_options_values:
|
|
92
|
-
return self.global_options_values[key]
|
|
93
|
-
|
|
94
91
|
raise KeyError(f"The item '{key}' was not found in '{self.values}")
|
|
95
92
|
|
|
96
93
|
|
|
@@ -98,9 +95,9 @@ class TaskBatchFetch(TaskBase):
|
|
|
98
95
|
"""Plugin downloader base class."""
|
|
99
96
|
|
|
100
97
|
def __init__(self, data: Dict[str, Any], options: Dict[str, Any]):
|
|
101
|
-
new_options = {"exec_before": [],
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
new_options: Dict[str, Any] = {"exec_before": [],
|
|
99
|
+
"exec_after": [],
|
|
100
|
+
"ignore_untracked": []}
|
|
104
101
|
new_options.update(options)
|
|
105
102
|
options = new_options
|
|
106
103
|
|
|
@@ -160,7 +157,8 @@ class TaskBatchFetch(TaskBase):
|
|
|
160
157
|
self._local_task_exec(cmd, cwd=str(cwd))
|
|
161
158
|
|
|
162
159
|
# Local
|
|
163
|
-
cmd = self["exec_before"]
|
|
160
|
+
cmd = self._item_values["exec_before"] if "exec_before" \
|
|
161
|
+
in self._item_values else None
|
|
164
162
|
if cmd:
|
|
165
163
|
self._local_task_exec(cmd, cwd=str(cwd))
|
|
166
164
|
|
|
@@ -176,7 +174,8 @@ class TaskBatchFetch(TaskBase):
|
|
|
176
174
|
self._local_task_exec(cmd, cwd=str(cwd))
|
|
177
175
|
|
|
178
176
|
# Local
|
|
179
|
-
cmd = self["exec_after"]
|
|
177
|
+
cmd = self._item_values["exec_after"] if "exec_after" \
|
|
178
|
+
in self._item_values else None
|
|
180
179
|
if cmd:
|
|
181
180
|
self._local_task_exec(cmd, cwd=str(cwd))
|
|
182
181
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2024 James Cherti
|
|
3
|
+
# Copyright (C) 2024-2025 James Cherti
|
|
4
4
|
# URL: https://github.com/jamescherti/batchfetch
|
|
5
5
|
#
|
|
6
6
|
# This program is free software: you can redistribute it and/or modify it under
|
|
@@ -35,6 +35,7 @@ from setproctitle import setproctitle
|
|
|
35
35
|
|
|
36
36
|
from .batchfetch_base import BatchFetchError, TaskBatchFetch
|
|
37
37
|
from .batchfetch_git import BatchFetchGit
|
|
38
|
+
from .helpers import collect_parent_dirs
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
class BatchFetchCli:
|
|
@@ -100,8 +101,14 @@ class BatchFetchCli:
|
|
|
100
101
|
file=sys.stderr)
|
|
101
102
|
sys.exit(1)
|
|
102
103
|
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
# The Batchfetch file shouldn't be tracked
|
|
105
|
+
absolute_batchfetch = Path(path).absolute()
|
|
106
|
+
self.ignore_untracked.add(absolute_batchfetch)
|
|
107
|
+
|
|
108
|
+
resolved_batchfetch = absolute_batchfetch.resolve()
|
|
109
|
+
self.ignore_untracked.add(resolved_batchfetch)
|
|
110
|
+
|
|
111
|
+
# Paths specified in the batchfetch.yaml file
|
|
105
112
|
untracked_paths = None
|
|
106
113
|
if "options" in yaml_dict and \
|
|
107
114
|
"ignore_untracked" in yaml_dict["options"]:
|
|
@@ -113,9 +120,14 @@ class BatchFetchCli:
|
|
|
113
120
|
|
|
114
121
|
if untracked_paths:
|
|
115
122
|
for ignore_untracked_path in untracked_paths:
|
|
116
|
-
|
|
123
|
+
# Absolute
|
|
124
|
+
ignore_untracked_path = \
|
|
117
125
|
Path(ignore_untracked_path).absolute()
|
|
118
|
-
)
|
|
126
|
+
self.ignore_untracked.add(ignore_untracked_path)
|
|
127
|
+
|
|
128
|
+
# Resolve
|
|
129
|
+
ignore_untracked_path = ignore_untracked_path.resolve()
|
|
130
|
+
self.ignore_untracked.add(ignore_untracked_path)
|
|
119
131
|
|
|
120
132
|
self._loads(dict(yaml_dict))
|
|
121
133
|
except OSError as err:
|
|
@@ -273,10 +285,22 @@ class BatchFetchCli:
|
|
|
273
285
|
def _find_untracked_paths(self):
|
|
274
286
|
"Find the files that are untracked and should be deleted."
|
|
275
287
|
untracked_paths = set()
|
|
288
|
+
cwd = Path.cwd()
|
|
289
|
+
local_ignore_untracked = set()
|
|
290
|
+
|
|
291
|
+
for tracked_dir, tracked_filenames in self.tracked_paths.items():
|
|
292
|
+
actual_filenames = {file.name for file in tracked_dir.iterdir()}
|
|
293
|
+
self.ignore_untracked |= {tracked_dir}
|
|
294
|
+
parents = collect_parent_dirs(cwd, tracked_dir)
|
|
295
|
+
local_ignore_untracked |= parents
|
|
296
|
+
|
|
276
297
|
for tracked_dir, tracked_filenames in self.tracked_paths.items():
|
|
277
298
|
actual_filenames = {file.name for file in tracked_dir.iterdir()}
|
|
278
299
|
for filename in actual_filenames - tracked_filenames:
|
|
279
300
|
full_path = tracked_dir / filename
|
|
301
|
+
if full_path in local_ignore_untracked:
|
|
302
|
+
continue
|
|
303
|
+
|
|
280
304
|
if full_path in self.ignore_untracked:
|
|
281
305
|
continue
|
|
282
306
|
|
|
@@ -422,19 +446,21 @@ def command_line_interface():
|
|
|
422
446
|
print()
|
|
423
447
|
|
|
424
448
|
os.chdir(args.directory)
|
|
425
|
-
batchfetch_cli = BatchFetchCli(verbose=args.verbose,
|
|
426
|
-
max_workers=args.jobs,
|
|
427
|
-
check_untracked=args.check_untracked,
|
|
428
|
-
targets=args.targets)
|
|
429
|
-
batchfetch_cli.load(file)
|
|
430
|
-
|
|
431
449
|
try:
|
|
450
|
+
batchfetch_cli = BatchFetchCli(
|
|
451
|
+
verbose=args.verbose,
|
|
452
|
+
max_workers=args.jobs,
|
|
453
|
+
check_untracked=args.check_untracked,
|
|
454
|
+
targets=args.targets,
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
batchfetch_cli.load(file)
|
|
432
458
|
if not batchfetch_cli.run_tasks():
|
|
433
459
|
errno = 1
|
|
434
460
|
except KeyboardInterrupt:
|
|
435
461
|
print("Interrupted.", file=sys.stderr)
|
|
436
462
|
errno = 1
|
|
437
|
-
except BatchFetchError as err:
|
|
463
|
+
except (yaml.parser.MarkedYAMLError, BatchFetchError) as err:
|
|
438
464
|
print(f"Error: {err}.", file=sys.stderr)
|
|
439
465
|
errno = 1
|
|
440
466
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2024 James Cherti
|
|
3
|
+
# Copyright (C) 2024-2025 James Cherti
|
|
4
4
|
# URL: https://github.com/jamescherti/batchfetch
|
|
5
5
|
#
|
|
6
6
|
# This program is free software: you can redistribute it and/or modify it under
|
|
@@ -21,8 +21,9 @@
|
|
|
21
21
|
import hashlib
|
|
22
22
|
import os
|
|
23
23
|
import shlex
|
|
24
|
+
from pathlib import Path
|
|
24
25
|
from subprocess import PIPE, CalledProcessError, Popen, list2cmdline
|
|
25
|
-
from typing import List, Tuple, Union
|
|
26
|
+
from typing import List, Set, Tuple, Union
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
def md5sum(filename: os.PathLike):
|
|
@@ -116,3 +117,25 @@ def run_indent(cmd: Union[List[str], str], spaces: int = 4,
|
|
|
116
117
|
stderr = indent_raw_output(stderr, spaces)
|
|
117
118
|
|
|
118
119
|
return (stdout, stderr)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def collect_parent_dirs(base_dir: Path, dir: Path) -> Set[Path]:
|
|
123
|
+
"""Collect all parent directories of 'dir' until 'base_dir' is reached.
|
|
124
|
+
|
|
125
|
+
If 'dir' is not inside 'base_dir', return None.
|
|
126
|
+
"""
|
|
127
|
+
parents: Set[Path] = set()
|
|
128
|
+
|
|
129
|
+
for dir_path, base_path in [(dir.resolve(), base_dir.resolve()),
|
|
130
|
+
(dir.absolute(), base_dir.absolute())]:
|
|
131
|
+
try:
|
|
132
|
+
# Check if dir is inside base_dir
|
|
133
|
+
dir_path.relative_to(base_path)
|
|
134
|
+
except ValueError:
|
|
135
|
+
continue
|
|
136
|
+
|
|
137
|
+
while dir_path != base_path:
|
|
138
|
+
parents.add(dir_path)
|
|
139
|
+
dir_path = dir_path.parent
|
|
140
|
+
|
|
141
|
+
return parents
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: batchfetch
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.4
|
|
4
4
|
Summary: Efficiently clone and pull multiple Git repositories.
|
|
5
5
|
Home-page: https://github.com/jamescherti/batchfetch
|
|
6
6
|
Author: James Cherti
|
|
@@ -213,7 +213,7 @@ batchfetch
|
|
|
213
213
|
|
|
214
214
|
## License
|
|
215
215
|
|
|
216
|
-
Copyright (C) 2024 [James Cherti](https://www.jamescherti.com)
|
|
216
|
+
Copyright (C) 2024-2025 [James Cherti](https://www.jamescherti.com)
|
|
217
217
|
|
|
218
218
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
219
219
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2024 James Cherti
|
|
3
|
+
# Copyright (C) 2024-2025 James Cherti
|
|
4
4
|
# URL: https://github.com/jamescherti/batchfetch
|
|
5
5
|
#
|
|
6
6
|
# This program is free software: you can redistribute it and/or modify it under
|
|
@@ -22,7 +22,7 @@ from setuptools import find_packages, setup
|
|
|
22
22
|
|
|
23
23
|
setup(
|
|
24
24
|
name="batchfetch",
|
|
25
|
-
version="1.3.
|
|
25
|
+
version="1.3.4",
|
|
26
26
|
packages=find_packages(),
|
|
27
27
|
description="Efficiently clone and pull multiple Git repositories.",
|
|
28
28
|
license="GPLv3",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|