skilleter-thingy 0.1.25__tar.gz → 0.1.27__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.
Potentially problematic release.
This version of skilleter-thingy might be problematic. Click here for more details.
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/PKG-INFO +6 -2
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/README.md +5 -1
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/pyproject.toml +1 -1
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/multigit.py +114 -35
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy.egg-info/PKG-INFO +6 -2
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/LICENSE +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/setup.cfg +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/__init__.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/addpath.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/borger.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/console_colours.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/diskspacecheck.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/docker_purge.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/ffind.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/ggit.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/ggrep.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_br.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_ca.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_cleanup.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_co.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_common.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_hold.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_mr.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_parent.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_retag.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_review.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_update.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/git_wt.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/gitcmp_helper.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/gitprompt.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/gl.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/linecount.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/localphotosync.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/moviemover.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/photodupe.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/phototidier.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/py_audit.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/readable.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/remdir.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/rmdupe.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/rpylint.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/splitpics.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/strreplace.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/sysmon.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/tfm.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/tfparse.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/__init__.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/colour.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/dc_curses.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/dc_defaults.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/dc_util.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/dircolors.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/docker.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/files.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/git.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/git2.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/gitlab.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/path.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/popup.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/process.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/run.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/tfm_pane.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/tidy.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/venv_template.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/trimpath.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/venv_create.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/window_rename.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/xchmod.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/yamlcheck.py +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy.egg-info/SOURCES.txt +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy.egg-info/dependency_links.txt +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy.egg-info/entry_points.txt +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy.egg-info/requires.txt +0 -0
- {skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: skilleter_thingy
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.27
|
|
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
|
|
@@ -104,7 +104,7 @@ Multigit tags are stored in the configuration file, not within the working tree
|
|
|
104
104
|
|
|
105
105
|
Multigit supports a small list of subcommands, each of which are prefixed with a `+` to distinguish them from Git commands:
|
|
106
106
|
|
|
107
|
-
`+clone
|
|
107
|
+
`+clone REPO <BRANCH>` - Clone REPO (which should contain a multigit configuration file), checking out BRANCH, if specified, then clone all the repos specified in the configuration, checking out the default branch in each one.
|
|
108
108
|
|
|
109
109
|
`+init` - Create or update the configuration file
|
|
110
110
|
|
|
@@ -118,6 +118,10 @@ Multigit supports a small list of subcommands, each of which are prefixed with a
|
|
|
118
118
|
|
|
119
119
|
`+untag TAG` - Remove the tag from the specified working trees (do nothing if the tag is not applied in the first place).
|
|
120
120
|
|
|
121
|
+
`+run COMMAND` - Run the specified command in each of the specified working trees
|
|
122
|
+
|
|
123
|
+
`+add REPO DIR` - Clone REPO into the DIR directory and, if successful, add it to the multigit configuration
|
|
124
|
+
|
|
121
125
|
Any command *not* prefixed with `+` is run in each of the working trees (filtered by the various multigit options) as a git command.
|
|
122
126
|
|
|
123
127
|
For example; `multigit -m commit -ab` would run `git commit -a` in each of the working trees that is branched and contains modified files.
|
|
@@ -81,7 +81,7 @@ Multigit tags are stored in the configuration file, not within the working tree
|
|
|
81
81
|
|
|
82
82
|
Multigit supports a small list of subcommands, each of which are prefixed with a `+` to distinguish them from Git commands:
|
|
83
83
|
|
|
84
|
-
`+clone
|
|
84
|
+
`+clone REPO <BRANCH>` - Clone REPO (which should contain a multigit configuration file), checking out BRANCH, if specified, then clone all the repos specified in the configuration, checking out the default branch in each one.
|
|
85
85
|
|
|
86
86
|
`+init` - Create or update the configuration file
|
|
87
87
|
|
|
@@ -95,6 +95,10 @@ Multigit supports a small list of subcommands, each of which are prefixed with a
|
|
|
95
95
|
|
|
96
96
|
`+untag TAG` - Remove the tag from the specified working trees (do nothing if the tag is not applied in the first place).
|
|
97
97
|
|
|
98
|
+
`+run COMMAND` - Run the specified command in each of the specified working trees
|
|
99
|
+
|
|
100
|
+
`+add REPO DIR` - Clone REPO into the DIR directory and, if successful, add it to the multigit configuration
|
|
101
|
+
|
|
98
102
|
Any command *not* prefixed with `+` is run in each of the working trees (filtered by the various multigit options) as a git command.
|
|
99
103
|
|
|
100
104
|
For example; `multigit -m commit -ab` would run `git commit -a` in each of the working trees that is branched and contains modified files.
|
|
@@ -6,6 +6,7 @@ import os
|
|
|
6
6
|
import sys
|
|
7
7
|
import fnmatch
|
|
8
8
|
import configparser
|
|
9
|
+
import subprocess
|
|
9
10
|
|
|
10
11
|
from dataclasses import dataclass, field
|
|
11
12
|
|
|
@@ -27,6 +28,8 @@ import thingy.colour as colour
|
|
|
27
28
|
# DONE: command to categorise working trees then command line filter to only act on working trees in category (in addition to other filtering options) - +tag <TAG> command tags all selected working trees and updates the configuration, +untag <TAG> command to remove tags in the same way
|
|
28
29
|
# DONE: init function
|
|
29
30
|
# DONE Consistent colours in output
|
|
31
|
+
# DONE:+run command to do things other than git commands
|
|
32
|
+
# DONE: Command that takes partial working tree name and either returns full path or pops up window to autocomplete until single match found - returns list of paths you can pipe into fzf
|
|
30
33
|
#
|
|
31
34
|
# NOPE: Clone to have option to update - as discussed, should be part of init
|
|
32
35
|
# NOPE: Dry-run option - just pass the option to the Git command
|
|
@@ -36,14 +39,12 @@ import thingy.colour as colour
|
|
|
36
39
|
# NOPE: Use PathLib - Don't really see the need
|
|
37
40
|
# NOPE: When we have something with multiple matches display a menu for user to select the one that they one - make it a library routine so can be used, for instance, for branch selection - Use fzf
|
|
38
41
|
# NOPE: Use pygit2 directly - don't see the need
|
|
42
|
+
# NOPE: .init option '--update' to update the configuration file with new working trees and remove ones that are no longer there - init does the removal, and added the '+add' command instead
|
|
43
|
+
# NOPE: Ability to read default configuration options from ~/.config/thingy/multigit.rc - these are insert before argv[1] before argparse called - limited use for this
|
|
39
44
|
#
|
|
40
|
-
# TODO: 2 .init option '--update' to update the configuration file with new working trees and remove ones that are no longer there
|
|
41
|
-
# TODO: 2. +run command to do things other than git commands
|
|
42
45
|
# TODO: 2. If run in a subdirectory, only process working trees in that tree (or have an option to do so, or an option _not_ to do so; --all)
|
|
43
46
|
# TODO: 2. select_git_repos() and +dir should use consist way of selecting repos if possible
|
|
44
47
|
# TODO: 3 .init option '--set-default' to update the default branch to the current one for specified working trees
|
|
45
|
-
# TODO: 3. Ability to read default configuration options from ~/.config/thingy/multigit.rc - these are insert before argv[1] before argparse called
|
|
46
|
-
# TODO: 3. Command that takes partial working tree name and either returns full path or pops up window to autocomplete until single match found
|
|
47
48
|
# TODO: 3. Verbose option
|
|
48
49
|
# TODO: 3. When filtering by tag or by repo name, if name starts with '!' only match if tag isn't present or repo name doesn't match (and don't allow '!' at start of tag otherwise)
|
|
49
50
|
# TODO: 3. (alternative to above) A '--not' option that inverts all the matching criteria, so '--not --branched --modified' selects all unmodified repos which aren't branched
|
|
@@ -66,7 +67,7 @@ DEFAULT_BRANCH = 'DEFAULT'
|
|
|
66
67
|
# commands are parameters so we have to manually create the help and parse the command line
|
|
67
68
|
|
|
68
69
|
HELP_INFO = """usage: multigit [--help|-h] [--verbose|-v] [--quiet|-q] [--config|-c CONFIG] [--repos|-r REPOS] [--modified|-m] [--branched|-b] [--sub|-s] [--tag|-t TAGS] [--continue|-o] [--path|-C PATH]
|
|
69
|
-
{+clone, +init, +config, +dir, +list, GIT_COMMAND} ...
|
|
70
|
+
{+clone, +init, +config, +dir, +list, +run, +add, GIT_COMMAND} ...
|
|
70
71
|
|
|
71
72
|
Run git commands in multiple Git repos. DISCLAIMER: This is beta-quality software, with missing features and liable to fail with a stack trace, but shouldn't eat your data
|
|
72
73
|
|
|
@@ -86,7 +87,7 @@ options:
|
|
|
86
87
|
--path, -C PATH Run as if the command was started in PATH instead of the current working directory
|
|
87
88
|
|
|
88
89
|
Sub-commands:
|
|
89
|
-
{+clone, +init, +dir, +config, +list, GIT_COMMAND}
|
|
90
|
+
{+clone, +init, +dir, +config, +list, +run, +add, GIT_COMMAND}
|
|
90
91
|
+clone REPO {BRANCH} Clone a repo containing a multigit configuration file, then clone all the child repos and check out the default branch in each
|
|
91
92
|
+init Build or update the configuration file using the current branch in each repo as the default branch
|
|
92
93
|
+config Return the name and location of the configuration file
|
|
@@ -94,6 +95,8 @@ Sub-commands:
|
|
|
94
95
|
+list Return a list of the top level directories of each of the Git repos
|
|
95
96
|
+tag TAG Apply a configuration tag to repos filtered by the command line options (list configuration tags if no parameter specified)
|
|
96
97
|
+untag TAG Remove a configuration tag to repos filtered by the command line options
|
|
98
|
+
+run COMMAND Run the specified command in repos filtered by the command line options
|
|
99
|
+
+add REPO DIR Clone REPO into the DIR directory and add it to the multigit configuration
|
|
97
100
|
GIT_COMMAND Any git command, including options and parameters - this is then run in all specified working trees
|
|
98
101
|
|
|
99
102
|
"""
|
|
@@ -308,9 +311,37 @@ def branch_name(name, default_branch):
|
|
|
308
311
|
|
|
309
312
|
################################################################################
|
|
310
313
|
|
|
314
|
+
def add_new_repo(args, config, repo):
|
|
315
|
+
"""Add a new configuration entry containing the default branch, remote origin
|
|
316
|
+
(if there is one) and name"""
|
|
317
|
+
|
|
318
|
+
abs_repo_path = absolute_repo_path(args, repo)
|
|
319
|
+
|
|
320
|
+
config[repo] = {}
|
|
321
|
+
|
|
322
|
+
default_branch = git.branch(path=abs_repo_path)
|
|
323
|
+
|
|
324
|
+
if not default_branch:
|
|
325
|
+
colour.error(f'Unable to determine default branch in [BLUE:{repo}]', prefix=True)
|
|
326
|
+
|
|
327
|
+
config[repo]['default branch'] = default_branch
|
|
328
|
+
|
|
329
|
+
remote = git.remotes(path=abs_repo_path)
|
|
330
|
+
|
|
331
|
+
if 'origin' in remote:
|
|
332
|
+
config[repo]['origin'] = remote['origin']
|
|
333
|
+
config[repo]['repo name'] = os.path.basename(remote['origin']).removesuffix('.git')
|
|
334
|
+
else:
|
|
335
|
+
config[repo]['repo name'] = os.path.basename(repo)
|
|
336
|
+
|
|
337
|
+
if not args.quiet:
|
|
338
|
+
colour.write(f'Added [BLUE:{repo}] with default branch [BLUE:{default_branch}]')
|
|
339
|
+
|
|
340
|
+
################################################################################
|
|
341
|
+
|
|
311
342
|
def mg_clone(args, config, console):
|
|
312
343
|
"""Clone a repo, optionally check out a branch and attempt to read the
|
|
313
|
-
configuration file and clone all the repos listed therein, checkouting
|
|
344
|
+
multigit configuration file and clone all the repos listed therein, checkouting
|
|
314
345
|
the default branch in each one"""
|
|
315
346
|
|
|
316
347
|
_ = console
|
|
@@ -399,29 +430,7 @@ def mg_init(args, config, console):
|
|
|
399
430
|
repo_list.append(repo)
|
|
400
431
|
|
|
401
432
|
if repo not in config:
|
|
402
|
-
|
|
403
|
-
# (if there is one) and name
|
|
404
|
-
|
|
405
|
-
abs_repo_path = absolute_repo_path(args, repo)
|
|
406
|
-
|
|
407
|
-
config[repo] = {}
|
|
408
|
-
|
|
409
|
-
default_branch = git.branch(path=abs_repo_path)
|
|
410
|
-
|
|
411
|
-
if not default_branch:
|
|
412
|
-
colour.error(f'Unable to determine default branch in [BLUE:{repo}]', prefix=True)
|
|
413
|
-
|
|
414
|
-
config[repo]['default branch'] = default_branch
|
|
415
|
-
|
|
416
|
-
remote = git.remotes(path=abs_repo_path)
|
|
417
|
-
|
|
418
|
-
if 'origin' in remote:
|
|
419
|
-
config[repo]['origin'] = remote['origin']
|
|
420
|
-
config[repo]['repo name'] = os.path.basename(remote['origin']).removesuffix('.git')
|
|
421
|
-
else:
|
|
422
|
-
config[repo]['repo name'] = os.path.basename(repo)
|
|
423
|
-
|
|
424
|
-
colour.write(f'Added [BLUE:{repo}] with default branch [BLUE:{default_branch}]')
|
|
433
|
+
add_new_repo(args, config, repo)
|
|
425
434
|
|
|
426
435
|
if not args.quiet:
|
|
427
436
|
colour.write(cleareol=True)
|
|
@@ -444,6 +453,39 @@ def mg_init(args, config, console):
|
|
|
444
453
|
|
|
445
454
|
################################################################################
|
|
446
455
|
|
|
456
|
+
def mg_add(args, config, console):
|
|
457
|
+
"""Add a new repo - takes 2 parameters; the repo to clone and the directory
|
|
458
|
+
to clone it into. If successful, adds the repo to the configuration"""
|
|
459
|
+
|
|
460
|
+
_ = console
|
|
461
|
+
_ = config
|
|
462
|
+
|
|
463
|
+
verbose(args, f'add: Parameters: {", ".join(args.parameters)}')
|
|
464
|
+
|
|
465
|
+
if len(args.parameters) != 2:
|
|
466
|
+
colour.error('The "[BOLD:+add]" command takes two parameters; the repo to clone the location to clone it into', prefix=True)
|
|
467
|
+
|
|
468
|
+
if args.modified or args.branched or args.tag or args.subdirectories:
|
|
469
|
+
colour.error('The "[BOLD:--tag]", "[BOLD:--modified]" "[BOLD:--sub]", and "[BOLD:--branched]" options cannot be used with the "[BOLD:+add]" subcommand', prefix=True)
|
|
470
|
+
|
|
471
|
+
repo = args.parameters[0]
|
|
472
|
+
location = args.parameters[1]
|
|
473
|
+
|
|
474
|
+
if os.path.exists(location):
|
|
475
|
+
colour.error(f'"[BLUE:{location}]" already exists', prefix=True)
|
|
476
|
+
|
|
477
|
+
git.clone(repo, path=location)
|
|
478
|
+
|
|
479
|
+
# Add to the configuration
|
|
480
|
+
|
|
481
|
+
add_new_repo(args, config, location)
|
|
482
|
+
|
|
483
|
+
# The configuration file needs to be updated
|
|
484
|
+
|
|
485
|
+
args.config_modified = True
|
|
486
|
+
|
|
487
|
+
################################################################################
|
|
488
|
+
|
|
447
489
|
def mg_dir(args, config, console):
|
|
448
490
|
"""Return the location of a working tree, given the name, or the root directory
|
|
449
491
|
of the tree if not
|
|
@@ -571,12 +613,43 @@ def mg_list(args, config, console):
|
|
|
571
613
|
|
|
572
614
|
################################################################################
|
|
573
615
|
|
|
574
|
-
def
|
|
616
|
+
def mg_run(args, config, console):
|
|
575
617
|
"""Run a command in each of the working trees, optionally continuing if
|
|
576
618
|
there's an error"""
|
|
577
619
|
|
|
578
620
|
_ = console
|
|
579
621
|
|
|
622
|
+
if not args.parameters:
|
|
623
|
+
colour.error('[BOLD:+run] command - missing parameter(s)')
|
|
624
|
+
|
|
625
|
+
# Run the command in each of the working trees
|
|
626
|
+
|
|
627
|
+
for repo in select_git_repos(args, config):
|
|
628
|
+
if not args.quiet:
|
|
629
|
+
colour.write(f'\n[BLUE:{os.path.relpath(repo.name)}]\n')
|
|
630
|
+
|
|
631
|
+
repo_path = absolute_repo_path(args, repo.name)
|
|
632
|
+
|
|
633
|
+
try:
|
|
634
|
+
status = subprocess.run(args.parameters, cwd=repo_path, check=False)
|
|
635
|
+
except FileNotFoundError:
|
|
636
|
+
err_msg = f'"[BLUE:{args.parameters[0]}]" - Command not found'
|
|
637
|
+
if args.error_continue:
|
|
638
|
+
colour.write(f'[RED:WARNING]: {err_msg}')
|
|
639
|
+
else:
|
|
640
|
+
colour.error(f'[RED:ERROR]: {err_msg}')
|
|
641
|
+
else:
|
|
642
|
+
if status.returncode and not args.error_continue:
|
|
643
|
+
sys.exit(status)
|
|
644
|
+
|
|
645
|
+
################################################################################
|
|
646
|
+
|
|
647
|
+
def run_git_command(args, config, console):
|
|
648
|
+
"""Run a Git command in each of the working trees, optionally continuing if
|
|
649
|
+
there's an error"""
|
|
650
|
+
|
|
651
|
+
_ = console
|
|
652
|
+
|
|
580
653
|
for repo in select_git_repos(args, config):
|
|
581
654
|
repo_command = [args.command]
|
|
582
655
|
|
|
@@ -585,9 +658,10 @@ def run_git_command(args, config, console):
|
|
|
585
658
|
for cmd in args.parameters:
|
|
586
659
|
repo_command.append(branch_name(cmd, repo['default branch']))
|
|
587
660
|
|
|
588
|
-
|
|
661
|
+
if not args.quiet:
|
|
662
|
+
colour.write(f'\n[BLUE:{os.path.relpath(repo.name)}]\n')
|
|
589
663
|
|
|
590
|
-
# Run the command in the
|
|
664
|
+
# Run the command in the working tree
|
|
591
665
|
|
|
592
666
|
repo_path = absolute_repo_path(args, repo.name)
|
|
593
667
|
|
|
@@ -680,11 +754,12 @@ def parse_command_line():
|
|
|
680
754
|
colour.error('The "[BOLD:--path]" option takes a path parameter')
|
|
681
755
|
|
|
682
756
|
try:
|
|
683
|
-
|
|
757
|
+
workingdir = arg_list.pop(0)
|
|
758
|
+
os.chdir(workingdir)
|
|
684
759
|
except IndexError:
|
|
685
760
|
colour.error('The "[BOLD:-C]" option takes a path parameter', prefix=True)
|
|
686
761
|
except FileNotFoundError:
|
|
687
|
-
colour.error('"[BOLD:--path]" - path not found', prefix=True)
|
|
762
|
+
colour.error(f'"[BOLD:--path]" - path "[BLUE:{workingdir}]" not found', prefix=True)
|
|
688
763
|
|
|
689
764
|
elif option in ('help', 'h'):
|
|
690
765
|
colour.write(HELP_INFO)
|
|
@@ -729,6 +804,8 @@ COMMANDS = {
|
|
|
729
804
|
'tag': mg_tag,
|
|
730
805
|
'untag': mg_untag,
|
|
731
806
|
'list': mg_list,
|
|
807
|
+
'run': mg_run,
|
|
808
|
+
'add': mg_add,
|
|
732
809
|
}
|
|
733
810
|
|
|
734
811
|
def main():
|
|
@@ -811,6 +888,8 @@ def multigit():
|
|
|
811
888
|
|
|
812
889
|
except git.GitError as exc:
|
|
813
890
|
sys.stderr.write(exc.msg)
|
|
891
|
+
sys.stderr.write('\n')
|
|
892
|
+
|
|
814
893
|
sys.exit(exc.status)
|
|
815
894
|
|
|
816
895
|
################################################################################
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: skilleter_thingy
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.27
|
|
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
|
|
@@ -104,7 +104,7 @@ Multigit tags are stored in the configuration file, not within the working tree
|
|
|
104
104
|
|
|
105
105
|
Multigit supports a small list of subcommands, each of which are prefixed with a `+` to distinguish them from Git commands:
|
|
106
106
|
|
|
107
|
-
`+clone
|
|
107
|
+
`+clone REPO <BRANCH>` - Clone REPO (which should contain a multigit configuration file), checking out BRANCH, if specified, then clone all the repos specified in the configuration, checking out the default branch in each one.
|
|
108
108
|
|
|
109
109
|
`+init` - Create or update the configuration file
|
|
110
110
|
|
|
@@ -118,6 +118,10 @@ Multigit supports a small list of subcommands, each of which are prefixed with a
|
|
|
118
118
|
|
|
119
119
|
`+untag TAG` - Remove the tag from the specified working trees (do nothing if the tag is not applied in the first place).
|
|
120
120
|
|
|
121
|
+
`+run COMMAND` - Run the specified command in each of the specified working trees
|
|
122
|
+
|
|
123
|
+
`+add REPO DIR` - Clone REPO into the DIR directory and, if successful, add it to the multigit configuration
|
|
124
|
+
|
|
121
125
|
Any command *not* prefixed with `+` is run in each of the working trees (filtered by the various multigit options) as a git command.
|
|
122
126
|
|
|
123
127
|
For example; `multigit -m commit -ab` would run `git commit -a` in each of the working trees that is branched and contains modified files.
|
|
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
|
|
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
|
|
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
|
|
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
|
{skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy/thingy/venv_template.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{skilleter_thingy-0.1.25 → skilleter_thingy-0.1.27}/skilleter_thingy.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|