skilleter-thingy 0.1.18__py3-none-any.whl → 0.1.21__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of skilleter-thingy might be problematic. Click here for more details.

Files changed (33) hide show
  1. skilleter_thingy/ffind.py +2 -2
  2. skilleter_thingy/ggit.py +1 -1
  3. skilleter_thingy/ggrep.py +2 -1
  4. skilleter_thingy/git_br.py +3 -3
  5. skilleter_thingy/git_common.py +2 -2
  6. skilleter_thingy/git_hold.py +6 -6
  7. skilleter_thingy/git_parent.py +4 -3
  8. skilleter_thingy/git_review.py +16 -12
  9. skilleter_thingy/git_update.py +2 -2
  10. skilleter_thingy/git_wt.py +5 -5
  11. skilleter_thingy/gitcmp_helper.py +6 -1
  12. skilleter_thingy/gphotosync.py +12 -8
  13. skilleter_thingy/localphotosync.py +77 -358
  14. skilleter_thingy/multigit.py +30 -34
  15. skilleter_thingy/photodupe.py +10 -10
  16. skilleter_thingy/py_audit.py +4 -2
  17. skilleter_thingy/readable.py +13 -11
  18. skilleter_thingy/sysmon.py +2 -2
  19. skilleter_thingy/thingy/colour.py +6 -2
  20. skilleter_thingy/thingy/dircolors.py +20 -18
  21. skilleter_thingy/thingy/git2.py +0 -1
  22. skilleter_thingy/thingy/popup.py +1 -1
  23. skilleter_thingy/thingy/tfm_pane.py +3 -3
  24. skilleter_thingy/thingy/tidy.py +14 -13
  25. skilleter_thingy/trimpath.py +5 -4
  26. skilleter_thingy/venv_create.py +1 -1
  27. {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/METADATA +1 -1
  28. skilleter_thingy-0.1.21.dist-info/PKG-INFO 2 +193 -0
  29. {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/RECORD +33 -32
  30. {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/WHEEL +0 -0
  31. {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/entry_points.txt +0 -0
  32. {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/licenses/LICENSE +0 -0
  33. {skilleter_thingy-0.1.18.dist-info → skilleter_thingy-0.1.21.dist-info}/top_level.txt +0 -0
@@ -133,14 +133,6 @@ class Arguments():
133
133
 
134
134
  ################################################################################
135
135
 
136
- def error(msg, status=1):
137
- """Quit with an error"""
138
-
139
- colour.write(f'[RED:ERROR:] {msg}\n', stream=sys.stderr)
140
- sys.exit(status)
141
-
142
- ################################################################################
143
-
144
136
  def verbose(args, msg):
145
137
  """Output a message to stderr if running verbosely"""
146
138
 
@@ -174,7 +166,11 @@ def find_configuration(default_config_file):
174
166
  if '/' in default_config_file:
175
167
  config_file = default_config_file
176
168
  else:
177
- config_path = os.getcwd()
169
+ try:
170
+ config_path = os.getcwd()
171
+ except FileNotFoundError:
172
+ colour.error('Unable to determine current directory', prefix=True)
173
+
178
174
  config_file = os.path.join(config_path, default_config_file)
179
175
 
180
176
  while not os.path.isfile(config_file) and config_path != '/':
@@ -314,10 +310,10 @@ def mg_clone(args, config, console):
314
310
  # Sanity checks
315
311
 
316
312
  if not args.parameters:
317
- error('The "clone" subcommand takes 1 or 2 parameters - the repo to clone and, optionally, the branch to check out')
313
+ colour.error('The "clone" subcommand takes 1 or 2 parameters - the repo to clone and, optionally, the branch to check out', prefix=True)
318
314
 
319
315
  if args.branched or args.modified:
320
- error('The "modified" and "branched" options cannot be used with the "clone" subcommand')
316
+ colour.error('The "modified" and "branched" options cannot be used with the "clone" subcommand', prefix=True)
321
317
 
322
318
  # Destination directory is the last portion of the repo URL with the extension removed
323
319
 
@@ -325,9 +321,9 @@ def mg_clone(args, config, console):
325
321
 
326
322
  if os.path.exists(directory):
327
323
  if os.path.isdir(directory):
328
- error(f'The "[BLUE:{directory}]" directory already exists')
324
+ colour.error(f'The "[BLUE:{directory}]" directory already exists', prefix=True)
329
325
  else:
330
- error(f'[BLUE:{directory}]" already exists')
326
+ colour.error(f'[BLUE:{directory}]" already exists', prefix=True)
331
327
 
332
328
  # Clone the repo and chdir into it
333
329
 
@@ -349,7 +345,7 @@ def mg_clone(args, config, console):
349
345
  args.configuration_file = args.default_configuration_file
350
346
 
351
347
  if not os.path.isfile(args.configuration_file):
352
- error(f'Cannot find the configuration file: [BOLD:{args.default_configuration_file}]')
348
+ colour.error(f'Cannot find the configuration file: [BOLD:{args.default_configuration_file}]', prefix=True)
353
349
 
354
350
  config.read(args.configuration_file)
355
351
 
@@ -383,7 +379,7 @@ def mg_init(args, config, console):
383
379
  # Sanity checks
384
380
 
385
381
  if args.modified or args.branched or args.tag or args.subdirectories:
386
- error('The "--tag", "--modified" "--sub", and "--branched" options cannot be used with the "init" subcommand')
382
+ colour.error('The "--tag", "--modified" "--sub", and "--branched" options cannot be used with the "init" subcommand', prefix=True)
387
383
 
388
384
  # Search for .git directories and add any that aren't already in the configuration
389
385
 
@@ -400,12 +396,12 @@ def mg_init(args, config, console):
400
396
 
401
397
  abs_repo_path = absolute_repo_path(args, repo)
402
398
 
403
- config[repo] = { }
399
+ config[repo] = {}
404
400
 
405
401
  default_branch = git.branch(path=abs_repo_path)
406
402
 
407
403
  if not default_branch:
408
- error(f'Unable to determine default branch in [BLUE:{repo}]')
404
+ colour.error(f'Unable to determine default branch in [BLUE:{repo}]', prefix=True)
409
405
 
410
406
  config[repo]['default branch'] = default_branch
411
407
 
@@ -451,12 +447,12 @@ def mg_dir(args, config, console):
451
447
  verbose(args, f'dir: Parameters: {", ".join(args.parameters)}')
452
448
 
453
449
  if len(args.parameters) > 1:
454
- error('The +dir command takes no more than one parameter - the name of the working tree to search for')
450
+ colour.error('The +dir command takes no more than one parameter - the name of the working tree to search for', prefix=True)
455
451
 
456
452
  # TODO: mg_dir _should_ use these options
457
453
 
458
454
  if args.modified or args.branched or args.tag or args.subdirectories:
459
- error('The "--tag", "--modified" "--sub", and "--branched" options cannot be used with the "dir" subcommand')
455
+ colour.error('The "--tag", "--modified" "--sub", and "--branched" options cannot be used with the "dir" subcommand', prefix=True)
460
456
 
461
457
  # If a parameter is specified, look for matches, otherwise just return the location of the
462
458
  # configuration file
@@ -490,7 +486,7 @@ def mg_dir(args, config, console):
490
486
  destination = destinations
491
487
 
492
488
  if not destination:
493
- error(f'No matches with [BLUE:{search_name}]')
489
+ colour.error(f'No matches with [BLUE:{search_name}]', prefix=True)
494
490
 
495
491
  colour.write("\n".join([relative_repo_path(args, d) for d in destination]))
496
492
 
@@ -505,7 +501,7 @@ def mg_tag(args, config, console):
505
501
  _ = console
506
502
 
507
503
  if len(args.parameters) > 1:
508
- error('The +tag command takes no more than one parameter')
504
+ colour.error('The +tag command takes no more than one parameter', prefix=True)
509
505
 
510
506
  for repo in select_git_repos(args, config):
511
507
  try:
@@ -529,7 +525,7 @@ def mg_untag(args, config, console):
529
525
  _ = console
530
526
 
531
527
  if len(args.parameters) > 1:
532
- error('The +tag command takes no more than one parameter')
528
+ colour.error('The +tag command takes no more than one parameter', prefix=True)
533
529
 
534
530
  for repo in select_git_repos(args, config):
535
531
  try:
@@ -551,7 +547,7 @@ def mg_config(args, config, console):
551
547
  _ = console
552
548
 
553
549
  if len(args.parameters):
554
- error('The +config command does not take parameters')
550
+ colour.error('The +config command does not take parameters', prefix=True)
555
551
 
556
552
  colour.write(os.path.relpath(args.configuration_file))
557
553
 
@@ -614,28 +610,28 @@ def parse_command_line():
614
610
 
615
611
  elif param in ('config', 'c'):
616
612
  if params:
617
- error('--config - missing configuration file parameter')
613
+ colour.error('--config - missing configuration file parameter', prefix=True)
618
614
  else:
619
615
  try:
620
616
  args.default_configuration_file = arg_list.pop(0)
621
617
  except IndexError:
622
- error('--config - missing configuration file parameter')
618
+ colour.error('--config - missing configuration file parameter', prefix=True)
623
619
 
624
620
  elif param in ('repos', 'r'):
625
621
  if params:
626
- error('--repos - missing repo parameter')
622
+ colour.error('--repos - missing repo parameter', prefix=True)
627
623
  try:
628
624
  args.repos.append(arg_list.pop(0))
629
625
  except IndexError:
630
- error('--repos - missing repo parameter')
626
+ colour.error('--repos - missing repo parameter', prefix=True)
631
627
 
632
628
  elif param in ('tag', 't'):
633
629
  if params:
634
- error('--tag - missing tag parameter')
630
+ colour.error('--tag - missing tag parameter', prefix=True)
635
631
  try:
636
632
  args.tag.append(arg_list.pop(0))
637
633
  except IndexError:
638
- error('--tag - missing tag parameter')
634
+ colour.error('--tag - missing tag parameter', prefix=True)
639
635
 
640
636
  elif param in ('modified', 'm'):
641
637
  args.modified = True
@@ -654,7 +650,7 @@ def parse_command_line():
654
650
  sys.exit(0)
655
651
 
656
652
  else:
657
- error(f'Invalid option: "{param}"')
653
+ colour.error(f'Invalid option: "{param}"', prefix=True)
658
654
 
659
655
  # After the options, we either have a multigit command (prefixed with '+') or a git command
660
656
  # followed by parameter
@@ -670,7 +666,7 @@ def parse_command_line():
670
666
  args.internal_command = False
671
667
 
672
668
  except IndexError:
673
- error('Missing command')
669
+ colour.error('Missing command', prefix=True)
674
670
 
675
671
  # Save the command parameters
676
672
 
@@ -702,7 +698,7 @@ def main():
702
698
  args = parse_command_line()
703
699
 
704
700
  if args.internal_command and args.command not in COMMANDS:
705
- error(f'Invalid command "{args.command}"')
701
+ colour.error(f'Invalid command "{args.command}"', prefix=True)
706
702
 
707
703
  # If the configuration file exists, read it
708
704
 
@@ -717,7 +713,7 @@ def main():
717
713
  if args.command == 'init':
718
714
  args.configuration_file = os.path.abspath(args.default_configuration_file)
719
715
  else:
720
- error('Cannot locate configuration file')
716
+ colour.error('Cannot locate configuration file', prefix=True)
721
717
 
722
718
  if args.configuration_file and os.path.isfile(args.configuration_file):
723
719
  config.read(args.configuration_file)
@@ -736,7 +732,7 @@ def main():
736
732
  # Everything except '+init' and '+clone' requires the configuration file
737
733
 
738
734
  if args.command not in ('init', 'clone') and args.configuration_file is None:
739
- error('Configuration file not found')
735
+ colour.error('Configuration file not found', prefix=True)
740
736
 
741
737
  COMMANDS[args.command](args, config, console)
742
738
 
@@ -21,21 +21,21 @@ def read_image_hashes(directories):
21
21
  hashes = defaultdict(list)
22
22
 
23
23
  # Walk each directory tree
24
-
24
+
25
25
  for directory in directories:
26
26
  print(f'Scanning directory tree {directory}')
27
-
27
+
28
28
  for root, _, files in os.walk(directory):
29
29
  print(f'Scanning directory {root}')
30
-
30
+
31
31
  for file in files:
32
32
  filepath = os.path.join(root, file)
33
-
33
+
34
34
  fileext = os.path.splitext(file)[1]
35
35
 
36
36
  if fileext.lower() not in ('.jbf', '.ini', '.xml', '.ffs_db'):
37
37
  # Calculate the hash and store path, dimensions and file size under the hash entry in the hashes table
38
-
38
+
39
39
  try:
40
40
  with Image.open(filepath) as image:
41
41
  hash_value = imagehash.average_hash(image, hash_size=12)
@@ -48,9 +48,9 @@ def read_image_hashes(directories):
48
48
 
49
49
  except OSError:
50
50
  sys.stderr.write(f'ERROR: Unable to read {filepath} (size={size})\n')
51
-
51
+
52
52
  # Return the hash table
53
-
53
+
54
54
  return hashes
55
55
 
56
56
  ################################################################################
@@ -62,11 +62,11 @@ def main():
62
62
  parser.add_argument('directories', nargs='*', action='store', help='Directories to search')
63
63
 
64
64
  args = parser.parse_args()
65
-
65
+
66
66
  if not args.directories:
67
67
  print('You must be specify at least one directory')
68
68
  sys.exit(1)
69
-
69
+
70
70
  try:
71
71
  print('Loading cached data')
72
72
 
@@ -78,7 +78,7 @@ def main():
78
78
  hashes = read_image_hashes(args.directories)
79
79
 
80
80
  # Sort the list of hashes so that we can easily find close matches
81
-
81
+
82
82
  print('Sorting hashes')
83
83
 
84
84
  hash_values = sorted([str(hashval) for hashval in hashes])
@@ -70,8 +70,10 @@ def audit(package, version):
70
70
  def main():
71
71
  """ Entry point """
72
72
 
73
- parser = argparse.ArgumentParser(description='Query api.osv.dev to determine whether Python packagers in a requirments.txt file are subject to known security vulnerabilities')
74
- parser.add_argument('requirements', nargs='*', type=str, action='store', help='The requirements file (if not specified, then the script searches for a requirements.txt file)')
73
+ parser = argparse.ArgumentParser(
74
+ description='Query api.osv.dev to determine whether Python packagers in a requirments.txt file are subject to known security vulnerabilities')
75
+ parser.add_argument('requirements', nargs='*', type=str, action='store',
76
+ help='The requirements file (if not specified, then the script searches for a requirements.txt file)')
75
77
  args = parser.parse_args()
76
78
 
77
79
  requirements = args.requirements or glob.glob('**/requirements.txt', recursive=True)
@@ -47,13 +47,13 @@ TF_TAG_ENTRY_IGNORE = re.compile(r'^ +".*" += +".*"')
47
47
  TF_TAG_CHANGE_BLOCK_END = re.compile(r'^ +}$')
48
48
 
49
49
  TF_MISC_REGEX = \
50
- [
51
- { 'regex': re.compile(r'(Read complete after) (\d+s|\d+m\d+s)'), 'replace': r'\1 {ELAPSED}'},
52
- { 'regex': re.compile(r'"(.*:.*)"( = ".*")'), 'replace': r'\1\2'},
53
- { 'regex': re.compile(r'"(.*:.*)"( = \[$)'), 'replace': r'\1\2'},
54
- { 'regex': re.compile(r'^last "terraform apply":$'), 'replace':r'last "terraform apply" which may have affected this plan:'},
55
- { 'find': ' ~ ', 'replace': ' * '},
56
- ]
50
+ [
51
+ {'regex': re.compile(r'(Read complete after) (\d+s|\d+m\d+s)'), 'replace': r'\1 {ELAPSED}'},
52
+ {'regex': re.compile(r'"(.*:.*)"( = ".*")'), 'replace': r'\1\2'},
53
+ {'regex': re.compile(r'"(.*:.*)"( = \[$)'), 'replace': r'\1\2'},
54
+ {'regex': re.compile(r'^last "terraform apply":$'), 'replace': r'last "terraform apply" which may have affected this plan:'},
55
+ {'find': ' ~ ', 'replace': ' * '},
56
+ ]
57
57
 
58
58
  TF_IGNORE_LIST = [
59
59
  {'start': TF_HAS_CHANGED, 'end': TF_HAS_CHANGED_END},
@@ -91,8 +91,10 @@ def parse_command_line():
91
91
  parser.add_argument('--terraform', '-T', action='store_true', help='Clean Terraform plan/apply log files')
92
92
  parser.add_argument('--replace', '-R', action='append', default=None, help='Additional regex replacements in the form "REGEX=REPLACEMENT"')
93
93
  parser.add_argument('--verbose', '-v', action='store_true', help='Output verbose status')
94
- parser.add_argument('--minimal', '-m', action='store_true', help='Remove unnecessary data from the file (e.g. Terraform progress updates (Refreshing..., Reading..., etc.))')
95
- parser.add_argument('--non-minimal', '-M', action='store_true', help='Do not remove unnecessary data from the file (e.g. Terraform progress updates (Refreshing..., Reading..., etc.))')
94
+ parser.add_argument('--minimal', '-m', action='store_true',
95
+ help='Remove unnecessary data from the file (e.g. Terraform progress updates (Refreshing..., Reading..., etc.))')
96
+ parser.add_argument('--non-minimal', '-M', action='store_true',
97
+ help='Do not remove unnecessary data from the file (e.g. Terraform progress updates (Refreshing..., Reading..., etc.))')
96
98
  parser.add_argument('files', nargs='*', default=None, help='The files to convert (use stdin/stout if no input files are specified)')
97
99
 
98
100
  args = parser.parse_args()
@@ -144,7 +146,7 @@ def parse_command_line():
144
146
  for entry in args.replace:
145
147
  regex, replace = entry.split('=')
146
148
  try:
147
- args.regex_replace.append({'regex': re.compile(regex), 'replace':replace})
149
+ args.regex_replace.append({'regex': re.compile(regex), 'replace': replace})
148
150
  except re.error as exc:
149
151
  print(f'ERROR in regular expression {regex}: {exc}')
150
152
  sys.exit(1)
@@ -291,7 +293,7 @@ def cleanfile(args, infile, outfile):
291
293
  # Write normal output, skipping >1 blank lines and skipping ignore blocks when the pre-ignore
292
294
  # count has hit zero.
293
295
 
294
- if clean is not None and not (ignore_until and pre_ignore_count==0):
296
+ if clean is not None and not (ignore_until and pre_ignore_count == 0):
295
297
  if clean != '' or prev_line != '':
296
298
  outfile.write(clean)
297
299
  outfile.write('\n')
@@ -57,7 +57,7 @@ def show_cpu_times(scr, first, w, h, x, y):
57
57
  scr.addstr(y+2, x, 'IRQ:')
58
58
  scr.addstr(y+3, x, 'Soft IRQ:')
59
59
 
60
- x+= w//3
60
+ x += w//3
61
61
 
62
62
  scr.addstr(y+1, x, 'Guest:')
63
63
  scr.addstr(y+2, x, 'Guest Nice:')
@@ -320,7 +320,7 @@ def show_temperatures(scr, first, w, h, x, y):
320
320
 
321
321
  # Panel title and the functions used to update them
322
322
 
323
- BOXES= {
323
+ BOXES = {
324
324
  'System Load': show_system_load,
325
325
  'Disk Access': show_disk_access,
326
326
  'Processes': show_processes,
@@ -184,9 +184,13 @@ def write(txt=None, newline=True, stream=sys.stdout, indent=0, strip=False, clea
184
184
 
185
185
  ################################################################################
186
186
 
187
- def error(txt, newline=True, stream=sys.stderr, status=1):
187
+ def error(txt, newline=True, stream=sys.stderr, status=1, prefix=False):
188
188
  """ Write an error message to the specified stream (defaulting to
189
- stderr) and exit with the specified status code (defaulting to 1) """
189
+ stderr) and exit with the specified status code (defaulting to 1)
190
+ Prefix the output with 'ERROR:' in red if prefix==True """
191
+
192
+ if prefix:
193
+ write('[RED:ERROR]: ', newline=False, stream=stream, )
190
194
 
191
195
  write(txt, newline, stream)
192
196
 
@@ -20,6 +20,7 @@ import thingy.dc_util as dc_util
20
20
  __all__ = ['Dircolors']
21
21
 
22
22
  _CODE_MAP = OrderedDict()
23
+
23
24
  def _init_code_map():
24
25
  """ mapping between the key name in the .dircolors file and the two letter
25
26
  code found in the LS_COLORS environment variable.
@@ -53,6 +54,7 @@ class Dircolors:
53
54
  """ Main dircolors class. Contains a database of formats corresponding to file types,
54
55
  modes, and extensions. Use the format() method to check a file and color it appropriately.
55
56
  """
57
+
56
58
  def __init__(self, load=True):
57
59
  """ Initialize a Dircolors object. If load=True (the default), then try
58
60
  to load dircolors info from the LS_COLORS environment variable.
@@ -98,7 +100,7 @@ class Dircolors:
98
100
  try:
99
101
  code, color = item.split('=', 1)
100
102
  except ValueError:
101
- continue # no key=value, just ignore
103
+ continue # no key=value, just ignore
102
104
  if code.startswith('*.'):
103
105
  self._extensions[code[1:]] = color
104
106
  else:
@@ -134,7 +136,7 @@ class Dircolors:
134
136
  elif isinstance(database, TextIOBase):
135
137
  file = database
136
138
  else:
137
- raise ValueError('database must be str or io.TextIOBase, not %s'%type(database))
139
+ raise ValueError('database must be str or io.TextIOBase, not %s' % type(database))
138
140
 
139
141
  try:
140
142
  for line in file:
@@ -147,18 +149,18 @@ class Dircolors:
147
149
  split = line.split()
148
150
  if len(split) != 2:
149
151
  if strict:
150
- raise ValueError('Warning: unable to parse dircolors line "%s"'%line)
152
+ raise ValueError('Warning: unable to parse dircolors line "%s"' % line)
151
153
  continue
152
154
 
153
155
  key, val = split
154
156
  if key == 'TERM':
155
- continue # ignore TERM directives
157
+ continue # ignore TERM directives
156
158
  elif key in _CODE_MAP:
157
159
  self._codes[_CODE_MAP[key]] = val
158
160
  elif key.startswith('.'):
159
161
  self._extensions[key] = val
160
162
  elif strict:
161
- raise ValueError('Warning: unable to parse dircolors line "%s"'%line)
163
+ raise ValueError('Warning: unable to parse dircolors line "%s"' % line)
162
164
  # elif not strict, skip
163
165
 
164
166
  if self._codes or self._extensions:
@@ -184,14 +186,14 @@ class Dircolors:
184
186
  # change .xyz to *.xyz
185
187
  yield '*' + pair[0], pair[1]
186
188
 
187
- return ':'.join('%s=%s'%pair for pair in gen_pairs())
189
+ return ':'.join('%s=%s' % pair for pair in gen_pairs())
188
190
 
189
191
  def _format_code(self, text, code):
190
192
  """ format text with an lscolors code. Return text unmodified if code
191
193
  isn't found in the database """
192
194
  val = self._codes.get(code, None)
193
195
  if val:
194
- return '\033[%sm%s\033[%sm'%(val, text, self._codes.get('rs', '0'))
196
+ return '\033[%sm%s\033[%sm' % (val, text, self._codes.get('rs', '0'))
195
197
  return text
196
198
 
197
199
  def _format_ext(self, text, ext):
@@ -200,7 +202,7 @@ class Dircolors:
200
202
  text need not actually end in '.ext' """
201
203
  val = self._extensions.get(ext, '0')
202
204
  if val:
203
- return '\033[%sm%s\033[%sm'%(val, text, self._codes.get('rs', '0'))
205
+ return '\033[%sm%s\033[%sm' % (val, text, self._codes.get('rs', '0'))
204
206
  return text
205
207
 
206
208
  def format_mode(self, text, mode):
@@ -225,7 +227,7 @@ class Dircolors:
225
227
  elif isinstance(mode, os.stat_result):
226
228
  mode = mode.st_mode
227
229
  else:
228
- raise ValueError('mode must be int or os.stat_result, not %s'%type(mode))
230
+ raise ValueError('mode must be int or os.stat_result, not %s' % type(mode))
229
231
 
230
232
  if mode:
231
233
  if stat.S_ISDIR(mode):
@@ -244,13 +246,13 @@ class Dircolors:
244
246
  # special file?
245
247
  # pylint: disable=bad-whitespace
246
248
  special_types = (
247
- (stat.S_IFLNK, 'ln'), # symlink
248
- (stat.S_IFIFO, 'pi'), # pipe (FIFO)
249
- (stat.S_IFSOCK, 'so'), # socket
250
- (stat.S_IFBLK, 'bd'), # block device
251
- (stat.S_IFCHR, 'cd'), # character device
252
- (stat.S_ISUID, 'su'), # setuid
253
- (stat.S_ISGID, 'sg'), # setgid
249
+ (stat.S_IFLNK, 'ln'), # symlink
250
+ (stat.S_IFIFO, 'pi'), # pipe (FIFO)
251
+ (stat.S_IFSOCK, 'so'), # socket
252
+ (stat.S_IFBLK, 'bd'), # block device
253
+ (stat.S_IFCHR, 'cd'), # character device
254
+ (stat.S_ISUID, 'su'), # setuid
255
+ (stat.S_ISGID, 'sg'), # setgid
254
256
  )
255
257
 
256
258
  for mask, code in special_types:
@@ -290,13 +292,13 @@ class Dircolors:
290
292
  try:
291
293
  statbuf = dc_util.stat_at(file, cwd, follow_symlinks)
292
294
  except OSError as e:
293
- return '%s [Error stat-ing: %s]'%(file, e.strerror)
295
+ return '%s [Error stat-ing: %s]' % (file, e.strerror)
294
296
 
295
297
  mode = statbuf.st_mode
296
298
  if (not follow_symlinks) and show_target and stat.S_ISLNK(mode):
297
299
  target_path = dc_util.readlink_at(file, cwd)
298
300
  try:
299
- dc_util.stat_at(target_path, cwd) # check for broken link
301
+ dc_util.stat_at(target_path, cwd) # check for broken link
300
302
  target = self.format(target_path, cwd, False, False)
301
303
  except OSError:
302
304
  # format as "orphan"
@@ -1287,7 +1287,6 @@ def log(branch1, branch2=None):
1287
1287
 
1288
1288
  def clean(recurse=False, force=False, dry_run=False, quiet=False,
1289
1289
  exclude=None, ignore_rules=False, remove_only_ignored=False, path=None):
1290
-
1291
1290
  """ Run git clean """
1292
1291
 
1293
1292
  cmd = ['clean']
@@ -82,6 +82,6 @@ class PopUp():
82
82
  time.sleep(1 - elapsed)
83
83
 
84
84
  del self.panel
85
-
85
+
86
86
  if self.refresh:
87
87
  self.screen.refresh()
@@ -148,7 +148,7 @@ class Pane():
148
148
 
149
149
  filestat = os.stat(filename, follow_symlinks=False)
150
150
 
151
- info = {'name':filename,
151
+ info = {'name': filename,
152
152
  'mode': filestat.st_mode,
153
153
  'uid': filestat.st_uid,
154
154
  'gid': filestat.st_gid,
@@ -310,7 +310,7 @@ class Pane():
310
310
  else:
311
311
  self.screen.clrtoeol()
312
312
 
313
- #if len(filename) < self.width:
313
+ # if len(filename) < self.width:
314
314
  # self.screen.addstr(self.file_list_y + ypos, len(filename), ' ' * (self.width - len(filename)), normal_colour)
315
315
 
316
316
  current_dir = path.trimpath(self.current_dir, self.width)
@@ -541,7 +541,7 @@ class Pane():
541
541
 
542
542
  self.height = height
543
543
  self.file_list_h = height-1
544
- self.width = pane_width-1 # TODO: Why '-1'?
544
+ self.width = pane_width-1 # TODO: Why '-1'?
545
545
  self.screen.resize(height, pane_width)
546
546
  self.screen.mvwin(y, x + pane_width*self.index)
547
547
 
@@ -76,23 +76,24 @@ RE_SHA1 = [
76
76
  # AWS ids
77
77
 
78
78
  RE_AWS = \
79
- [
80
- {'regex': re.compile(r'eni-0[0-9a-f]{16}'), 'replace': '{ENI-ID}'},
81
- {'regex': re.compile(r'ami-0[0-9a-f]{16}'), 'replace': '{AMI-ID}'},
82
- {'regex': re.compile(r'snap-0[0-9a-f]{16}'), 'replace': '{AMI-SNAP}'},
83
- {'regex': re.compile(r'vol-0[0-9a-f]{16}'), 'replace': '{AMI-VOL}'},
84
- {'regex': re.compile(r'sir-[0-9a-z]{8}'), 'replace': '{SPOT-INSTANCE}'},
85
- {'regex': re.compile(r'i-0[0-9a-f]{16}'), 'replace': '{EC2-ID}'},
86
- {'regex': re.compile(r'request id: [0-0a-f]{8}-[0-0a-f]{4}-[0-0a-f]{4}-[0-0a-f]{4}-[0-0a-f]{12}'), 'replace': 'request id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
87
- ]
79
+ [
80
+ {'regex': re.compile(r'eni-0[0-9a-f]{16}'), 'replace': '{ENI-ID}'},
81
+ {'regex': re.compile(r'ami-0[0-9a-f]{16}'), 'replace': '{AMI-ID}'},
82
+ {'regex': re.compile(r'snap-0[0-9a-f]{16}'), 'replace': '{AMI-SNAP}'},
83
+ {'regex': re.compile(r'vol-0[0-9a-f]{16}'), 'replace': '{AMI-VOL}'},
84
+ {'regex': re.compile(r'sir-[0-9a-z]{8}'), 'replace': '{SPOT-INSTANCE}'},
85
+ {'regex': re.compile(r'i-0[0-9a-f]{16}'), 'replace': '{EC2-ID}'},
86
+ {'regex': re.compile(r'request id: [0-0a-f]{8}-[0-0a-f]{4}-[0-0a-f]{4}-[0-0a-f]{4}-[0-0a-f]{12}'),
87
+ 'replace': 'request id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
88
+ ]
88
89
 
89
90
  # Data transfer speeds
90
91
 
91
92
  RE_SPEED = \
92
- [
93
- {'regex': re.compile(r'[0-9.]+ *MB/s'), 'replace': '{SPEED}'},
94
- {'regex': re.compile(r'[0-9.]+ *MiB/s'), 'replace': '{SPEED}'},
95
- ]
93
+ [
94
+ {'regex': re.compile(r'[0-9.]+ *MB/s'), 'replace': '{SPEED}'},
95
+ {'regex': re.compile(r'[0-9.]+ *MiB/s'), 'replace': '{SPEED}'},
96
+ ]
96
97
 
97
98
  ################################################################################
98
99
 
@@ -52,10 +52,11 @@ def main():
52
52
 
53
53
  # Set the path, defaulting to the current directory
54
54
 
55
- if args.path:
56
- full_path = args.path
57
- else:
58
- full_path = os.getcwd()
55
+ try:
56
+ full_path = args.path or os.getcwd()
57
+ except FileNotFoundError:
58
+ logging.critical('Unable to locate directory')
59
+ sys.exit(1)
59
60
 
60
61
  trimmed = path.trimpath(full_path, trim_width)
61
62
 
@@ -24,7 +24,7 @@ def main():
24
24
 
25
25
  statinfo = os.stat(script)
26
26
 
27
- os.chmod(script, statinfo.st_mode|stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH)
27
+ os.chmod(script, statinfo.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
28
28
 
29
29
  print(f'Created virtual environment: {script}')
30
30
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skilleter_thingy
3
- Version: 0.1.18
3
+ Version: 0.1.21
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