skilleter-thingy 0.0.74__py3-none-any.whl → 0.0.75__py3-none-any.whl
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.
Potentially problematic release.
This version of skilleter-thingy might be problematic. Click here for more details.
- skilleter_thingy/multigit.py +90 -8
- skilleter_thingy/thingy/git2.py +13 -10
- {skilleter_thingy-0.0.74.dist-info → skilleter_thingy-0.0.75.dist-info}/METADATA +1 -1
- {skilleter_thingy-0.0.74.dist-info → skilleter_thingy-0.0.75.dist-info}/RECORD +8 -8
- {skilleter_thingy-0.0.74.dist-info → skilleter_thingy-0.0.75.dist-info}/LICENSE +0 -0
- {skilleter_thingy-0.0.74.dist-info → skilleter_thingy-0.0.75.dist-info}/WHEEL +0 -0
- {skilleter_thingy-0.0.74.dist-info → skilleter_thingy-0.0.75.dist-info}/entry_points.txt +0 -0
- {skilleter_thingy-0.0.74.dist-info → skilleter_thingy-0.0.75.dist-info}/top_level.txt +0 -0
skilleter_thingy/multigit.py
CHANGED
|
@@ -22,17 +22,22 @@ import thingy.colour as colour
|
|
|
22
22
|
# Default settings
|
|
23
23
|
|
|
24
24
|
[repo_path]
|
|
25
|
-
name = path
|
|
26
25
|
default branch = name
|
|
27
26
|
"""
|
|
28
27
|
|
|
29
28
|
# TODO: [ ] -j option to run in parallel?
|
|
30
29
|
# TODO: [ ] init function
|
|
31
|
-
# TODO: [
|
|
32
|
-
# TODO: [
|
|
33
|
-
# TODO: [
|
|
30
|
+
# TODO: [/] Use the configuration file
|
|
31
|
+
# TODO: [/] Don't use a fixed list of default branch names
|
|
32
|
+
# TODO: [/] / Output name of each git repo as it is processed as command sits there seeming to do nothing otherwise.
|
|
34
33
|
# TODO: [ ] ? Pull/fetch - only output after running command and only if something updated
|
|
35
34
|
# TODO: [ ] Don't save the configuration on exit if it hasn't changed
|
|
35
|
+
# TODO: [ ] Consistent colours in output
|
|
36
|
+
# TODO: [ ] Is it going to be a problem if the same repo is checked out twice or more in the same workspace
|
|
37
|
+
# TODO: [ ] Better error-handling - e.g. continue/abort option after failure in one repo
|
|
38
|
+
# TODO: [ ] Dry-run option
|
|
39
|
+
# TODO: [ ] Verbose option
|
|
40
|
+
|
|
36
41
|
################################################################################
|
|
37
42
|
|
|
38
43
|
DEFAULT_CONFIG_FILE = 'multigit.toml'
|
|
@@ -100,6 +105,8 @@ def mg_init(args, config, console):
|
|
|
100
105
|
def mg_status(args, config, console):
|
|
101
106
|
"""Report Git status for any repo that has a non-empty status"""
|
|
102
107
|
|
|
108
|
+
# TODO: [ ] More user-friendly output
|
|
109
|
+
|
|
103
110
|
for repo in find_git_repos(args.directory, args.repos):
|
|
104
111
|
if not args.quiet:
|
|
105
112
|
show_progress(console.columns, repo)
|
|
@@ -229,6 +236,23 @@ def mg_push(args, config, console):
|
|
|
229
236
|
# TODO: Add option for force-push?
|
|
230
237
|
# TODO: Add option for manual confirmation?
|
|
231
238
|
|
|
239
|
+
for repo in find_git_repos(args.directory, args.repos):
|
|
240
|
+
if not args.quiet:
|
|
241
|
+
show_progress(console.columns, repo)
|
|
242
|
+
|
|
243
|
+
branch = git.branch(path=repo)
|
|
244
|
+
|
|
245
|
+
if branch != config[repo]['default branch']:
|
|
246
|
+
colour.write(f'Pushing changes to [BLUE:{branch}] in [BOLD:{repo}]')
|
|
247
|
+
|
|
248
|
+
result = git.push(path=repo)
|
|
249
|
+
|
|
250
|
+
if result:
|
|
251
|
+
for line in result:
|
|
252
|
+
colour.write(f' {line}')
|
|
253
|
+
|
|
254
|
+
colour.write()
|
|
255
|
+
|
|
232
256
|
################################################################################
|
|
233
257
|
|
|
234
258
|
def mg_checkout(args, config, console):
|
|
@@ -252,6 +276,57 @@ def mg_checkout(args, config, console):
|
|
|
252
276
|
|
|
253
277
|
################################################################################
|
|
254
278
|
|
|
279
|
+
def mg_commit(args, config, console):
|
|
280
|
+
"""For every repo that has a branch checked out and changes present,
|
|
281
|
+
commit those changes onto the branch"""
|
|
282
|
+
|
|
283
|
+
# TODO [ ] Option to amend the commit if it is not the first one on the current branch
|
|
284
|
+
# TODO [ ] Prevent commits if current branch is the default branch
|
|
285
|
+
|
|
286
|
+
for repo in find_git_repos(args.directory, args.repos):
|
|
287
|
+
if not args.quiet:
|
|
288
|
+
show_progress(console.columns, repo)
|
|
289
|
+
|
|
290
|
+
branch = git.branch(path=repo)
|
|
291
|
+
modified = git.status(path=repo)
|
|
292
|
+
|
|
293
|
+
if branch != config[repo]['default branch'] and modified:
|
|
294
|
+
colour.write(f'Committing [BOLD:{len(modified)}] changes onto [BLUE:{branch}] branch in [BOLD:{repo}]')
|
|
295
|
+
|
|
296
|
+
git.commit(all=True, message=args.message, path=repo)
|
|
297
|
+
|
|
298
|
+
################################################################################
|
|
299
|
+
|
|
300
|
+
def mg_update(args, config, console):
|
|
301
|
+
"""For every repo, pull the default branch and if the current branch
|
|
302
|
+
is not the default branch, rebase it onto the default branch"""
|
|
303
|
+
|
|
304
|
+
# TODO: [ ] Option to pull current branch
|
|
305
|
+
# TODO: [ ] Use git-update
|
|
306
|
+
# TODO: [ ] Option to delete current branch before pulling (to get updates without conflicts)
|
|
307
|
+
# TODO: [ ] Option to stash changes on current branch before updating and unstash afterwards
|
|
308
|
+
|
|
309
|
+
for repo in find_git_repos(args.directory, args.repos):
|
|
310
|
+
if not args.quiet:
|
|
311
|
+
show_progress(console.columns, repo)
|
|
312
|
+
|
|
313
|
+
branch = git.branch(path=repo)
|
|
314
|
+
default_branch = config[repo]['default branch']
|
|
315
|
+
|
|
316
|
+
colour.write(f'Updating branch [BLUE:{branch}] in [BOLD:{repo}]')
|
|
317
|
+
|
|
318
|
+
if branch != default_branch:
|
|
319
|
+
git.checkout(default_branch, path=repo)
|
|
320
|
+
|
|
321
|
+
git.pull(path=repo)
|
|
322
|
+
|
|
323
|
+
if branch != default_branch:
|
|
324
|
+
git.checkout(branch, path=repo)
|
|
325
|
+
result = git.rebase(default_branch, path=repo)
|
|
326
|
+
colour.write(f' {result[0].strip()}')
|
|
327
|
+
|
|
328
|
+
################################################################################
|
|
329
|
+
|
|
255
330
|
def main():
|
|
256
331
|
"""Main function"""
|
|
257
332
|
|
|
@@ -262,11 +337,13 @@ def main():
|
|
|
262
337
|
'pull': mg_pull,
|
|
263
338
|
'push': mg_push,
|
|
264
339
|
'checkout': mg_checkout,
|
|
340
|
+
'commit': mg_commit,
|
|
341
|
+
'update': mg_update,
|
|
265
342
|
}
|
|
266
343
|
|
|
267
344
|
# Parse args in the form COMMAND OPTIONS SUBCOMMAND SUBCOMMAND_OPTIONS PARAMETERS
|
|
268
345
|
|
|
269
|
-
parser = argparse.ArgumentParser(description='
|
|
346
|
+
parser = argparse.ArgumentParser(description='Run git commands in multiple Git repos. DISCLAIMER: This is beta-quality software, with missing features and liable to fail with stack dump, but shouldn\'t eat your data')
|
|
270
347
|
|
|
271
348
|
parser.add_argument('--dryrun', '--dry-run', '-D', action='store_true', help='Dry-run comands')
|
|
272
349
|
parser.add_argument('--debug', '-d', action='store_true', help='Debug')
|
|
@@ -291,6 +368,11 @@ def main():
|
|
|
291
368
|
parser_checkout.add_argument('--create', action='store_true', help='Create the specified branch and check it out')
|
|
292
369
|
parser_checkout.add_argument('branch', nargs='?', default=None, action='store', help='The branch name to check out (defaults to the default branch)')
|
|
293
370
|
|
|
371
|
+
parser_commit = subparsers.add_parser('commit', help='Commit changes')
|
|
372
|
+
parser_commit.add_argument('--message', '-m', action='store', default=None, help='The commit message')
|
|
373
|
+
|
|
374
|
+
parser_update = subparsers.add_parser('update', help='Pull the default branch and if the current branch isn\'t the default branch, rebase it onto the default branch')
|
|
375
|
+
|
|
294
376
|
# Parse the command line
|
|
295
377
|
|
|
296
378
|
args = parser.parse_args()
|
|
@@ -321,10 +403,10 @@ def main():
|
|
|
321
403
|
|
|
322
404
|
commands[args.command](args, config, console)
|
|
323
405
|
|
|
324
|
-
# Save the updated configuration file
|
|
406
|
+
# Save the updated configuration file if it has changed (currently, only the init command will do this).
|
|
325
407
|
|
|
326
|
-
if config:
|
|
327
|
-
with open(args.config, 'w') as configfile:
|
|
408
|
+
if config and args.command == 'init':
|
|
409
|
+
with open(args.config, 'w', encoding='utf8') as configfile:
|
|
328
410
|
config.write(configfile)
|
|
329
411
|
|
|
330
412
|
################################################################################
|
skilleter_thingy/thingy/git2.py
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
* Functions will raise exceptions on error. If the underlying git command
|
|
16
16
|
returns an error, a git.GitError() exception is raised.
|
|
17
17
|
|
|
18
|
-
* TODO: Cache list of branches when git.branches/isbranch called
|
|
18
|
+
* TODO: [ ] Cache list of branches when git.branches/isbranch called
|
|
19
|
+
* TODO: [ ] API change - git_run_status should raise an exception on failure and just return the git output
|
|
19
20
|
"""
|
|
20
21
|
################################################################################
|
|
21
22
|
|
|
@@ -53,13 +54,13 @@ def git(cmd, stdout=None, stderr=None, path=None):
|
|
|
53
54
|
to get the exception.
|
|
54
55
|
Optionally redirect stdout and stderr as specified. """
|
|
55
56
|
|
|
56
|
-
logging.debug('Running git %s', ' '.join(cmd))
|
|
57
|
-
|
|
58
57
|
git_cmd = ['git']
|
|
59
58
|
|
|
60
59
|
if path:
|
|
61
60
|
git_cmd += ['-C', path]
|
|
62
61
|
|
|
62
|
+
logging.debug('Running %s', ' '.join(git_cmd + cmd))
|
|
63
|
+
|
|
63
64
|
try:
|
|
64
65
|
return run.run(git_cmd + cmd, stdout=stdout, stderr=stderr)
|
|
65
66
|
except run.RunError as exc:
|
|
@@ -274,10 +275,10 @@ def rebase_required(branch, parent):
|
|
|
274
275
|
|
|
275
276
|
################################################################################
|
|
276
277
|
|
|
277
|
-
def rebase(branch):
|
|
278
|
+
def rebase(branch, path=None):
|
|
278
279
|
""" Rebase the current branch against the specified branch """
|
|
279
280
|
|
|
280
|
-
return git_run_status(['rebase', branch])
|
|
281
|
+
return git_run_status(['rebase', branch], path=path)
|
|
281
282
|
|
|
282
283
|
################################################################################
|
|
283
284
|
|
|
@@ -622,7 +623,8 @@ def rm(files):
|
|
|
622
623
|
|
|
623
624
|
def commit(files=None,
|
|
624
625
|
message=None,
|
|
625
|
-
all=False, amend=False, foreground=False, patch=False, dry_run=False
|
|
626
|
+
all=False, amend=False, foreground=False, patch=False, dry_run=False,
|
|
627
|
+
path=None):
|
|
626
628
|
""" Commit files to git """
|
|
627
629
|
|
|
628
630
|
cmd = ['commit']
|
|
@@ -647,16 +649,17 @@ def commit(files=None,
|
|
|
647
649
|
cmd += ['-m', message]
|
|
648
650
|
|
|
649
651
|
if foreground:
|
|
650
|
-
return git(cmd, stdout=sys.stdout, stderr=sys.stderr)
|
|
652
|
+
return git(cmd, stdout=sys.stdout, stderr=sys.stderr, path=path)
|
|
651
653
|
|
|
652
|
-
return git(cmd)
|
|
654
|
+
return git(cmd, path=path)
|
|
653
655
|
|
|
654
656
|
################################################################################
|
|
655
657
|
|
|
656
658
|
def push(all=False, mirror=False, tags=False, atomic=False, dry_run=False,
|
|
657
659
|
follow_tags=False, receive_pack=False, repo=None, force=False, delete=False,
|
|
658
660
|
prune=False, verbose=False, set_upstream=False, push_options=[], signed=None,
|
|
659
|
-
force_with_lease=False, no_verify=False, repository=None, refspec=None
|
|
661
|
+
force_with_lease=False, no_verify=False, repository=None, refspec=None,
|
|
662
|
+
path=None):
|
|
660
663
|
""" Push commits to a remote """
|
|
661
664
|
|
|
662
665
|
cmd = ['push']
|
|
@@ -720,7 +723,7 @@ def push(all=False, mirror=False, tags=False, atomic=False, dry_run=False,
|
|
|
720
723
|
for ref in refspec:
|
|
721
724
|
cmd.append(ref)
|
|
722
725
|
|
|
723
|
-
return git(cmd)
|
|
726
|
+
return git(cmd, path=path)
|
|
724
727
|
|
|
725
728
|
################################################################################
|
|
726
729
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: skilleter_thingy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.75
|
|
4
4
|
Summary: A collection of useful utilities, mainly aimed at making Git more friendly
|
|
5
5
|
Author-email: John Skilleter <john@skilleter.org.uk>
|
|
6
6
|
Project-URL: Home, https://skilleter.org.uk
|
|
@@ -25,7 +25,7 @@ skilleter_thingy/gl.py,sha256=9zbGpKxw6lX9RghLkdy-Q5sZlqtbB3uGFO04qTu1dH8,5954
|
|
|
25
25
|
skilleter_thingy/gphotosync.py,sha256=Vb2zYTEFp26BYdkG810SRg9afyfDqvq4CLHTk-MFf60,22388
|
|
26
26
|
skilleter_thingy/linecount.py,sha256=5voQtjJjDCVx4zjPwVRy620NpuLiwwFitzxjIsRGtxQ,4310
|
|
27
27
|
skilleter_thingy/moviemover.py,sha256=j_Xb9_jFdgpFBAXcF4tEqbnKH_FonlnUU39LiCK980k,4470
|
|
28
|
-
skilleter_thingy/multigit.py,sha256=
|
|
28
|
+
skilleter_thingy/multigit.py,sha256=QKn2DLf5Fr6WJr99PEM1YV5mmTlfoX7Qt5SbaXA4S8w,15695
|
|
29
29
|
skilleter_thingy/photodupe.py,sha256=l0hbzSLb2Vk2ceteg-x9fHXCEE1uUuFo84hz5rsZUPA,4184
|
|
30
30
|
skilleter_thingy/phototidier.py,sha256=5gSjlINUxf3ZQl3NG0o7CsWwODvTbokIMIafLFvn8Hc,7818
|
|
31
31
|
skilleter_thingy/py_audit.py,sha256=xJm5k5qyeA6ii8mODa4dOkmP8L1drv94UHuxR54RsIM,4384
|
|
@@ -52,7 +52,7 @@ skilleter_thingy/thingy/dircolors.py,sha256=5NbXMsGWdABLvvZfB70VPmN6N5HyyihfpgoQ
|
|
|
52
52
|
skilleter_thingy/thingy/docker.py,sha256=9EFatudoVPfB1UbDEtzdJDB3o6ToHiNHv8-oLsUeqiQ,2449
|
|
53
53
|
skilleter_thingy/thingy/files.py,sha256=oW6E6WWwVFSUPdrZnKMx7P_w_hh3etjoN7RrqvYHCHc,4705
|
|
54
54
|
skilleter_thingy/thingy/git.py,sha256=qXWIduF4jbP5pKFYt_hW9Ex5iL9mSBBrcNKBkULhRTg,38834
|
|
55
|
-
skilleter_thingy/thingy/git2.py,sha256=
|
|
55
|
+
skilleter_thingy/thingy/git2.py,sha256=ylEuwO-URTLxFQI--y5ed0Dg0v88reupCRBQnnkohf0,35971
|
|
56
56
|
skilleter_thingy/thingy/gitlab.py,sha256=uXAF918xnPk6qQyiwPQDbMZfqtJzhiRqDS7yEtJEIAg,6079
|
|
57
57
|
skilleter_thingy/thingy/path.py,sha256=8uM2Q9zFRWv_SaVOX49PeecQXttl7J6lsmBuRXWsXKY,4732
|
|
58
58
|
skilleter_thingy/thingy/popup.py,sha256=jW-nbpdeswqEMTli7OmBv1J8XQsvFoMI0J33O6dOeu8,2529
|
|
@@ -61,9 +61,9 @@ skilleter_thingy/thingy/run.py,sha256=6SNKWF01fSxzB10GMU9ajraXYZqAL1w0PXkqjJdr1U
|
|
|
61
61
|
skilleter_thingy/thingy/tfm_pane.py,sha256=oqy5zBzKwfbjbGqetbbhpKi4x5He7sl4qkmhUeqtdZc,19789
|
|
62
62
|
skilleter_thingy/thingy/tidy.py,sha256=71DCyj0VJrj52RmjQyj1eOiQJIfy5EIPHuThOrS6ZTA,5876
|
|
63
63
|
skilleter_thingy/thingy/venv_template.py,sha256=SsVNvSwojd8NnFeQaZPCRQYTNdwJRplpZpygbUEXRnY,1015
|
|
64
|
-
skilleter_thingy-0.0.
|
|
65
|
-
skilleter_thingy-0.0.
|
|
66
|
-
skilleter_thingy-0.0.
|
|
67
|
-
skilleter_thingy-0.0.
|
|
68
|
-
skilleter_thingy-0.0.
|
|
69
|
-
skilleter_thingy-0.0.
|
|
64
|
+
skilleter_thingy-0.0.75.dist-info/LICENSE,sha256=ljOS4DjXvqEo5VzGfdaRwgRZPbNScGBmfwyC8PChvmQ,32422
|
|
65
|
+
skilleter_thingy-0.0.75.dist-info/METADATA,sha256=QbQfpZry6Uc_yjViSwKltz6mj4IE8hiT5ED0sBJqBIc,5313
|
|
66
|
+
skilleter_thingy-0.0.75.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
67
|
+
skilleter_thingy-0.0.75.dist-info/entry_points.txt,sha256=uW11ofmIbfPP_5B-pxb8YDkHbeZ_xeCoO6358R9wGVI,2146
|
|
68
|
+
skilleter_thingy-0.0.75.dist-info/top_level.txt,sha256=8-JhgToBBiWURunmvfpSxEvNkDHQQ7r25-aBXtZv61g,17
|
|
69
|
+
skilleter_thingy-0.0.75.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|