skilleter-thingy 0.2.13__tar.gz → 0.2.15__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.2.13 → skilleter_thingy-0.2.15}/PKG-INFO +1 -1
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/pyproject.toml +1 -1
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/ffind.py +23 -20
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_cleanup.py +1 -1
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_review.py +1 -2
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_update.py +3 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/gitcmp_helper.py +17 -14
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/rpylint.py +28 -20
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/tfm.py +0 -2
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/docker.py +11 -11
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/files.py +6 -6
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/git.py +12 -6
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/popup.py +2 -1
- skilleter_thingy-0.2.15/skilleter_thingy/thingy/run.py +306 -0
- skilleter_thingy-0.2.15/skilleter_thingy/x.py +3 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy.egg-info/PKG-INFO +1 -1
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy.egg-info/SOURCES.txt +1 -1
- skilleter_thingy-0.2.13/skilleter_thingy/thingy/process.py +0 -32
- skilleter_thingy-0.2.13/skilleter_thingy/thingy/run.py +0 -376
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/LICENSE +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/README.md +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/setup.cfg +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/__init__.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/addpath.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/console_colours.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/docker_purge.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/ggit.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/ggrep.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_br.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_ca.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_co.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_common.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_hold.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_mr.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_parent.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_retag.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/git_wt.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/gitprompt.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/gl.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/linecount.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/multigit.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/py_audit.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/readable.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/remdir.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/rmdupe.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/strreplace.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/tfparse.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/__init__.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/colour.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/dc_curses.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/dc_defaults.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/dc_util.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/dircolors.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/gitlab.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/path.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/tfm_pane.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/tidy.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/thingy/venv_template.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/trimpath.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/venv_create.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/xchmod.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy/yamlcheck.py +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy.egg-info/dependency_links.txt +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy.egg-info/entry_points.txt +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/skilleter_thingy.egg-info/requires.txt +0 -0
- {skilleter_thingy-0.2.13 → skilleter_thingy-0.2.15}/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.2.
|
|
3
|
+
Version: 0.2.15
|
|
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
|
|
@@ -26,11 +26,10 @@ import pwd
|
|
|
26
26
|
import datetime
|
|
27
27
|
import re
|
|
28
28
|
import shlex
|
|
29
|
-
import copy
|
|
30
29
|
import logging
|
|
30
|
+
import subprocess
|
|
31
31
|
|
|
32
32
|
from thingy import git
|
|
33
|
-
from thingy import run
|
|
34
33
|
from thingy import dircolors
|
|
35
34
|
from thingy import colour
|
|
36
35
|
|
|
@@ -39,7 +38,7 @@ from thingy import colour
|
|
|
39
38
|
def error(msg, status=1):
|
|
40
39
|
""" Report an error message and exit """
|
|
41
40
|
|
|
42
|
-
sys.stderr.write('
|
|
41
|
+
sys.stderr.write(f'{msg}\n')
|
|
43
42
|
sys.exit(status)
|
|
44
43
|
|
|
45
44
|
################################################################################
|
|
@@ -48,7 +47,7 @@ def report_exception(exc):
|
|
|
48
47
|
""" Handle an exception triggered inside os.walk - currently just reports
|
|
49
48
|
the exception - typically a permission error. """
|
|
50
49
|
|
|
51
|
-
sys.stderr.write('
|
|
50
|
+
sys.stderr.write(f'{exc}\n')
|
|
52
51
|
|
|
53
52
|
################################################################################
|
|
54
53
|
|
|
@@ -68,17 +67,18 @@ def report_file(args, filepath, filestat, dircolour):
|
|
|
68
67
|
if args.exec:
|
|
69
68
|
# Copy the exec string and insert the file
|
|
70
69
|
|
|
71
|
-
cmd =
|
|
72
|
-
|
|
70
|
+
cmd = []
|
|
71
|
+
for i in args.exec:
|
|
72
|
+
cmd.append(i.replace('^', filepath))
|
|
73
73
|
|
|
74
74
|
logging.debug('Running "%s"', ' '.join(cmd))
|
|
75
75
|
|
|
76
76
|
# Attempt to run the command
|
|
77
77
|
|
|
78
78
|
try:
|
|
79
|
-
|
|
80
|
-
except
|
|
81
|
-
error(exc.
|
|
79
|
+
subprocess.run(cmd, check=True)
|
|
80
|
+
except subprocess.CalledProcessError as exc:
|
|
81
|
+
error('%s failed with status=%d' % (' '.join(cmd), exc.returncode))
|
|
82
82
|
except FileNotFoundError:
|
|
83
83
|
error('File not found attempting to run "%s"' % ' '.join(cmd))
|
|
84
84
|
except PermissionError:
|
|
@@ -86,7 +86,7 @@ def report_file(args, filepath, filestat, dircolour):
|
|
|
86
86
|
|
|
87
87
|
if args.verbose or not args.exec:
|
|
88
88
|
if args.zero:
|
|
89
|
-
sys.stdout.write('
|
|
89
|
+
sys.stdout.write(f'{filepath}\0')
|
|
90
90
|
else:
|
|
91
91
|
# Colourise output if required
|
|
92
92
|
|
|
@@ -96,7 +96,7 @@ def report_file(args, filepath, filestat, dircolour):
|
|
|
96
96
|
# Quote the file if necessary
|
|
97
97
|
|
|
98
98
|
if not args.unquoted and ' ' in filepath:
|
|
99
|
-
filepath = '"
|
|
99
|
+
filepath = f'"{filepath}"'
|
|
100
100
|
|
|
101
101
|
# Output full details or just the filename
|
|
102
102
|
|
|
@@ -186,7 +186,7 @@ def grep_match(regex, filename):
|
|
|
186
186
|
|
|
187
187
|
recomp = re.compile(regex)
|
|
188
188
|
|
|
189
|
-
with open(filename, 'r', errors='ignore') as infile:
|
|
189
|
+
with open(filename, 'r', errors='ignore', encoding='utf8') as infile:
|
|
190
190
|
for text in infile:
|
|
191
191
|
if recomp.search(text):
|
|
192
192
|
break
|
|
@@ -299,7 +299,7 @@ def validate_arguments(args):
|
|
|
299
299
|
if args.type:
|
|
300
300
|
for t in args.type:
|
|
301
301
|
if t not in ['b', 'c', 'd', 'p', 'f', 'l', 's']:
|
|
302
|
-
error('Invalid type "
|
|
302
|
+
error(f'Invalid type "{t}"')
|
|
303
303
|
|
|
304
304
|
# Precompile regexes if using them
|
|
305
305
|
|
|
@@ -392,14 +392,15 @@ def validate_arguments(args):
|
|
|
392
392
|
# marker if it isn't there.
|
|
393
393
|
|
|
394
394
|
if args.exec:
|
|
395
|
-
|
|
395
|
+
replacements = args.exec.count('^')
|
|
396
|
+
|
|
397
|
+
if replacements > 1:
|
|
396
398
|
error('Too many "^" characters in the exec string')
|
|
399
|
+
elif not replacements:
|
|
400
|
+
args.exec = f'{args.exec} ^'
|
|
397
401
|
|
|
398
402
|
args.exec = shlex.split(args.exec)
|
|
399
403
|
|
|
400
|
-
if '^' not in args.exec:
|
|
401
|
-
args.exec.append('^')
|
|
402
|
-
|
|
403
404
|
# If the path option has been used, try to switch to the specified directory
|
|
404
405
|
|
|
405
406
|
if args.path:
|
|
@@ -501,9 +502,11 @@ def main():
|
|
|
501
502
|
diff_cmd.append(file)
|
|
502
503
|
|
|
503
504
|
try:
|
|
504
|
-
|
|
505
|
-
except
|
|
506
|
-
error(exc)
|
|
505
|
+
subprocess.run(diff_cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
|
|
506
|
+
except subprocess.CalledProcessError as exc:
|
|
507
|
+
error(f'Diff failed with status={exc.returncode}')
|
|
508
|
+
except FileNotFoundError:
|
|
509
|
+
error('Unable to run %s' % ' '.join(diff_cmd))
|
|
507
510
|
|
|
508
511
|
# Report the number of objects found
|
|
509
512
|
|
|
@@ -47,7 +47,6 @@ import sys
|
|
|
47
47
|
import argparse
|
|
48
48
|
import curses
|
|
49
49
|
import curses.panel
|
|
50
|
-
import curses.textpad
|
|
51
50
|
import pickle
|
|
52
51
|
import fnmatch
|
|
53
52
|
import subprocess
|
|
@@ -200,7 +199,7 @@ class PopUp():
|
|
|
200
199
|
else:
|
|
201
200
|
break
|
|
202
201
|
|
|
203
|
-
def __exit__(self,
|
|
202
|
+
def __exit__(self, _exc_type, _exc_value, _exc_traceback):
|
|
204
203
|
""" Remove the popup """
|
|
205
204
|
|
|
206
205
|
if self.panel:
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
|
|
19
19
|
TODO: Avoid lots of pulls - should be able to fetch then updated each local branch.
|
|
20
20
|
TODO: Add option to specify name of master branch or additional names to add to the list
|
|
21
|
+
TODO: Config entry for regularly-ignored branches
|
|
22
|
+
TODO: Config entry for branches that shouldn't be rebased (main, master, release/*)
|
|
23
|
+
TODO: Command line option when using -a to skip working trees that are modified
|
|
21
24
|
"""
|
|
22
25
|
################################################################################
|
|
23
26
|
|
|
@@ -43,9 +43,9 @@ import argparse
|
|
|
43
43
|
import filecmp
|
|
44
44
|
import re
|
|
45
45
|
import logging
|
|
46
|
+
import subprocess
|
|
46
47
|
|
|
47
48
|
from thingy import colour
|
|
48
|
-
from thingy import run
|
|
49
49
|
from thingy import files
|
|
50
50
|
from thingy import git
|
|
51
51
|
from thingy import dircolors
|
|
@@ -81,7 +81,7 @@ def report_permissions(perm):
|
|
|
81
81
|
permtext.append(mask_char if permissions & mask else '-')
|
|
82
82
|
mask >>= 1
|
|
83
83
|
|
|
84
|
-
return '
|
|
84
|
+
return ''.join(permtext)
|
|
85
85
|
|
|
86
86
|
################################################################################
|
|
87
87
|
|
|
@@ -146,7 +146,7 @@ def main():
|
|
|
146
146
|
# Check and handle for the simple case of an unmerged file
|
|
147
147
|
|
|
148
148
|
if args.old_file is None:
|
|
149
|
-
colour.write('[CYAN
|
|
149
|
+
colour.write(f'[CYAN:{args.file_path}] is not merged')
|
|
150
150
|
sys.exit(0)
|
|
151
151
|
|
|
152
152
|
# Make sure that we have all the expected parameters
|
|
@@ -158,11 +158,11 @@ def main():
|
|
|
158
158
|
# Make sure we can access the temporary files supplied
|
|
159
159
|
|
|
160
160
|
if not os.access(args.old_file, os.R_OK):
|
|
161
|
-
sys.stderr.write('Unable to read temporary old file:
|
|
161
|
+
sys.stderr.write(f'Unable to read temporary old file: {args.old_file}\n')
|
|
162
162
|
sys.exit(2)
|
|
163
163
|
|
|
164
164
|
if not os.access(args.new_file, os.R_OK):
|
|
165
|
-
sys.stderr.write('Unable to read temporary new file:
|
|
165
|
+
sys.stderr.write(f'Unable to read temporary new file: {args.new_file}\n')
|
|
166
166
|
sys.exit(2)
|
|
167
167
|
|
|
168
168
|
dc = dircolors.Dircolors()
|
|
@@ -195,12 +195,12 @@ def main():
|
|
|
195
195
|
# If processing more than one file, append he index and total number of files
|
|
196
196
|
|
|
197
197
|
if path_total > 0:
|
|
198
|
-
heading.append('(
|
|
198
|
+
heading.append(f'({path_count}/{path_total})')
|
|
199
199
|
|
|
200
200
|
# Check for newly created/deleted files (other version will be '/dev/null')
|
|
201
201
|
|
|
202
|
-
created_file =
|
|
203
|
-
deleted_file =
|
|
202
|
+
created_file = args.old_file == '/dev/null'
|
|
203
|
+
deleted_file = args.new_file == '/dev/null'
|
|
204
204
|
|
|
205
205
|
if created_file:
|
|
206
206
|
heading.append('(new file)')
|
|
@@ -232,11 +232,11 @@ def main():
|
|
|
232
232
|
formatted_new_size = files.format_size(new_size, always_suffix=True)
|
|
233
233
|
|
|
234
234
|
if created_file:
|
|
235
|
-
colour.write(' New size: [CYAN
|
|
235
|
+
colour.write(f' New size: [CYAN:{formatted_new_size}]')
|
|
236
236
|
elif deleted_file:
|
|
237
|
-
colour.write(' Original size: [CYAN
|
|
237
|
+
colour.write(f' Original size: [CYAN:{formatted_old_size}]')
|
|
238
238
|
elif new_size == old_size:
|
|
239
|
-
colour.write(' Size: [CYAN]
|
|
239
|
+
colour.write(f' Size: [CYAN]{formatted_new_size}[NORMAL] (no change)')
|
|
240
240
|
else:
|
|
241
241
|
formatted_delta_size = files.format_size(abs(new_size - old_size), always_suffix=True)
|
|
242
242
|
|
|
@@ -297,9 +297,12 @@ def main():
|
|
|
297
297
|
|
|
298
298
|
if not deleted_file or not skip_deleted:
|
|
299
299
|
try:
|
|
300
|
-
|
|
301
|
-
except
|
|
302
|
-
print('Diff failed
|
|
300
|
+
subprocess.run([difftool, args.old_file, args.new_file], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
|
|
301
|
+
except subprocess.CalledProcessError as exc:
|
|
302
|
+
print(f'WARNING: Diff failed - status = {exc.returncode}')
|
|
303
|
+
except FileNotFoundError:
|
|
304
|
+
print(f'ERROR: Unable to locate diff tool {difftool}')
|
|
305
|
+
sys.exit(1)
|
|
303
306
|
|
|
304
307
|
# Separate reports with a blank line
|
|
305
308
|
|
|
@@ -10,8 +10,11 @@ import os
|
|
|
10
10
|
import sys
|
|
11
11
|
import argparse
|
|
12
12
|
import glob
|
|
13
|
+
import subprocess
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
################################################################################
|
|
16
|
+
|
|
17
|
+
PYLINT = 'pylint'
|
|
15
18
|
|
|
16
19
|
################################################################################
|
|
17
20
|
|
|
@@ -32,26 +35,30 @@ def main():
|
|
|
32
35
|
|
|
33
36
|
sourcefiles = []
|
|
34
37
|
|
|
35
|
-
# Use rgrep to find source files that have a Python 3
|
|
38
|
+
# Use rgrep to find source files that have a Python 3 hashbang
|
|
36
39
|
|
|
37
40
|
for entry in args.paths:
|
|
38
41
|
if os.path.isdir(entry):
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
result = subprocess.run(['rgrep', '-E', '--exclude-dir=.git', '-l', '#![[:space:]]*/usr/bin/(env[[:space:]])?python3'] + args.paths,
|
|
43
|
+
capture_output=True, check=False, text=True)
|
|
44
|
+
|
|
45
|
+
if result.returncode == 1:
|
|
46
|
+
sys.stderr.write('No Python3 source files found\n')
|
|
47
|
+
sys.exit(2)
|
|
48
|
+
|
|
49
|
+
if result.returncode:
|
|
50
|
+
sys.stderr.write(f'ERROR #{result.returncode}: {result.stderr}')
|
|
51
|
+
sys.exit(1)
|
|
52
|
+
|
|
53
|
+
sourcefiles += result.stdout.split('\n')
|
|
54
|
+
|
|
48
55
|
elif os.path.isfile(entry):
|
|
49
56
|
sourcefiles.append(entry)
|
|
50
57
|
else:
|
|
51
58
|
files = glob.glob(entry)
|
|
52
59
|
|
|
53
60
|
if not files:
|
|
54
|
-
sys.stderr.write('No files found matching "
|
|
61
|
+
sys.stderr.write(f'No files found matching "{entry}"')
|
|
55
62
|
sys.exit(2)
|
|
56
63
|
|
|
57
64
|
sourcefiles += files
|
|
@@ -59,18 +66,19 @@ def main():
|
|
|
59
66
|
# Run pylint on all the files
|
|
60
67
|
|
|
61
68
|
try:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
result = subprocess.run([PYLINT, '--output-format', 'parseable'] + sourcefiles, capture_output=False, check=False, text=True)
|
|
70
|
+
|
|
71
|
+
except FileNotFoundError:
|
|
72
|
+
sys.stderr.write(f'Unable to locate {PYLINT}\n')
|
|
73
|
+
sys.exit(1)
|
|
67
74
|
|
|
68
|
-
if
|
|
69
|
-
sys.stderr.write('Unexpected error:
|
|
75
|
+
if result.returncode >= 64:
|
|
76
|
+
sys.stderr.write(f'Unexpected error: {result.returncode}\n')
|
|
77
|
+
sys.exit(3)
|
|
70
78
|
|
|
71
79
|
# Function return code is the status return from pylint
|
|
72
80
|
|
|
73
|
-
return
|
|
81
|
+
return result.returncode
|
|
74
82
|
|
|
75
83
|
################################################################################
|
|
76
84
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"""
|
|
13
13
|
################################################################################
|
|
14
14
|
|
|
15
|
-
import thingy.
|
|
15
|
+
import thingy.run as run
|
|
16
16
|
|
|
17
17
|
################################################################################
|
|
18
18
|
|
|
@@ -33,9 +33,9 @@ def instances(all=False):
|
|
|
33
33
|
|
|
34
34
|
instances_list = []
|
|
35
35
|
try:
|
|
36
|
-
for result in
|
|
36
|
+
for result in run.run(cmd):
|
|
37
37
|
instances_list.append(result)
|
|
38
|
-
except
|
|
38
|
+
except run.RunError as exc:
|
|
39
39
|
raise DockerError(exc)
|
|
40
40
|
|
|
41
41
|
return instances_list
|
|
@@ -48,8 +48,8 @@ def stop(instance, force=False):
|
|
|
48
48
|
# TODO: force option not implemented
|
|
49
49
|
|
|
50
50
|
try:
|
|
51
|
-
|
|
52
|
-
except
|
|
51
|
+
run.run(['docker', 'stop', instance], output=True)
|
|
52
|
+
except run.RunError as exc:
|
|
53
53
|
raise DockerError(exc)
|
|
54
54
|
|
|
55
55
|
################################################################################
|
|
@@ -65,8 +65,8 @@ def rm(instance, force=False):
|
|
|
65
65
|
cmd.append(instance)
|
|
66
66
|
|
|
67
67
|
try:
|
|
68
|
-
|
|
69
|
-
except
|
|
68
|
+
run.run(cmd, output=True)
|
|
69
|
+
except run.RunError as exc:
|
|
70
70
|
raise DockerError(exc)
|
|
71
71
|
|
|
72
72
|
################################################################################
|
|
@@ -75,9 +75,9 @@ def images():
|
|
|
75
75
|
""" Return a list of all current Docker images """
|
|
76
76
|
|
|
77
77
|
try:
|
|
78
|
-
for result in
|
|
78
|
+
for result in run.run(['docker', 'images', '-q']):
|
|
79
79
|
yield result
|
|
80
|
-
except
|
|
80
|
+
except run.RunError as exc:
|
|
81
81
|
raise DockerError(exc)
|
|
82
82
|
|
|
83
83
|
################################################################################
|
|
@@ -92,6 +92,6 @@ def rmi(image, force=False):
|
|
|
92
92
|
cmd.append(image)
|
|
93
93
|
|
|
94
94
|
try:
|
|
95
|
-
|
|
96
|
-
except
|
|
95
|
+
run.run(cmd, foreground=True)
|
|
96
|
+
except run.RunError as exc:
|
|
97
97
|
raise DockerError(exc)
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import os
|
|
13
13
|
import shutil
|
|
14
|
-
|
|
15
|
-
import thingy.process as process
|
|
14
|
+
import subprocess
|
|
16
15
|
|
|
17
16
|
################################################################################
|
|
18
17
|
|
|
@@ -31,7 +30,7 @@ def file_type(filename, mime=False):
|
|
|
31
30
|
# is not a file, so we have to do that.
|
|
32
31
|
|
|
33
32
|
if not os.path.isfile(filename) or not os.access(filename, os.R_OK):
|
|
34
|
-
raise
|
|
33
|
+
raise FileNotFoundError('Unable to access %s' % filename)
|
|
35
34
|
|
|
36
35
|
cmd = ['file', '--brief']
|
|
37
36
|
|
|
@@ -40,8 +39,9 @@ def file_type(filename, mime=False):
|
|
|
40
39
|
|
|
41
40
|
cmd.append(filename)
|
|
42
41
|
|
|
43
|
-
result =
|
|
44
|
-
|
|
42
|
+
result = subprocess.run(cmd, capture_output=True, check=False, text=True)
|
|
43
|
+
|
|
44
|
+
return result.stdout.split('\n')[0] if result.returncode==0 else None
|
|
45
45
|
|
|
46
46
|
################################################################################
|
|
47
47
|
|
|
@@ -148,7 +148,7 @@ if __name__ == "__main__":
|
|
|
148
148
|
for mimeflag in (False, True):
|
|
149
149
|
print('/bin/sh is: %s' % file_type('/bin/sh', mimeflag))
|
|
150
150
|
print('/bin/dash is: %s' % file_type('/bin/dash', mimeflag))
|
|
151
|
-
print('
|
|
151
|
+
print('multigit.py is: %s' % file_type('multigit.py', mimeflag))
|
|
152
152
|
print('')
|
|
153
153
|
|
|
154
154
|
for sizevalue in (0, 1, 999, 1024, 1025, 1.3 * 1024, 2**32 - 1, 2**64 + 2**49):
|
|
@@ -948,18 +948,21 @@ def ref(fields=('objectname'), sort=None, remotes=False, path=None):
|
|
|
948
948
|
|
|
949
949
|
################################################################################
|
|
950
950
|
|
|
951
|
-
def branches(all=False, path=None):
|
|
951
|
+
def branches(all=False, path=None, remote=False):
|
|
952
952
|
""" Return a list of all the branches in the current repo """
|
|
953
953
|
|
|
954
|
-
cmd = ['branch']
|
|
954
|
+
cmd = ['branch', '--format=%(refname:short)','--list']
|
|
955
955
|
|
|
956
956
|
if all:
|
|
957
957
|
cmd.append('--all')
|
|
958
958
|
|
|
959
|
+
if remote:
|
|
960
|
+
cmd.append('--remote')
|
|
961
|
+
|
|
959
962
|
results = []
|
|
960
963
|
for output in git(cmd, path=path):
|
|
961
964
|
if ' -> ' not in output and '(HEAD detached at ' not in output:
|
|
962
|
-
results.append(output
|
|
965
|
+
results.append(output)
|
|
963
966
|
|
|
964
967
|
return results
|
|
965
968
|
|
|
@@ -1250,7 +1253,10 @@ def matching_branch(branchname, case=False, path=None):
|
|
|
1250
1253
|
otherwise, it just checks for a branches containing the branchname
|
|
1251
1254
|
as a substring. """
|
|
1252
1255
|
|
|
1253
|
-
|
|
1256
|
+
local_branches = branches(path=path)
|
|
1257
|
+
remote_branches = branches(path=path, remote=True)
|
|
1258
|
+
|
|
1259
|
+
all_branches = local_branches + remote_branches
|
|
1254
1260
|
|
|
1255
1261
|
# Always return exact matches
|
|
1256
1262
|
|
|
@@ -1284,8 +1290,8 @@ def matching_branch(branchname, case=False, path=None):
|
|
|
1284
1290
|
# If the match is a remote branch, ignore it if we already have the equivalent
|
|
1285
1291
|
# local branch, otherwise add the name of the local branch that would be created.
|
|
1286
1292
|
|
|
1287
|
-
if branch
|
|
1288
|
-
localbranch = '/'.join(branch.split('/')[
|
|
1293
|
+
if branch in remote_branches:
|
|
1294
|
+
localbranch = '/'.join(branch.split('/')[1:])
|
|
1289
1295
|
if localbranch not in matching:
|
|
1290
1296
|
matching_remote.append(localbranch)
|
|
1291
1297
|
else:
|
|
@@ -14,6 +14,7 @@ the popup again.
|
|
|
14
14
|
|
|
15
15
|
import time
|
|
16
16
|
import curses
|
|
17
|
+
import curses.panel
|
|
17
18
|
|
|
18
19
|
################################################################################
|
|
19
20
|
|
|
@@ -71,7 +72,7 @@ class PopUp():
|
|
|
71
72
|
curses.panel.update_panels()
|
|
72
73
|
self.screen.refresh()
|
|
73
74
|
|
|
74
|
-
def __exit__(self,
|
|
75
|
+
def __exit__(self, _exc_type, _exc_value, _exc_traceback):
|
|
75
76
|
""" Remove the popup """
|
|
76
77
|
|
|
77
78
|
if self.panel:
|