@codebend3r/che 1.0.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/LICENSE +21 -0
- package/README.md +424 -0
- package/bin/che.py +869 -0
- package/bin/commands.py +872 -0
- package/bin/drives/eject-all-drives.py +203 -0
- package/bin/drives/mount-all-drives.py +140 -0
- package/bin/drives/ping-nas.py +242 -0
- package/bin/files/compress-folders.py +188 -0
- package/bin/files/delete-by-ext.py +108 -0
- package/bin/files/delete-empty-folders.py +136 -0
- package/bin/files/delete-smb-files.py +105 -0
- package/bin/files/files-under-size.py +132 -0
- package/bin/files/find-largest-files.py +102 -0
- package/bin/files/make-alpha-dir.py +63 -0
- package/bin/git/all-actions.py +545 -0
- package/bin/git/checkout-my-branches.py +147 -0
- package/bin/git/clean-stale-branches.py +161 -0
- package/bin/git/prune-worktrees.py +143 -0
- package/bin/git/sync-all-branches.py +368 -0
- package/bin/git/update-local-branches.py +195 -0
- package/bin/install.py +1515 -0
- package/bin/shellgen.py +782 -0
- package/bin/system/btop-launch.py +114 -0
- package/bin/system/update-brew.py +146 -0
- package/bin/tui.py +648 -0
- package/bin/utils.py +836 -0
- package/bin/video/delete-duplicate-videos.py +313 -0
- package/bin/video/detect-green-magenta-videos.py +268 -0
- package/bin/video/find-movie-by-year.py +84 -0
- package/bin/video/find-video-mkv-issues.py +242 -0
- package/bin/video/fix-codecs.py +209 -0
- package/bin/video/largest-tv-shows.py +175 -0
- package/bin/video/remove-metadata.py +126 -0
- package/bin/video/rename-video-file.py +329 -0
- package/bin/video/scan-videos-audio-language.py +110 -0
- package/bin/video/show-codecs.py +111 -0
- package/bin/video/validate-video-files.py +114 -0
- package/bin/video/video-list.py +120 -0
- package/package.json +54 -0
- package/shell/che.bash +382 -0
- package/shell/che.fish +282 -0
- package/shell/che.zsh +389 -0
- package/shell/completions/_che +146 -0
- package/shell/completions/che.bash +107 -0
- package/shell/completions/che.fish +371 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""๐ฅ๏ธ Launch btop with a gruvbox theme that follows the macOS appearance.
|
|
3
|
+
|
|
4
|
+
Light mode uses ``gruvbox_light``, Dark mode ``gruvbox_dark_v2``. The chosen
|
|
5
|
+
theme is written into ``btop.conf`` before launch, because btop reads its
|
|
6
|
+
config once at start.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
btop-launch.py [btop-args...]
|
|
10
|
+
|
|
11
|
+
Any extra arguments are passed straight through to btop.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import re
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
22
|
+
|
|
23
|
+
from utils import info, require_binary, run, warning
|
|
24
|
+
|
|
25
|
+
__version__ = "1.0.1"
|
|
26
|
+
|
|
27
|
+
CONF = Path.home() / ".config" / "btop" / "btop.conf"
|
|
28
|
+
LIGHT_THEME = "gruvbox_light"
|
|
29
|
+
DARK_THEME = "gruvbox_dark_v2"
|
|
30
|
+
|
|
31
|
+
USAGE = f"""Usage:
|
|
32
|
+
btop-launch.py [btop-args...]
|
|
33
|
+
|
|
34
|
+
Description:
|
|
35
|
+
๐ฅ๏ธ Set btop's color_theme to match the current macOS appearance
|
|
36
|
+
({LIGHT_THEME} in Light mode, {DARK_THEME} in Dark mode), then exec btop.
|
|
37
|
+
Any extra arguments are passed straight through to btop.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
# `[^\S\n]` rather than `\s`: \s matches newlines, so a config with a line
|
|
41
|
+
# break between "color_theme" and "=" would have two lines collapsed into one.
|
|
42
|
+
# perl -p works a line at a time and cannot do that.
|
|
43
|
+
_COLOR_THEME_RE = re.compile(r"^color_theme[^\S\n]*=.*$", re.MULTILINE)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def current_theme() -> str:
|
|
47
|
+
"""Pick the theme matching the macOS appearance.
|
|
48
|
+
|
|
49
|
+
``defaults read -g AppleInterfaceStyle`` prints "Dark" in Dark mode and
|
|
50
|
+
exits non-zero (the key is absent) in Light mode.
|
|
51
|
+
"""
|
|
52
|
+
completed = run(["defaults", "read", "-g", "AppleInterfaceStyle"], check=False, capture=True)
|
|
53
|
+
value = (completed.stdout or "").strip() if completed.returncode == 0 else ""
|
|
54
|
+
return DARK_THEME if value == "Dark" else LIGHT_THEME
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def apply_theme(theme: str) -> None:
|
|
58
|
+
"""Rewrite the ``color_theme`` line in btop.conf, leaving the rest alone."""
|
|
59
|
+
if not CONF.is_file():
|
|
60
|
+
warning(f"btop config not found at {CONF}; launching with existing theme")
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
# newline="" so existing CRLF (or CR) line endings survive the
|
|
65
|
+
# round-trip; read_text/write_text would rewrite every line ending in
|
|
66
|
+
# the file, where `perl -i` only ever touched the matched line.
|
|
67
|
+
# surrogateescape so a config carrying non-UTF-8 bytes still round-trips
|
|
68
|
+
# instead of raising and leaving btop unlaunchable.
|
|
69
|
+
with CONF.open("r", encoding="utf-8", errors="surrogateescape", newline="") as handle:
|
|
70
|
+
original = handle.read()
|
|
71
|
+
except OSError as exc:
|
|
72
|
+
warning(f"Could not read {CONF}: {exc}; launching with existing theme")
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
updated, count = _COLOR_THEME_RE.subn(f'color_theme = "{theme}"', original)
|
|
76
|
+
if count == 0:
|
|
77
|
+
warning(f"No color_theme line in {CONF}; launching with existing theme")
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
if updated != original:
|
|
81
|
+
try:
|
|
82
|
+
with CONF.open("w", encoding="utf-8", errors="surrogateescape", newline="") as handle:
|
|
83
|
+
handle.write(updated)
|
|
84
|
+
except OSError as exc:
|
|
85
|
+
warning(f"Could not write {CONF}: {exc}; launching with existing theme")
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
info(f"btop theme -> {theme}")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def main(argv: list[str] | None = None) -> int:
|
|
92
|
+
args = list(sys.argv[1:] if argv is None else argv)
|
|
93
|
+
|
|
94
|
+
if args and args[0] in ("-h", "--help"):
|
|
95
|
+
print(USAGE)
|
|
96
|
+
return 0
|
|
97
|
+
|
|
98
|
+
# Theme first, then the binary check: the shell version rewrote the config
|
|
99
|
+
# even when btop was missing, so re-ordering would silently stop the theme
|
|
100
|
+
# tracking the system appearance on a machine where btop is not installed.
|
|
101
|
+
apply_theme(current_theme())
|
|
102
|
+
|
|
103
|
+
btop = require_binary("btop", hint="Install it with `brew install btop`.")
|
|
104
|
+
|
|
105
|
+
# exec, not spawn: btop is a full-screen TUI and this process has nothing
|
|
106
|
+
# left to do. Replacing the image keeps signal handling and the exit code
|
|
107
|
+
# identical to running btop directly, exactly like `exec btop "$@"`.
|
|
108
|
+
# argv[0] stays the bare name, which is what btop echoes in its own usage.
|
|
109
|
+
os.execv(btop, ["btop", *args]) # noqa: S606 - absolute path, no shell
|
|
110
|
+
return 0 # unreachable; execv never returns
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
if __name__ == "__main__":
|
|
114
|
+
sys.exit(main())
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""๐บ Update Homebrew, upgrade formulae and casks, then clean up.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
update-brew.py [--dry-run] [--no-cask] [--no-cleanup] [--no-autoremove]
|
|
6
|
+
[--greedy] [--doctor]
|
|
7
|
+
|
|
8
|
+
Options:
|
|
9
|
+
--dry-run Show what would be upgraded/removed, change nothing
|
|
10
|
+
--no-cask Skip upgrading casks (apps)
|
|
11
|
+
--no-cleanup Skip 'brew cleanup' at the end
|
|
12
|
+
--no-autoremove Skip 'brew autoremove' (leave unused deps in place)
|
|
13
|
+
--greedy Pass --greedy to cask upgrade (force-update self-updating apps)
|
|
14
|
+
--doctor Run 'brew doctor' at the very end
|
|
15
|
+
--help Show help
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import sys
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
24
|
+
|
|
25
|
+
from utils import (
|
|
26
|
+
add_bool_flag,
|
|
27
|
+
build_parser,
|
|
28
|
+
info,
|
|
29
|
+
log,
|
|
30
|
+
note,
|
|
31
|
+
require_binary,
|
|
32
|
+
run,
|
|
33
|
+
run_cli,
|
|
34
|
+
success,
|
|
35
|
+
warning,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__version__ = "1.0.0"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def brew(
|
|
42
|
+
argv: list[str],
|
|
43
|
+
*,
|
|
44
|
+
dry_run: bool,
|
|
45
|
+
dry_run_argv: list[str] | None = None,
|
|
46
|
+
echo: bool = False,
|
|
47
|
+
) -> None:
|
|
48
|
+
"""Run a brew subcommand, or its --dry-run form.
|
|
49
|
+
|
|
50
|
+
Homebrew's own ``--dry-run`` exits non-zero in some situations that are not
|
|
51
|
+
really failures, so the preview calls are non-fatal - the same ``|| true``
|
|
52
|
+
the shell version used. The real calls stay fatal.
|
|
53
|
+
"""
|
|
54
|
+
if dry_run:
|
|
55
|
+
if dry_run_argv is None:
|
|
56
|
+
warning(f" ๐ช Would run: {' '.join(argv)}")
|
|
57
|
+
return
|
|
58
|
+
run(dry_run_argv, check=False)
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
# Only `brew update` echoed its command in the shell version; the other
|
|
62
|
+
# steps called brew directly, and brew narrates itself.
|
|
63
|
+
if echo:
|
|
64
|
+
log(f" โถ {' '.join(argv)}")
|
|
65
|
+
run(argv)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def main(argv: list[str] | None = None) -> int:
|
|
69
|
+
parser = build_parser(
|
|
70
|
+
prog="update-brew",
|
|
71
|
+
description="๐บ Update Homebrew, upgrade formulae and casks, then clean up.",
|
|
72
|
+
)
|
|
73
|
+
add_bool_flag(parser, "--dry-run", help="Show what would change, change nothing")
|
|
74
|
+
add_bool_flag(parser, "--no-cask", dest="no_cask", help="Skip upgrading casks")
|
|
75
|
+
add_bool_flag(parser, "--no-cleanup", dest="no_cleanup", help="Skip 'brew cleanup'")
|
|
76
|
+
add_bool_flag(parser, "--no-autoremove", dest="no_autoremove", help="Skip 'brew autoremove'")
|
|
77
|
+
add_bool_flag(parser, "--greedy", help="Pass --greedy to cask upgrade")
|
|
78
|
+
add_bool_flag(parser, "--doctor", help="Run 'brew doctor' at the very end")
|
|
79
|
+
args = parser.parse_args(argv)
|
|
80
|
+
|
|
81
|
+
require_binary("brew", hint="Install Homebrew first: https://brew.sh")
|
|
82
|
+
|
|
83
|
+
dry = args.dry_run
|
|
84
|
+
header_suffix = " ๐ต (dry run)" if dry else ""
|
|
85
|
+
note("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ")
|
|
86
|
+
note(f"๐บ update-brew{header_suffix}")
|
|
87
|
+
note("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ")
|
|
88
|
+
|
|
89
|
+
# 1. Refresh Homebrew itself and tap metadata
|
|
90
|
+
info("๐ก Updating Homebrew metadata...")
|
|
91
|
+
brew(["brew", "update"], dry_run=dry, echo=True)
|
|
92
|
+
|
|
93
|
+
# 2. Upgrade formulae
|
|
94
|
+
info("โฌ๏ธ Upgrading formulae...")
|
|
95
|
+
brew(["brew", "upgrade"], dry_run=dry, dry_run_argv=["brew", "upgrade", "--dry-run"])
|
|
96
|
+
|
|
97
|
+
# 3. Upgrade casks (apps)
|
|
98
|
+
if args.no_cask:
|
|
99
|
+
note("โญ๏ธ Skipping cask upgrades (--no-cask)")
|
|
100
|
+
else:
|
|
101
|
+
info("๐ฆ Upgrading casks...")
|
|
102
|
+
cask_argv = ["brew", "upgrade", "--cask"]
|
|
103
|
+
if args.greedy:
|
|
104
|
+
cask_argv.append("--greedy")
|
|
105
|
+
brew(cask_argv, dry_run=dry, dry_run_argv=[*cask_argv, "--dry-run"])
|
|
106
|
+
|
|
107
|
+
# 4. Remove unused dependencies
|
|
108
|
+
if args.no_autoremove:
|
|
109
|
+
note("โญ๏ธ Skipping autoremove (--no-autoremove)")
|
|
110
|
+
else:
|
|
111
|
+
info("๐งน Removing unused dependencies...")
|
|
112
|
+
brew(
|
|
113
|
+
["brew", "autoremove"],
|
|
114
|
+
dry_run=dry,
|
|
115
|
+
dry_run_argv=["brew", "autoremove", "--dry-run"],
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# 5. Cleanup old versions + cache
|
|
119
|
+
if args.no_cleanup:
|
|
120
|
+
note("โญ๏ธ Skipping cleanup (--no-cleanup)")
|
|
121
|
+
else:
|
|
122
|
+
info("๐๏ธ Cleaning up old versions and cache...")
|
|
123
|
+
brew(
|
|
124
|
+
["brew", "cleanup", "-s"],
|
|
125
|
+
dry_run=dry,
|
|
126
|
+
dry_run_argv=["brew", "cleanup", "--dry-run", "-s"],
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# 6. Optional doctor pass - advisory, never fatal
|
|
130
|
+
if args.doctor:
|
|
131
|
+
info("๐ฉบ Running brew doctor...")
|
|
132
|
+
completed = run(["brew", "doctor"], check=False)
|
|
133
|
+
if completed.returncode != 0:
|
|
134
|
+
warning("โ ๏ธ brew doctor reported issues (non-fatal)")
|
|
135
|
+
|
|
136
|
+
print()
|
|
137
|
+
note("โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ")
|
|
138
|
+
if dry:
|
|
139
|
+
log("๐ก Dry run complete. Nothing was actually changed.")
|
|
140
|
+
else:
|
|
141
|
+
success("๐ Homebrew is up to date and tidy! ๐บโจ")
|
|
142
|
+
return 0
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
if __name__ == "__main__":
|
|
146
|
+
run_cli(main)
|