skilleter-thingy 0.0.79__tar.gz → 0.0.81__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.0.79/skilleter_thingy.egg-info → skilleter_thingy-0.0.81}/PKG-INFO +1 -1
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/pyproject.toml +1 -1
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/git_review.py +20 -6
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/multigit.py +239 -115
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/git2.py +13 -7
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81/skilleter_thingy.egg-info}/PKG-INFO +1 -1
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/LICENSE +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/README.md +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/setup.cfg +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/__init__.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/addpath.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/borger.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/box.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/console_colours.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/diskspacecheck.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/docker_purge.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/ffind.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/ggit.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/ggrep.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/git_br.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/git_ca.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/git_cleanup.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/git_co.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/git_common.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/git_hold.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/git_mr.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/git_parent.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/git_update.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/git_wt.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/gitcmp_helper.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/gitprompt.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/gl.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/gphotosync.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/linecount.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/moviemover.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/photodupe.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/phototidier.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/py_audit.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/readable.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/remdir.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/rmdupe.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/rpylint.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/splitpics.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/strreplace.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/sysmon.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/tfm.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/tfparse.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/__init__.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/colour.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/dc_curses.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/dc_defaults.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/dc_util.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/dircolors.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/docker.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/files.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/git.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/gitlab.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/path.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/popup.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/process.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/run.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/tfm_pane.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/tidy.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/thingy/venv_template.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/trimpath.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/venv_create.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/window_rename.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/xchmod.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy/yamlcheck.py +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy.egg-info/SOURCES.txt +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy.egg-info/dependency_links.txt +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy.egg-info/entry_points.txt +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy.egg-info/requires.txt +0 -0
- {skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: skilleter_thingy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.81
|
|
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
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
Copyright (C) 2020 John Skilleter
|
|
7
7
|
|
|
8
8
|
TODO:
|
|
9
|
+
* Check for nothing to review before starting curses to avoid screen flicker when we start and immediately quit.
|
|
9
10
|
* Use inotify to watch files in the review and prompt to reload if they have changed
|
|
10
11
|
* Better status line
|
|
11
12
|
* Mouse functionality?
|
|
@@ -17,14 +18,13 @@
|
|
|
17
18
|
* add command
|
|
18
19
|
* commit command
|
|
19
20
|
* ability to embed colour changes in strings when writing with curses
|
|
20
|
-
* if no changes, screen should not flicker (it activates them immediately deactives curses)
|
|
21
21
|
* Bottom line of the display should be menu that changes to a prompt if necc when running a command
|
|
22
22
|
* Scroll, rather than jump, when moving down off the bottom of the screen - start scrolling when within 10% of top or bottom
|
|
23
23
|
* Bottom line of display should show details of current file rather than help?
|
|
24
24
|
* Mark/Unmark as reviewed by wildcard
|
|
25
25
|
* Think that maintaining the list of files as a dictionary may be better than a list
|
|
26
26
|
* Filter in/out new/deleted files
|
|
27
|
-
* Universal filter dialog replace individual
|
|
27
|
+
* Universal filter dialog replace individual options and allow selection of:
|
|
28
28
|
* Show: all / deleted / updated files
|
|
29
29
|
* Show: all / wildcard match / wildcard non-match
|
|
30
30
|
* Show: all / reviewed / unreviewed files
|
|
@@ -194,11 +194,11 @@ class PopUp():
|
|
|
194
194
|
if self.waitkey:
|
|
195
195
|
while True:
|
|
196
196
|
keypress = self.screen.getch()
|
|
197
|
-
if keypress
|
|
198
|
-
break
|
|
199
|
-
else:
|
|
197
|
+
if keypress == curses.KEY_RESIZE:
|
|
200
198
|
curses.panel.update_panels()
|
|
201
199
|
self.screen.refresh()
|
|
200
|
+
else:
|
|
201
|
+
break
|
|
202
202
|
|
|
203
203
|
def __exit__(self, exc_type, exc_value, exc_traceback):
|
|
204
204
|
""" Remove the popup """
|
|
@@ -293,6 +293,7 @@ class GitReview():
|
|
|
293
293
|
self.show_none_whitespace_stats = False
|
|
294
294
|
|
|
295
295
|
self.finished = False
|
|
296
|
+
self.status_code = 0
|
|
296
297
|
|
|
297
298
|
# Use paths relative to the current directory
|
|
298
299
|
|
|
@@ -386,6 +387,7 @@ class GitReview():
|
|
|
386
387
|
ord('e'): {'help': 'Edit the current file', 'function': self.__key_edit_file},
|
|
387
388
|
ord('s'): {'help': 'Cycle sort order', 'function': self.__key_cycle_search},
|
|
388
389
|
ord('S'): {'help': 'Reverse sort order', 'function': self.__key_reverse_sort},
|
|
390
|
+
3: {'help': 'Exit', 'function': self.__key_error_review},
|
|
389
391
|
}
|
|
390
392
|
|
|
391
393
|
################################################################################
|
|
@@ -920,6 +922,14 @@ class GitReview():
|
|
|
920
922
|
|
|
921
923
|
################################################################################
|
|
922
924
|
|
|
925
|
+
def __key_error_review(self):
|
|
926
|
+
""" Quit with an error"""
|
|
927
|
+
|
|
928
|
+
self.finished = True
|
|
929
|
+
self.status_code = 1
|
|
930
|
+
|
|
931
|
+
################################################################################
|
|
932
|
+
|
|
923
933
|
def __key_toggle_reviewed(self):
|
|
924
934
|
""" Toggle mark file as reviewed and move down unless hide mode enabled
|
|
925
935
|
and file is now hidden """
|
|
@@ -1406,6 +1416,8 @@ def main(screen, args):
|
|
|
1406
1416
|
|
|
1407
1417
|
review.save_state()
|
|
1408
1418
|
|
|
1419
|
+
return review.status_code
|
|
1420
|
+
|
|
1409
1421
|
################################################################################
|
|
1410
1422
|
|
|
1411
1423
|
def git_review():
|
|
@@ -1414,7 +1426,9 @@ def git_review():
|
|
|
1414
1426
|
try:
|
|
1415
1427
|
command_args = parse_command_line()
|
|
1416
1428
|
|
|
1417
|
-
curses.wrapper(main, command_args)
|
|
1429
|
+
statcode = curses.wrapper(main, command_args)
|
|
1430
|
+
|
|
1431
|
+
sys.exit(statcode)
|
|
1418
1432
|
|
|
1419
1433
|
except KeyboardInterrupt:
|
|
1420
1434
|
sys.exit(1)
|
|
@@ -8,6 +8,7 @@ import argparse
|
|
|
8
8
|
import fnmatch
|
|
9
9
|
import configparser
|
|
10
10
|
import shlex
|
|
11
|
+
import pathlib
|
|
11
12
|
from collections import defaultdict
|
|
12
13
|
|
|
13
14
|
import thingy.git2 as git
|
|
@@ -15,35 +16,32 @@ import thingy.colour as colour
|
|
|
15
16
|
|
|
16
17
|
################################################################################
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# TODO:
|
|
28
|
-
#
|
|
29
|
-
# TODO:
|
|
30
|
-
# TODO:
|
|
31
|
-
# TODO:
|
|
32
|
-
# TODO:
|
|
33
|
-
# TODO:
|
|
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
|
-
# TODO: [ ] When specifying list of repos, if repo name doesn't contain '/' prefix it with '*'?
|
|
41
|
-
# TODO: [ ] Switch to tomlkit
|
|
19
|
+
# DONE: / Output name of each git repo as it is processed as command sits there seeming to do nothing otherwise.
|
|
20
|
+
# DONE: Don't save the configuration on exit if it hasn't changed
|
|
21
|
+
# DONE: Don't use a fixed list of default branch names
|
|
22
|
+
# DONE: Use the configuration file
|
|
23
|
+
# DONE: init function
|
|
24
|
+
# TODO: -j option to run in parallel?
|
|
25
|
+
# TODO: Pull/fetch - only output after running command and only if something updated
|
|
26
|
+
# TODO: Better error-handling - e.g. continue/abort option after failure in one repo
|
|
27
|
+
# TODO: Consistent colours in output
|
|
28
|
+
# TODO: Dry-run option
|
|
29
|
+
# DONE: If the config file isn't in the current directory then search up the directory tree for it but run in the current directory
|
|
30
|
+
# TODO: If run in a subdirectory, only process repos in that tree (or have an option to do so)
|
|
31
|
+
# TODO: Is it going to be a problem if the same repo is checked out twice or more in the same workspace
|
|
32
|
+
# TODO: Switch to tomlkit
|
|
33
|
+
# TODO: Verbose option
|
|
34
|
+
# TODO: When specifying list of repos, if repo name doesn't contain '/' prefix it with '*'?
|
|
42
35
|
|
|
43
36
|
################################################################################
|
|
44
37
|
|
|
45
38
|
DEFAULT_CONFIG_FILE = 'multigit.toml'
|
|
46
39
|
|
|
40
|
+
# If a branch name is specified as 'DEFAULT' then the default branch for the
|
|
41
|
+
# repo is used instead.
|
|
42
|
+
|
|
43
|
+
DEFAULT_BRANCH = 'DEFAULT'
|
|
44
|
+
|
|
47
45
|
################################################################################
|
|
48
46
|
|
|
49
47
|
def error(msg, status=1):
|
|
@@ -68,7 +66,7 @@ def show_progress(width, msg):
|
|
|
68
66
|
|
|
69
67
|
################################################################################
|
|
70
68
|
|
|
71
|
-
def find_git_repos(
|
|
69
|
+
def find_git_repos(args):
|
|
72
70
|
"""Locate and return a list of '.git' directory parent directories in the
|
|
73
71
|
specified path.
|
|
74
72
|
|
|
@@ -79,13 +77,13 @@ def find_git_repos(directory, wildcard):
|
|
|
79
77
|
|
|
80
78
|
repos = set()
|
|
81
79
|
|
|
82
|
-
for root, dirs, _ in os.walk(directory):
|
|
80
|
+
for root, dirs, _ in os.walk(args.directory):
|
|
83
81
|
if '.git' in dirs:
|
|
84
82
|
if root.startswith('./'):
|
|
85
83
|
root = root[2:]
|
|
86
84
|
|
|
87
|
-
if
|
|
88
|
-
for card in
|
|
85
|
+
if args.repos:
|
|
86
|
+
for card in args.repos:
|
|
89
87
|
if fnmatch.fnmatch(root, card):
|
|
90
88
|
if root not in repos:
|
|
91
89
|
yield root
|
|
@@ -98,18 +96,74 @@ def find_git_repos(directory, wildcard):
|
|
|
98
96
|
|
|
99
97
|
################################################################################
|
|
100
98
|
|
|
99
|
+
def select_git_repos(args, config):
|
|
100
|
+
"""Return git repos from the configuration that match the criteria on the
|
|
101
|
+
multigit command line (the --repos, --modified and --branched options)
|
|
102
|
+
or, return them all if no relevant options specified"""
|
|
103
|
+
|
|
104
|
+
for repo in config.sections():
|
|
105
|
+
# If wildcards are specified, then only match wildcards
|
|
106
|
+
|
|
107
|
+
if args.repos:
|
|
108
|
+
for card in args.repos:
|
|
109
|
+
if fnmatch.fnmatch(repo, card):
|
|
110
|
+
matching = True
|
|
111
|
+
break
|
|
112
|
+
else:
|
|
113
|
+
matching = False
|
|
114
|
+
else:
|
|
115
|
+
matching = True
|
|
116
|
+
|
|
117
|
+
# If branched specified, only match if the repo is matched _and_ branched
|
|
118
|
+
|
|
119
|
+
if matching and args.branched:
|
|
120
|
+
if git.branch(path=repo) == config[repo]['default branch']:
|
|
121
|
+
matching = False
|
|
122
|
+
|
|
123
|
+
# If modified specified, only match if the repo is matched _and_ modified
|
|
124
|
+
|
|
125
|
+
if matching and args.modified:
|
|
126
|
+
if not git.status(path=repo):
|
|
127
|
+
matching = False
|
|
128
|
+
|
|
129
|
+
if matching:
|
|
130
|
+
yield config[repo]
|
|
131
|
+
|
|
132
|
+
################################################################################
|
|
133
|
+
|
|
134
|
+
def branch_name(name, default_branch):
|
|
135
|
+
"""If name is None or DEFAULT_BRANCH return default_branch, otherwise return name"""
|
|
136
|
+
|
|
137
|
+
return default_branch if not name or name == DEFAULT_BRANCH else name
|
|
138
|
+
|
|
139
|
+
################################################################################
|
|
140
|
+
|
|
141
|
+
def run_git_status(cmd, path, cont=False, redirect=True):
|
|
142
|
+
|
|
143
|
+
output, status = git.git_run_status(cmd, path=path, redirect=redirect)
|
|
144
|
+
|
|
145
|
+
if output:
|
|
146
|
+
colour.write(f'[BOLD:{path}]')
|
|
147
|
+
colour.write()
|
|
148
|
+
colour.write(output, indent=4)
|
|
149
|
+
|
|
150
|
+
if status and not cont:
|
|
151
|
+
sys.exit(status)
|
|
152
|
+
|
|
153
|
+
################################################################################
|
|
154
|
+
|
|
101
155
|
def mg_init(args, config, console):
|
|
102
156
|
"""Create or update the configuration
|
|
103
157
|
By default, it scans the tree for git directories and adds or updates them
|
|
104
158
|
in the configuration, using the current branch as the default branch. """
|
|
105
159
|
|
|
106
|
-
# TODO:
|
|
160
|
+
# TODO: Update should remove or warn about repos that are no longer present
|
|
107
161
|
|
|
108
162
|
# Search for .git directories
|
|
109
163
|
|
|
110
|
-
for repo in find_git_repos(args
|
|
164
|
+
for repo in find_git_repos(args):
|
|
111
165
|
if not args.quiet:
|
|
112
|
-
show_progress(console.columns, repo)
|
|
166
|
+
show_progress(console.columns, repo.name)
|
|
113
167
|
|
|
114
168
|
if not repo in config:
|
|
115
169
|
config[repo] = {
|
|
@@ -129,20 +183,20 @@ def mg_init(args, config, console):
|
|
|
129
183
|
def mg_status(args, config, console):
|
|
130
184
|
"""Report Git status for any repo that has a non-empty status"""
|
|
131
185
|
|
|
132
|
-
# TODO:
|
|
186
|
+
# TODO: More user-friendly output
|
|
133
187
|
|
|
134
|
-
for repo in
|
|
188
|
+
for repo in select_git_repos(args, config):
|
|
135
189
|
if not args.quiet:
|
|
136
|
-
show_progress(console.columns, repo)
|
|
190
|
+
show_progress(console.columns, repo.name)
|
|
137
191
|
|
|
138
|
-
status = git.status(path=repo)
|
|
139
|
-
branch = git.branch(path=repo)
|
|
192
|
+
status = git.status(path=repo.name)
|
|
193
|
+
branch = git.branch(path=repo.name)
|
|
140
194
|
|
|
141
|
-
if status or branch !=
|
|
142
|
-
if branch ==
|
|
143
|
-
colour.write(f'[BOLD:{repo}]')
|
|
195
|
+
if status or branch != repo['default branch']:
|
|
196
|
+
if branch == repo['default branch']:
|
|
197
|
+
colour.write(f'[BOLD:{repo.name}]')
|
|
144
198
|
else:
|
|
145
|
-
colour.write(f'[BOLD:{repo}] - branch: [BLUE:{branch}]')
|
|
199
|
+
colour.write(f'[BOLD:{repo.name}] - branch: [BLUE:{branch}]')
|
|
146
200
|
|
|
147
201
|
staged = defaultdict(list)
|
|
148
202
|
unstaged = defaultdict(list)
|
|
@@ -206,16 +260,18 @@ def mg_status(args, config, console):
|
|
|
206
260
|
def mg_fetch(args, config, console):
|
|
207
261
|
"""Run git fetch everywhere"""
|
|
208
262
|
|
|
209
|
-
|
|
263
|
+
_ = config
|
|
264
|
+
|
|
265
|
+
for repo in select_git_repos(args, config):
|
|
210
266
|
if not args.quiet:
|
|
211
|
-
show_progress(console.columns, repo)
|
|
267
|
+
show_progress(console.columns, repo.name)
|
|
212
268
|
|
|
213
|
-
colour.write(f'Fetching updates for [BLUE:{repo}]')
|
|
269
|
+
colour.write(f'Fetching updates for [BLUE:{repo.name}]')
|
|
214
270
|
|
|
215
|
-
result = git.fetch(path=repo)
|
|
271
|
+
result = git.fetch(path=repo.name)
|
|
216
272
|
|
|
217
273
|
if result:
|
|
218
|
-
colour.write(f'[BOLD:{repo}]')
|
|
274
|
+
colour.write(f'[BOLD:{repo.name}]')
|
|
219
275
|
for item in result:
|
|
220
276
|
if item.startswith('From '):
|
|
221
277
|
colour.write(f' [BLUE:{item}]')
|
|
@@ -229,19 +285,21 @@ def mg_fetch(args, config, console):
|
|
|
229
285
|
def mg_pull(args, config, console):
|
|
230
286
|
"""Run git pull everywhere"""
|
|
231
287
|
|
|
232
|
-
|
|
288
|
+
_ = config
|
|
289
|
+
|
|
290
|
+
for repo in select_git_repos(args, config):
|
|
233
291
|
if not args.quiet:
|
|
234
|
-
show_progress(console.columns, repo)
|
|
292
|
+
show_progress(console.columns, repo.name)
|
|
235
293
|
|
|
236
|
-
colour.write(f'Pulling updates for [BLUE:{repo}]')
|
|
294
|
+
colour.write(f'Pulling updates for [BLUE:{repo.name}]')
|
|
237
295
|
|
|
238
296
|
try:
|
|
239
|
-
result = git.pull(path=repo)
|
|
297
|
+
result = git.pull(path=repo.name)
|
|
240
298
|
except git.GitError as exc:
|
|
241
|
-
error(f'Error in {repo}: {exc}')
|
|
299
|
+
error(f'Error in {repo.name}: {exc}')
|
|
242
300
|
|
|
243
301
|
if result and result[0] != 'Already up-to-date.':
|
|
244
|
-
colour.write(f'[BOLD:{repo}]')
|
|
302
|
+
colour.write(f'[BOLD:{repo.name}]')
|
|
245
303
|
for item in result:
|
|
246
304
|
if item.startswith('Updating'):
|
|
247
305
|
colour.write(f' [BLUE:{item}]')
|
|
@@ -257,19 +315,19 @@ def mg_push(args, config, console):
|
|
|
257
315
|
and where the most recent commit was the current user and was on the branch
|
|
258
316
|
"""
|
|
259
317
|
|
|
260
|
-
#
|
|
261
|
-
# TODO:
|
|
318
|
+
# DONE: Add option for force-push?
|
|
319
|
+
# TODO: Add option for manual confirmation?
|
|
262
320
|
|
|
263
|
-
for repo in
|
|
321
|
+
for repo in select_git_repos(args, config):
|
|
264
322
|
if not args.quiet:
|
|
265
|
-
show_progress(console.columns, repo)
|
|
323
|
+
show_progress(console.columns, repo.name)
|
|
266
324
|
|
|
267
|
-
branch = git.branch(path=repo)
|
|
325
|
+
branch = git.branch(path=repo.name)
|
|
268
326
|
|
|
269
|
-
if branch !=
|
|
270
|
-
colour.write(f'Pushing changes to [BLUE:{branch}] in [BOLD:{repo}]')
|
|
327
|
+
if branch != repo['default branch']:
|
|
328
|
+
colour.write(f'Pushing changes to [BLUE:{branch}] in [BOLD:{repo.name}]')
|
|
271
329
|
|
|
272
|
-
result = git.push(path=repo, force_with_lease=args.force)
|
|
330
|
+
result = git.push(path=repo.name, force_with_lease=args.force)
|
|
273
331
|
|
|
274
332
|
if result:
|
|
275
333
|
colour.write(result, indent=4)
|
|
@@ -284,21 +342,21 @@ def mg_checkout(args, config, console):
|
|
|
284
342
|
if the branch exists in the repo.
|
|
285
343
|
If the 'create' option is specified then branch is created"""
|
|
286
344
|
|
|
287
|
-
# TODO:
|
|
288
|
-
# TODO:
|
|
289
|
-
# TODO:
|
|
290
|
-
# TODO:
|
|
345
|
+
# TODO: Add --create handling
|
|
346
|
+
# TODO: Checkout remote branches
|
|
347
|
+
# TODO: only try checkout if branch exists
|
|
348
|
+
# TODO: option to fetch before checking out
|
|
291
349
|
|
|
292
|
-
for repo in
|
|
350
|
+
for repo in select_git_repos(args, config):
|
|
293
351
|
if not args.quiet:
|
|
294
|
-
show_progress(console.columns, repo)
|
|
352
|
+
show_progress(console.columns, repo.name)
|
|
295
353
|
|
|
296
|
-
branch = args.branch or
|
|
354
|
+
branch = branch_name(args.branch or repo.name['default branch'])
|
|
297
355
|
|
|
298
|
-
if git.branch(path=repo) != branch:
|
|
299
|
-
colour.write(f'Checking out [BLUE:{branch}] in [BOLD:{repo}]')
|
|
356
|
+
if git.branch(path=repo.name) != branch:
|
|
357
|
+
colour.write(f'Checking out [BLUE:{branch}] in [BOLD:{repo.name}]')
|
|
300
358
|
|
|
301
|
-
git.checkout(branch, create=args.create, path=repo)
|
|
359
|
+
git.checkout(branch, create=args.create, path=repo.name)
|
|
302
360
|
|
|
303
361
|
################################################################################
|
|
304
362
|
|
|
@@ -306,21 +364,21 @@ def mg_commit(args, config, console):
|
|
|
306
364
|
"""For every repo that has a branch checked out and changes present,
|
|
307
365
|
commit those changes onto the branch"""
|
|
308
366
|
|
|
309
|
-
#
|
|
310
|
-
#
|
|
311
|
-
#
|
|
367
|
+
# DONE: Option to amend the commit if it is not the first one on the current branch
|
|
368
|
+
# DONE: Prevent commits if current branch is the default branch
|
|
369
|
+
# DONE: Option to specify wildcard for files to commit (default is all files)
|
|
312
370
|
|
|
313
|
-
for repo in
|
|
371
|
+
for repo in select_git_repos(args, config):
|
|
314
372
|
if not args.quiet:
|
|
315
|
-
show_progress(console.columns, repo)
|
|
373
|
+
show_progress(console.columns, repo.name)
|
|
316
374
|
|
|
317
|
-
branch = git.branch(path=repo)
|
|
318
|
-
modified = git.status(path=repo)
|
|
375
|
+
branch = git.branch(path=repo.name)
|
|
376
|
+
modified = git.status(path=repo.name)
|
|
319
377
|
|
|
320
|
-
if branch !=
|
|
321
|
-
colour.write(f'Committing [BOLD:{len(modified)}] changes onto [BLUE:{branch}] branch in [BOLD:{repo}]')
|
|
378
|
+
if branch != repo['default branch'] and modified:
|
|
379
|
+
colour.write(f'Committing [BOLD:{len(modified)}] changes onto [BLUE:{branch}] branch in [BOLD:{repo.name}]')
|
|
322
380
|
|
|
323
|
-
git.commit(all=True, message=args.message, path=repo)
|
|
381
|
+
git.commit(all=True, message=args.message, path=repo.name)
|
|
324
382
|
|
|
325
383
|
################################################################################
|
|
326
384
|
|
|
@@ -328,28 +386,37 @@ def mg_update(args, config, console):
|
|
|
328
386
|
"""For every repo, pull the default branch and if the current branch
|
|
329
387
|
is not the default branch, rebase it onto the default branch"""
|
|
330
388
|
|
|
331
|
-
# TODO:
|
|
332
|
-
# TODO:
|
|
333
|
-
# TODO:
|
|
334
|
-
# TODO:
|
|
389
|
+
# TODO: Option to pull current branch
|
|
390
|
+
# TODO: Use git-update
|
|
391
|
+
# TODO: Option to delete current branch before pulling (to get updates without conflicts)
|
|
392
|
+
# TODO: Option to stash changes on current branch before updating and unstash afterwards
|
|
335
393
|
|
|
336
|
-
for repo in
|
|
394
|
+
for repo in select_git_repos(args, config):
|
|
337
395
|
if not args.quiet:
|
|
338
|
-
show_progress(console.columns, repo)
|
|
396
|
+
show_progress(console.columns, repo.name)
|
|
339
397
|
|
|
340
|
-
branch = git.branch(path=repo)
|
|
341
|
-
default_branch =
|
|
398
|
+
branch = git.branch(path=repo.name)
|
|
399
|
+
default_branch = repo['default branch']
|
|
342
400
|
|
|
343
|
-
colour.write(f'Updating branch [BLUE:{branch}] in [BOLD:{repo}]')
|
|
401
|
+
colour.write(f'Updating branch [BLUE:{branch}] in [BOLD:{repo.name}]')
|
|
344
402
|
|
|
345
403
|
if branch != default_branch:
|
|
346
|
-
|
|
404
|
+
if not args.quiet:
|
|
405
|
+
colour.write(f'Checking out [BLUE:{default_branch}]', indent=4)
|
|
347
406
|
|
|
348
|
-
|
|
407
|
+
git.checkout(default_branch, path=repo.name)
|
|
408
|
+
|
|
409
|
+
if not args.quiet:
|
|
410
|
+
colour.write(f'Pulling updates from remote', indent=4)
|
|
411
|
+
|
|
412
|
+
git.pull(path=repo.name)
|
|
349
413
|
|
|
350
414
|
if branch != default_branch:
|
|
351
|
-
|
|
352
|
-
|
|
415
|
+
if not args.quiet:
|
|
416
|
+
colour.write(f'Checking out [BLUE:{branch}] and rebasing against [BLUE:{default_branch}]', indent=4)
|
|
417
|
+
|
|
418
|
+
git.checkout(branch, path=repo.name)
|
|
419
|
+
result = git.rebase(default_branch, path=repo.name)
|
|
353
420
|
colour.write(result[0], indent=4)
|
|
354
421
|
|
|
355
422
|
################################################################################
|
|
@@ -357,28 +424,30 @@ def mg_update(args, config, console):
|
|
|
357
424
|
def mg_clean(args, config, console):
|
|
358
425
|
"""Clean the repos"""
|
|
359
426
|
|
|
360
|
-
|
|
427
|
+
_ = config
|
|
428
|
+
|
|
429
|
+
for repo in select_git_repos(args, config):
|
|
361
430
|
if not args.quiet:
|
|
362
|
-
show_progress(console.columns, repo)
|
|
431
|
+
show_progress(console.columns, repo.name)
|
|
363
432
|
|
|
364
433
|
result = git.clean(recurse=args.recurse, force=args.force, dry_run=args.dry_run,
|
|
365
434
|
quiet=args.quiet, exclude=args.exclude, ignore_rules=args.x,
|
|
366
|
-
remove_only_ignored=args.X, path=repo)
|
|
435
|
+
remove_only_ignored=args.X, path=repo.name)
|
|
367
436
|
|
|
368
437
|
first_skip = True
|
|
369
438
|
|
|
370
439
|
if result:
|
|
371
|
-
colour.write(f'[BOLD:{repo}]')
|
|
440
|
+
colour.write(f'[BOLD:{repo.name}]')
|
|
372
441
|
|
|
373
442
|
for item in result:
|
|
374
443
|
skipping = item.startswith('Skipping repository ')
|
|
375
444
|
|
|
376
445
|
if skipping and not args.verbose:
|
|
377
446
|
if first_skip:
|
|
378
|
-
colour.write(
|
|
447
|
+
colour.write('Skipping sub-repositories', indent=4)
|
|
379
448
|
first_skip = False
|
|
380
449
|
else:
|
|
381
|
-
colour.write(
|
|
450
|
+
colour.write(item.strip(), indent=4)
|
|
382
451
|
|
|
383
452
|
colour.write()
|
|
384
453
|
|
|
@@ -388,12 +457,15 @@ def mg_dir(args, config, console):
|
|
|
388
457
|
"""Return the location of a working tree, given the name. Returns an
|
|
389
458
|
error unless there is a unique match"""
|
|
390
459
|
|
|
460
|
+
_ = console
|
|
461
|
+
_ = config
|
|
462
|
+
|
|
391
463
|
location = []
|
|
392
464
|
search_dir = args.dir[0]
|
|
393
465
|
|
|
394
|
-
for repo in
|
|
395
|
-
if fnmatch.fnmatch(
|
|
396
|
-
location.append(repo)
|
|
466
|
+
for repo in select_git_repos(args, config):
|
|
467
|
+
if fnmatch.fnmatch(repo['name'], search_dir):
|
|
468
|
+
location.append(repo.name)
|
|
397
469
|
|
|
398
470
|
if len(location) == 0:
|
|
399
471
|
error(f'No matches with {dir}')
|
|
@@ -408,21 +480,59 @@ def mg_run(args, config, console):
|
|
|
408
480
|
"""Run a command in each of the working trees, optionally continuing if
|
|
409
481
|
there's an error"""
|
|
410
482
|
|
|
483
|
+
_ = config
|
|
484
|
+
|
|
411
485
|
cmd = shlex.split(args.cmd[0])
|
|
412
486
|
|
|
413
|
-
for repo in
|
|
487
|
+
for repo in select_git_repos(args, config):
|
|
414
488
|
if not args.quiet:
|
|
415
|
-
show_progress(console.columns, repo)
|
|
489
|
+
show_progress(console.columns, repo.name)
|
|
416
490
|
|
|
417
|
-
|
|
491
|
+
run_git_status(cmd, repo.name, args.cont)
|
|
418
492
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
493
|
+
################################################################################
|
|
494
|
+
|
|
495
|
+
def mg_review(args, config, console):
|
|
496
|
+
"""Run the git review command"""
|
|
497
|
+
|
|
498
|
+
# TODO: Better parsing to replace DEFAULT with default branch only where appropriate
|
|
499
|
+
|
|
500
|
+
for repo in select_git_repos(args, config):
|
|
501
|
+
if not args.quiet:
|
|
502
|
+
show_progress(console.columns, repo.name)
|
|
503
|
+
|
|
504
|
+
params = []
|
|
505
|
+
for p in args.parameters:
|
|
506
|
+
params += shlex.split(p.replace(DEFAULT_BRANCH, repo['default branch']))
|
|
423
507
|
|
|
424
|
-
|
|
425
|
-
|
|
508
|
+
colour.write(f'Running review in [BOLD:{repo.name}]')
|
|
509
|
+
run_git_status(['review'] + params, repo.name, cont=True, redirect=False)
|
|
510
|
+
|
|
511
|
+
################################################################################
|
|
512
|
+
|
|
513
|
+
def read_configuration(args):
|
|
514
|
+
"""If the configuration file name has path elements, try and read it, otherwise
|
|
515
|
+
search up the directory tree looking for the configuration file.
|
|
516
|
+
Returns the configuration data, or None if the configuration file
|
|
517
|
+
could not be found."""
|
|
518
|
+
|
|
519
|
+
if '/' in args.config:
|
|
520
|
+
config_file = args.config
|
|
521
|
+
else:
|
|
522
|
+
config_path = os.getcwd()
|
|
523
|
+
config_file = os.path.join(config_path, args.config)
|
|
524
|
+
|
|
525
|
+
while not os.path.isfile(config_file) and config_path != '/':
|
|
526
|
+
config_path = os.path.dirname(config_path)
|
|
527
|
+
config_file = os.path.join(config_path, args.config)
|
|
528
|
+
|
|
529
|
+
config = configparser.ConfigParser()
|
|
530
|
+
|
|
531
|
+
if os.path.isfile(config_file):
|
|
532
|
+
config.read(config_file)
|
|
533
|
+
return config
|
|
534
|
+
|
|
535
|
+
return None
|
|
426
536
|
|
|
427
537
|
################################################################################
|
|
428
538
|
|
|
@@ -441,6 +551,7 @@ def main():
|
|
|
441
551
|
'clean': mg_clean,
|
|
442
552
|
'dir': mg_dir,
|
|
443
553
|
'run': mg_run,
|
|
554
|
+
'review': mg_review,
|
|
444
555
|
}
|
|
445
556
|
|
|
446
557
|
# Parse args in the form COMMAND OPTIONS SUBCOMMAND SUBCOMMAND_OPTIONS PARAMETERS
|
|
@@ -454,6 +565,8 @@ def main():
|
|
|
454
565
|
parser.add_argument('--config', '-c', action='store', default=DEFAULT_CONFIG_FILE, help=f'The configuration file (defaults to {DEFAULT_CONFIG_FILE})')
|
|
455
566
|
parser.add_argument('--directory', '--dir', action='store', default='.', help='The top-level directory of the multigit tree (defaults to the current directory)')
|
|
456
567
|
parser.add_argument('--repos', '-r', action='append', default=None, help='The repo names to work on (defaults to all repos and can contain shell wildcards and can be issued multiple times on the command line)')
|
|
568
|
+
parser.add_argument('--modified', '-m', action='store_true', help='Select repos that have local modifications')
|
|
569
|
+
parser.add_argument('--branched', '-b', action='store_true', help='Select repos that do not have the default branch checked out')
|
|
457
570
|
|
|
458
571
|
subparsers = parser.add_subparsers(dest='command')
|
|
459
572
|
|
|
@@ -495,6 +608,9 @@ def main():
|
|
|
495
608
|
parser_run.add_argument('--cont', '-c', action='store_true', help='Continue if the command returns an error in any of the working trees')
|
|
496
609
|
parser_run.add_argument('cmd', nargs=1, action='store', help='The command to run (should be quoted)')
|
|
497
610
|
|
|
611
|
+
parser_review = subparsers.add_parser('review', help='Review the changes in a working tree')
|
|
612
|
+
parser_review.add_argument('parameters', nargs='*', action='store', help='Parameters passed to the "git review" command')
|
|
613
|
+
|
|
498
614
|
# Parse the command line
|
|
499
615
|
|
|
500
616
|
args = parser.parse_args()
|
|
@@ -504,12 +620,20 @@ def main():
|
|
|
504
620
|
if not args.command:
|
|
505
621
|
error('No command specified')
|
|
506
622
|
|
|
623
|
+
if args.command not in commands:
|
|
624
|
+
error(f'Unrecognized command "{args.command}"')
|
|
625
|
+
|
|
507
626
|
# If the configuration file exists, read it
|
|
508
627
|
|
|
509
|
-
config =
|
|
628
|
+
config = read_configuration(args)
|
|
629
|
+
|
|
630
|
+
# Command-specific validation
|
|
510
631
|
|
|
511
|
-
if
|
|
512
|
-
|
|
632
|
+
if args.command == 'init':
|
|
633
|
+
if args.modified or args.branched:
|
|
634
|
+
error('The "--modified" and "--branched" options cannot be used with the "init" subcommand')
|
|
635
|
+
elif not config:
|
|
636
|
+
error(f'Unable to location configuration file "{args.config}"')
|
|
513
637
|
|
|
514
638
|
# Get the console size
|
|
515
639
|
|
|
@@ -550,8 +674,8 @@ def multigit():
|
|
|
550
674
|
# Catch-all failure for Git errors
|
|
551
675
|
|
|
552
676
|
except git.GitError as exc:
|
|
553
|
-
sys.stderr.write(exc)
|
|
554
|
-
sys.exit(
|
|
677
|
+
sys.stderr.write(exc.msg)
|
|
678
|
+
sys.exit(exc.status)
|
|
555
679
|
|
|
556
680
|
################################################################################
|
|
557
681
|
|
|
@@ -73,7 +73,7 @@ def git(cmd, stdout=None, stderr=None, path=None):
|
|
|
73
73
|
|
|
74
74
|
################################################################################
|
|
75
75
|
|
|
76
|
-
def git_run_status(cmd, stdout=None, stderr=None, path=None):
|
|
76
|
+
def git_run_status(cmd, stdout=None, stderr=None, path=None, redirect=True):
|
|
77
77
|
""" Wrapper for run.run that returns the output and status, and
|
|
78
78
|
does not raise an exception on error.
|
|
79
79
|
Optionally redirect stdout and stderr as specified. """
|
|
@@ -85,12 +85,15 @@ def git_run_status(cmd, stdout=None, stderr=None, path=None):
|
|
|
85
85
|
if path:
|
|
86
86
|
git_cmd += ['-C', path]
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
if redirect:
|
|
89
|
+
result = subprocess.run(git_cmd + cmd,
|
|
90
|
+
stdout=stdout or subprocess.PIPE,
|
|
91
|
+
stderr=stderr or subprocess.PIPE,
|
|
92
|
+
text=True, check=False,
|
|
93
|
+
errors='ignore',
|
|
94
|
+
universal_newlines=True)
|
|
95
|
+
else:
|
|
96
|
+
result = subprocess.run(git_cmd + cmd)
|
|
94
97
|
|
|
95
98
|
return (result.stdout or result.stderr), result.returncode
|
|
96
99
|
|
|
@@ -443,6 +446,9 @@ def status(ignored=False, untracked=False, path=None):
|
|
|
443
446
|
stats = []
|
|
444
447
|
stats.append(result[0:2])
|
|
445
448
|
|
|
449
|
+
if not untracked and result[0] == '?':
|
|
450
|
+
continue
|
|
451
|
+
|
|
446
452
|
name = result[3:]
|
|
447
453
|
if ' -> ' in name:
|
|
448
454
|
stats += name.split(' -> ', 1)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: skilleter_thingy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.81
|
|
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
|
|
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.0.79 → skilleter_thingy-0.0.81}/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.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{skilleter_thingy-0.0.79 → skilleter_thingy-0.0.81}/skilleter_thingy.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|