@codebend3r/che 1.1.0 → 1.2.0
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.
- package/README.md +38 -24
- package/bin/art.py +22 -20
- package/bin/che.py +208 -587
- package/bin/commands.py +220 -231
- package/bin/doctor.py +220 -0
- package/bin/drives/eject-all-drives.py +21 -38
- package/bin/drives/mount-all-drives.py +18 -62
- package/bin/drives/ping-nas.py +77 -105
- package/bin/files/compress-folders.py +7 -11
- package/bin/files/delete-by-ext.py +10 -14
- package/bin/files/delete-empty-folders.py +33 -37
- package/bin/files/delete-smb-files.py +12 -21
- package/bin/files/files-under-size.py +5 -11
- package/bin/files/find-largest-files.py +21 -25
- package/bin/files/list-permission.py +40 -0
- package/bin/files/make-alpha-dir.py +2 -0
- package/bin/git/all-actions.py +350 -253
- package/bin/git/checkout-my-branches.py +42 -63
- package/bin/git/clean-stale-branches.py +23 -48
- package/bin/git/prune-worktrees.py +12 -51
- package/bin/git/sync-all-branches.py +54 -283
- package/bin/git/update-local-branches.py +67 -73
- package/bin/gitutils.py +263 -0
- package/bin/install.py +393 -1182
- package/bin/machine.py +345 -0
- package/bin/media.py +127 -0
- package/bin/menu.py +437 -0
- package/bin/nas.py +102 -0
- package/bin/rcfile.py +380 -0
- package/bin/shellgen.py +503 -431
- package/bin/system/btop-launch.py +17 -13
- package/bin/system/update-brew.py +57 -68
- package/bin/tui.py +156 -153
- package/bin/utils.py +165 -237
- package/bin/video/delete-duplicate-videos.py +64 -62
- package/bin/video/detect-green-magenta-videos.py +105 -95
- package/bin/video/find-movie-by-year.py +3 -0
- package/bin/video/find-video-mkv-issues.py +48 -65
- package/bin/video/fix-codecs.py +25 -30
- package/bin/video/largest-tv-shows.py +60 -57
- package/bin/video/remove-metadata.py +3 -6
- package/bin/video/rename-video-file.py +74 -84
- package/bin/video/scan-videos-audio-language.py +16 -33
- package/bin/video/show-codecs.py +20 -24
- package/bin/video/validate-video-files.py +5 -8
- package/bin/video/video-list.py +17 -20
- package/package.json +4 -10
- package/shell/che.bash +33 -33
- package/shell/che.fish +7 -7
- package/shell/che.zsh +33 -33
- package/shell/completions/_che +19 -19
- package/shell/completions/che.bash +15 -15
- package/shell/completions/che.fish +34 -50
|
@@ -14,8 +14,8 @@ Options:
|
|
|
14
14
|
from __future__ import annotations
|
|
15
15
|
|
|
16
16
|
import heapq
|
|
17
|
-
import re
|
|
18
17
|
import sys
|
|
18
|
+
from collections.abc import Iterator
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
|
|
21
21
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
@@ -26,15 +26,13 @@ from utils import (
|
|
|
26
26
|
format_bytes,
|
|
27
27
|
info,
|
|
28
28
|
iter_files,
|
|
29
|
-
|
|
29
|
+
note_settings,
|
|
30
|
+
parse_count,
|
|
30
31
|
run_cli,
|
|
31
32
|
scan_root,
|
|
32
|
-
warning,
|
|
33
33
|
)
|
|
34
34
|
|
|
35
|
-
__version__ = "2.0
|
|
36
|
-
|
|
37
|
-
_NON_NEGATIVE_INT = re.compile(r"[0-9]+")
|
|
35
|
+
__version__ = "2.1.0"
|
|
38
36
|
|
|
39
37
|
|
|
40
38
|
def main(argv: list[str] | None = None) -> int:
|
|
@@ -43,32 +41,29 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
43
41
|
description="📊 List the largest files under a path, biggest first.",
|
|
44
42
|
)
|
|
45
43
|
parser.add_argument("--path", default=".", metavar="DIR", help="Directory to scan (default: .)")
|
|
46
|
-
#
|
|
47
|
-
# error and exit before the shell version's own message could be produced.
|
|
44
|
+
# A string, validated by parse_count below rather than `type=int`.
|
|
48
45
|
parser.add_argument(
|
|
49
46
|
"--length", default="10", metavar="N", help="How many files to list (default: 10)"
|
|
50
47
|
)
|
|
51
|
-
add_bool_flag(parser, "--full-path",
|
|
48
|
+
add_bool_flag(parser, "--full-path", help="Print the whole path")
|
|
52
49
|
|
|
53
50
|
info(f"Running command in {Path.cwd()}")
|
|
54
51
|
args = parser.parse_args(argv)
|
|
55
52
|
|
|
56
|
-
|
|
57
|
-
warning("❌ --length must be a non-negative integer")
|
|
58
|
-
return 1
|
|
59
|
-
length = int(args.length)
|
|
60
|
-
|
|
61
|
-
if not args.path:
|
|
62
|
-
warning("❌ --path cannot be empty")
|
|
63
|
-
return 1
|
|
53
|
+
length = parse_count(args.length, "--length")
|
|
64
54
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
55
|
+
note_settings(
|
|
56
|
+
("Searching in", args.path),
|
|
57
|
+
("List length", length),
|
|
58
|
+
("Show full path", args.full_path),
|
|
59
|
+
rule=False,
|
|
60
|
+
)
|
|
68
61
|
|
|
62
|
+
# An empty --path reads "--path is required" after the settings, where the
|
|
63
|
+
# shell version printed "--path cannot be empty" before them.
|
|
69
64
|
root = scan_root(args.path)
|
|
70
65
|
|
|
71
|
-
def sized() ->
|
|
66
|
+
def sized() -> Iterator[tuple[int, str, Path]]:
|
|
72
67
|
for path in iter_files(root, skip_macos_metadata=False):
|
|
73
68
|
try:
|
|
74
69
|
size = path.stat().st_size
|
|
@@ -80,10 +75,11 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
80
75
|
yield size, str(path), path
|
|
81
76
|
|
|
82
77
|
# `sort -nr | head -n N` ties break on the whole line DESCENDING, because
|
|
83
|
-
# -r reverses the last-resort comparison too. nlargest on (size, str)
|
|
84
|
-
# the same ordering
|
|
85
|
-
#
|
|
86
|
-
|
|
78
|
+
# -r reverses the last-resort comparison too. nlargest on (size, str, ...)
|
|
79
|
+
# gives the same ordering - the path string is unique, so the comparison
|
|
80
|
+
# never reaches the Path - and holds only N entries rather than the whole
|
|
81
|
+
# tree: a million-file media root would otherwise cost about a gigabyte.
|
|
82
|
+
top = heapq.nlargest(length, sized())
|
|
87
83
|
|
|
88
84
|
for size, _, path in top:
|
|
89
85
|
if args.full_path:
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""🔐 Show the ownership and mode of a volume under ``/Volumes``.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
list-permission.py [VOLUME] (no VOLUME lists /Volumes itself)
|
|
6
|
+
|
|
7
|
+
Options:
|
|
8
|
+
--help Show help
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
17
|
+
|
|
18
|
+
from utils import build_parser, run, run_cli
|
|
19
|
+
|
|
20
|
+
__version__ = "1.0.0"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main(argv: list[str] | None = None) -> int:
|
|
24
|
+
parser = build_parser(
|
|
25
|
+
prog="list-permission",
|
|
26
|
+
description="🔐 Show ownership and mode of a volume under /Volumes.",
|
|
27
|
+
)
|
|
28
|
+
parser.add_argument("volume", nargs="?", default="", help="Volume name (default: /Volumes)")
|
|
29
|
+
# DELIBERATE DIVERGENCE from the shell wrapper, `command ls -ld
|
|
30
|
+
# "/Volumes/$1"`, which ignored any argument after the first. A second one
|
|
31
|
+
# is an error here rather than silently dropped.
|
|
32
|
+
args = parser.parse_args(argv)
|
|
33
|
+
|
|
34
|
+
# `ls` runs as a program, so a user's `alias ls=eza` never replaces the
|
|
35
|
+
# `ls -l` listing - the reason the wrapper spelled it `command ls`.
|
|
36
|
+
return run(["ls", "-ld", f"/Volumes/{args.volume}"], check=False).returncode
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if __name__ == "__main__":
|
|
40
|
+
run_cli(main)
|