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.

@@ -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: [ ] Use the configuration file
32
- # TODO: [ ] Don't use a fixed list of default branch names
33
- # TODO: [ ] / Output name of each git repo as it is processed as command sits there seeming to do nothing otherwise.
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='Gitlab commands')
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
  ################################################################################
@@ -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.74
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=2E3lizBNO4o0zJzg-nPA38ogj3c-RMaSK6HpqIVBMDc,12178
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=jh2zNsQB6d-nROTPZXbeHCXG9TQIDV8ItsHhdGoeQk0,35752
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.74.dist-info/LICENSE,sha256=ljOS4DjXvqEo5VzGfdaRwgRZPbNScGBmfwyC8PChvmQ,32422
65
- skilleter_thingy-0.0.74.dist-info/METADATA,sha256=PGTpGZ8NmFGHyRJDykHfY3anHyLU3W1X-CFasmWH83k,5313
66
- skilleter_thingy-0.0.74.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
67
- skilleter_thingy-0.0.74.dist-info/entry_points.txt,sha256=uW11ofmIbfPP_5B-pxb8YDkHbeZ_xeCoO6358R9wGVI,2146
68
- skilleter_thingy-0.0.74.dist-info/top_level.txt,sha256=8-JhgToBBiWURunmvfpSxEvNkDHQQ7r25-aBXtZv61g,17
69
- skilleter_thingy-0.0.74.dist-info/RECORD,,
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,,