batchfetch 1.3.3__tar.gz → 1.3.5__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.3 → batchfetch-1.3.5}/PKG-INFO +2 -2
- {batchfetch-1.3.3 → batchfetch-1.3.5}/README.md +1 -1
- {batchfetch-1.3.3 → batchfetch-1.3.5}/batchfetch/__init__.py +1 -1
- {batchfetch-1.3.3 → batchfetch-1.3.5}/batchfetch/batchfetch_base.py +1 -1
- {batchfetch-1.3.3 → batchfetch-1.3.5}/batchfetch/batchfetch_cli.py +39 -12
- {batchfetch-1.3.3 → batchfetch-1.3.5}/batchfetch/batchfetch_git.py +16 -13
- {batchfetch-1.3.3 → batchfetch-1.3.5}/batchfetch/helpers.py +25 -2
- {batchfetch-1.3.3 → batchfetch-1.3.5}/batchfetch.egg-info/PKG-INFO +2 -2
- {batchfetch-1.3.3 → batchfetch-1.3.5}/setup.py +2 -2
- {batchfetch-1.3.3 → batchfetch-1.3.5}/LICENSE +0 -0
- {batchfetch-1.3.3 → batchfetch-1.3.5}/batchfetch.egg-info/SOURCES.txt +0 -0
- {batchfetch-1.3.3 → batchfetch-1.3.5}/batchfetch.egg-info/dependency_links.txt +0 -0
- {batchfetch-1.3.3 → batchfetch-1.3.5}/batchfetch.egg-info/entry_points.txt +0 -0
- {batchfetch-1.3.3 → batchfetch-1.3.5}/batchfetch.egg-info/requires.txt +0 -0
- {batchfetch-1.3.3 → batchfetch-1.3.5}/batchfetch.egg-info/top_level.txt +0 -0
- {batchfetch-1.3.3 → batchfetch-1.3.5}/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.5
|
|
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
|
|
@@ -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,10 +101,17 @@ 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 \
|
|
114
|
+
isinstance(yaml_dict["options"], dict) and \
|
|
107
115
|
"ignore_untracked" in yaml_dict["options"]:
|
|
108
116
|
untracked_paths = \
|
|
109
117
|
yaml_dict["options"]["ignore_untracked"]
|
|
@@ -113,9 +121,14 @@ class BatchFetchCli:
|
|
|
113
121
|
|
|
114
122
|
if untracked_paths:
|
|
115
123
|
for ignore_untracked_path in untracked_paths:
|
|
116
|
-
|
|
124
|
+
# Absolute
|
|
125
|
+
ignore_untracked_path = \
|
|
117
126
|
Path(ignore_untracked_path).absolute()
|
|
118
|
-
)
|
|
127
|
+
self.ignore_untracked.add(ignore_untracked_path)
|
|
128
|
+
|
|
129
|
+
# Resolve
|
|
130
|
+
ignore_untracked_path = ignore_untracked_path.resolve()
|
|
131
|
+
self.ignore_untracked.add(ignore_untracked_path)
|
|
119
132
|
|
|
120
133
|
self._loads(dict(yaml_dict))
|
|
121
134
|
except OSError as err:
|
|
@@ -273,10 +286,22 @@ class BatchFetchCli:
|
|
|
273
286
|
def _find_untracked_paths(self):
|
|
274
287
|
"Find the files that are untracked and should be deleted."
|
|
275
288
|
untracked_paths = set()
|
|
289
|
+
cwd = Path.cwd()
|
|
290
|
+
local_ignore_untracked = set()
|
|
291
|
+
|
|
292
|
+
for tracked_dir, tracked_filenames in self.tracked_paths.items():
|
|
293
|
+
actual_filenames = {file.name for file in tracked_dir.iterdir()}
|
|
294
|
+
self.ignore_untracked |= {tracked_dir}
|
|
295
|
+
parents = collect_parent_dirs(cwd, tracked_dir)
|
|
296
|
+
local_ignore_untracked |= parents
|
|
297
|
+
|
|
276
298
|
for tracked_dir, tracked_filenames in self.tracked_paths.items():
|
|
277
299
|
actual_filenames = {file.name for file in tracked_dir.iterdir()}
|
|
278
300
|
for filename in actual_filenames - tracked_filenames:
|
|
279
301
|
full_path = tracked_dir / filename
|
|
302
|
+
if full_path in local_ignore_untracked:
|
|
303
|
+
continue
|
|
304
|
+
|
|
280
305
|
if full_path in self.ignore_untracked:
|
|
281
306
|
continue
|
|
282
307
|
|
|
@@ -422,19 +447,21 @@ def command_line_interface():
|
|
|
422
447
|
print()
|
|
423
448
|
|
|
424
449
|
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
450
|
try:
|
|
451
|
+
batchfetch_cli = BatchFetchCli(
|
|
452
|
+
verbose=args.verbose,
|
|
453
|
+
max_workers=args.jobs,
|
|
454
|
+
check_untracked=args.check_untracked,
|
|
455
|
+
targets=args.targets,
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
batchfetch_cli.load(file)
|
|
432
459
|
if not batchfetch_cli.run_tasks():
|
|
433
460
|
errno = 1
|
|
434
461
|
except KeyboardInterrupt:
|
|
435
462
|
print("Interrupted.", file=sys.stderr)
|
|
436
463
|
errno = 1
|
|
437
|
-
except BatchFetchError as err:
|
|
464
|
+
except (yaml.parser.MarkedYAMLError, BatchFetchError) as err:
|
|
438
465
|
print(f"Error: {err}.", file=sys.stderr)
|
|
439
466
|
errno = 1
|
|
440
467
|
|
|
@@ -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
|
|
@@ -117,7 +117,7 @@ class BatchFetchGit(TaskBatchFetch):
|
|
|
117
117
|
|
|
118
118
|
self.add_output(f"[GIT {update_type}] {self[self.main_key]}"
|
|
119
119
|
+ (f" (Ref: {self['revision']})"
|
|
120
|
-
|
|
120
|
+
if self["revision"] else "") + "\n")
|
|
121
121
|
|
|
122
122
|
try:
|
|
123
123
|
# Delete
|
|
@@ -130,32 +130,34 @@ class BatchFetchGit(TaskBatchFetch):
|
|
|
130
130
|
|
|
131
131
|
# Update
|
|
132
132
|
if self.git_local_dir.is_dir():
|
|
133
|
+
do_git_fetch = self["git_pull"]
|
|
134
|
+
|
|
133
135
|
# Pre exec
|
|
134
|
-
|
|
136
|
+
if do_git_fetch:
|
|
137
|
+
self._update_current_branch_name()
|
|
138
|
+
|
|
135
139
|
self._repo_fix_remote_origin()
|
|
136
140
|
self._exec_before(cwd=self.git_local_dir)
|
|
137
141
|
|
|
138
142
|
if not self["revision"]:
|
|
139
143
|
self.values["revision"] = self._run_get_firstline(
|
|
140
|
-
"git symbolic-ref
|
|
141
|
-
).split("/")[-1]
|
|
144
|
+
"git symbolic-ref --short HEAD")
|
|
142
145
|
if not self["revision"]:
|
|
143
146
|
raise BatchFetchError(
|
|
144
147
|
"Unable to determine the default origin branch"
|
|
145
148
|
)
|
|
146
149
|
|
|
147
150
|
self.add_output(self.indent_spaces +
|
|
148
|
-
|
|
151
|
+
"[INFO] Update revision to: '" +
|
|
149
152
|
self["revision"] + "'\n")
|
|
150
153
|
|
|
151
|
-
|
|
154
|
+
if do_git_fetch:
|
|
155
|
+
git_fetch_done = self._repo_fetch()
|
|
152
156
|
|
|
153
|
-
|
|
154
|
-
git_branch_changed = self._repo_fix_branch()
|
|
157
|
+
self._repo_fix_branch()
|
|
155
158
|
|
|
156
|
-
git_merge_done = False
|
|
157
159
|
if git_fetch_done:
|
|
158
|
-
|
|
160
|
+
self._git_merge()
|
|
159
161
|
|
|
160
162
|
if self.get_changed():
|
|
161
163
|
self._exec_after(cwd=self.git_local_dir)
|
|
@@ -192,6 +194,8 @@ class BatchFetchGit(TaskBatchFetch):
|
|
|
192
194
|
|
|
193
195
|
:param cmd: Command to be executed. Can be a list or a string.
|
|
194
196
|
:param kwargs: Additional keyword arguments for Popen.
|
|
197
|
+
:cwd: Current working directory.
|
|
198
|
+
:env: Environment variables.
|
|
195
199
|
:return: Tuple containing two lists: stdout lines and stderr lines.
|
|
196
200
|
"""
|
|
197
201
|
if not cwd:
|
|
@@ -264,11 +268,10 @@ class BatchFetchGit(TaskBatchFetch):
|
|
|
264
268
|
# Merge
|
|
265
269
|
do_git_fetch = self["git_pull"]
|
|
266
270
|
do_git_fetch = False
|
|
267
|
-
commit_ref = None
|
|
268
271
|
|
|
269
272
|
try:
|
|
270
273
|
# Check if the revision such as
|
|
271
|
-
|
|
274
|
+
_, _ = self._run(["git", "cat-file", "-e", self["revision"]])
|
|
272
275
|
except subprocess.CalledProcessError:
|
|
273
276
|
do_git_fetch = True
|
|
274
277
|
self.add_output(
|
|
@@ -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.5
|
|
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.5",
|
|
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
|