shellscripts 0.23.1__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.
Files changed (45) hide show
  1. shell_scripts/__init__.py +5 -0
  2. shell_scripts/__main__.py +5 -0
  3. shell_scripts/commands/__init__.py +81 -0
  4. shell_scripts/commands/_dc_common.py +138 -0
  5. shell_scripts/commands/ai_install.py +453 -0
  6. shell_scripts/commands/bin_links.py +78 -0
  7. shell_scripts/commands/claude.py +56 -0
  8. shell_scripts/commands/clean.py +98 -0
  9. shell_scripts/commands/codex.py +107 -0
  10. shell_scripts/commands/copilot.py +54 -0
  11. shell_scripts/commands/dicom2jpg.py +98 -0
  12. shell_scripts/commands/dicomviewer.py +83 -0
  13. shell_scripts/commands/diff_cmd.py +50 -0
  14. shell_scripts/commands/doxygen_cmd.py +159 -0
  15. shell_scripts/commands/edit_cmd.py +50 -0
  16. shell_scripts/commands/gemini.py +54 -0
  17. shell_scripts/commands/kiro.py +54 -0
  18. shell_scripts/commands/opencode.py +54 -0
  19. shell_scripts/commands/pdf_crop.py +520 -0
  20. shell_scripts/commands/pdf_merge.py +180 -0
  21. shell_scripts/commands/pdf_split_by_format.py +243 -0
  22. shell_scripts/commands/pdf_split_by_toc.py +197 -0
  23. shell_scripts/commands/pdf_tiler_090.py +61 -0
  24. shell_scripts/commands/pdf_tiler_100.py +61 -0
  25. shell_scripts/commands/pdf_toc_clean.py +175 -0
  26. shell_scripts/commands/pi.py +61 -0
  27. shell_scripts/commands/req_cmd.py +362 -0
  28. shell_scripts/commands/tests_cmd.py +87 -0
  29. shell_scripts/commands/ubuntu_dark_theme.py +64 -0
  30. shell_scripts/commands/venv_cmd.py +82 -0
  31. shell_scripts/commands/video2h264.py +89 -0
  32. shell_scripts/commands/video2h265.py +87 -0
  33. shell_scripts/commands/view_cmd.py +50 -0
  34. shell_scripts/commands/vscode_cmd.py +42 -0
  35. shell_scripts/commands/vsinsider_cmd.py +42 -0
  36. shell_scripts/config.py +328 -0
  37. shell_scripts/core.py +324 -0
  38. shell_scripts/utils.py +455 -0
  39. shell_scripts/version_check.py +323 -0
  40. shellscripts-0.23.1.dist-info/METADATA +310 -0
  41. shellscripts-0.23.1.dist-info/RECORD +45 -0
  42. shellscripts-0.23.1.dist-info/WHEEL +5 -0
  43. shellscripts-0.23.1.dist-info/entry_points.txt +3 -0
  44. shellscripts-0.23.1.dist-info/licenses/LICENSE +674 -0
  45. shellscripts-0.23.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env python3
2
+ import os
3
+ import shutil
4
+ import subprocess
5
+ import tempfile
6
+ import xml.etree.ElementTree as ET
7
+ from pathlib import Path
8
+
9
+ from shell_scripts.utils import require_project_root, require_commands, print_error
10
+
11
+ PROGRAM = "shellscripts"
12
+ DESCRIPTION = "Generate Doxygen documentation (HTML, PDF, Markdown)."
13
+
14
+
15
+ def print_help(version):
16
+ print(f"Usage: {PROGRAM} doxygen ({version})")
17
+ print()
18
+ print("doxygen options:")
19
+ print(" --help - Show this help message.")
20
+ print()
21
+ print("Generates HTML, PDF, and Markdown documentation in doxygen/ directory.")
22
+ print("Requires: doxygen, make, pdflatex.")
23
+
24
+
25
+ def _supports_generate_markdown():
26
+ require_commands("doxygen")
27
+ try:
28
+ result = subprocess.run(
29
+ ["doxygen", "-x"],
30
+ capture_output=True,
31
+ text=True,
32
+ timeout=10,
33
+ )
34
+ return "GENERATE_MARKDOWN" in result.stdout
35
+ except Exception:
36
+ return False
37
+
38
+
39
+ def _write_doxyfile(path, project_root, src_dir, doxygen_dir, has_md):
40
+ content = f"""PROJECT_NAME = "{project_root.name}"
41
+ OUTPUT_DIRECTORY = "{doxygen_dir}"
42
+ INPUT = "{src_dir}"
43
+ FILE_PATTERNS = *.py *.sh *.js *.ts *.go *.java *.c *.cpp *.h *.hpp *.rb *.php *.rs *.swift *.kt *.scala *.lua *.r *.m *.mm *.cs
44
+ RECURSIVE = YES
45
+ EXTRACT_ALL = YES
46
+ EXTRACT_PRIVATE = YES
47
+ EXTRACT_STATIC = YES
48
+ EXTRACT_LOCAL_CLASSES = YES
49
+ EXTRACT_ANON_NSPACES = YES
50
+ JAVADOC_AUTOBRIEF = YES
51
+ MULTILINE_CPP_IS_BRIEF = YES
52
+ SORT_MEMBER_DOCS = YES
53
+ SORT_BRIEF_DOCS = YES
54
+ FULL_PATH_NAMES = NO
55
+ STRIP_FROM_PATH = "{project_root}"
56
+ WARN_IF_UNDOCUMENTED = NO
57
+ WARN_IF_DOC_ERROR = YES
58
+ WARN_NO_PARAMDOC = NO
59
+ QUIET = YES
60
+ GENERATE_HTML = YES
61
+ HTML_OUTPUT = html
62
+ GENERATE_LATEX = YES
63
+ LATEX_OUTPUT = latex
64
+ USE_PDFLATEX = YES
65
+ GENERATE_XML = YES
66
+ XML_OUTPUT = xml
67
+ MARKDOWN_ID_STYLE = GITHUB
68
+ TOC_INCLUDE_HEADINGS = 3
69
+ """
70
+ if has_md:
71
+ content += "GENERATE_MARKDOWN = YES\nMARKDOWN_OUTPUT = markdown\n"
72
+
73
+ Path(path).write_text(content)
74
+
75
+
76
+ def _generate_markdown_fallback(xml_dir, markdown_dir):
77
+ markdown_dir.mkdir(parents=True, exist_ok=True)
78
+ index_xml = xml_dir / "index.xml"
79
+ if not index_xml.exists():
80
+ return
81
+
82
+ root = ET.parse(str(index_xml)).getroot()
83
+ entries = []
84
+ for compound in root.findall("compound"):
85
+ name = (compound.findtext("name") or "").strip()
86
+ kind = (compound.get("kind") or "").strip()
87
+ refid = (compound.get("refid") or "").strip()
88
+ if name:
89
+ entries.append((kind, name, refid))
90
+
91
+ entries.sort(key=lambda item: (item[0], item[1]))
92
+ lines = ["# Doxygen Markdown Index", "", "Generated from Doxygen XML output.", ""]
93
+ for kind, name, refid in entries:
94
+ lines.append(f"- `{kind}` `{name}` (`{refid}`)")
95
+
96
+ (markdown_dir / "index.md").write_text("\n".join(lines) + "\n")
97
+
98
+
99
+ def run(args):
100
+ project_root = require_project_root()
101
+ os.chdir(project_root)
102
+
103
+ require_commands("doxygen")
104
+
105
+ src_dir = project_root / "src"
106
+ doxygen_dir = project_root / "doxygen"
107
+ html_dir = doxygen_dir / "html"
108
+ markdown_dir = doxygen_dir / "markdown"
109
+ pdf_dir = doxygen_dir / "pdf"
110
+ latex_dir = doxygen_dir / "latex"
111
+ xml_dir = doxygen_dir / "xml"
112
+
113
+ if not src_dir.is_dir():
114
+ print_error(f"Source directory not found: {src_dir}")
115
+ return 1
116
+
117
+ has_md = _supports_generate_markdown()
118
+
119
+ for d in (html_dir, markdown_dir, pdf_dir, latex_dir, xml_dir):
120
+ if d.exists():
121
+ shutil.rmtree(d)
122
+ doxygen_dir.mkdir(parents=True, exist_ok=True)
123
+ pdf_dir.mkdir(parents=True, exist_ok=True)
124
+
125
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".conf", delete=False) as f:
126
+ doxyfile = f.name
127
+ try:
128
+ _write_doxyfile(doxyfile, project_root, src_dir, doxygen_dir, has_md)
129
+ result = subprocess.run(["doxygen", doxyfile])
130
+ if result.returncode != 0:
131
+ print_error("Doxygen generation failed.")
132
+ return 1
133
+ finally:
134
+ os.unlink(doxyfile)
135
+
136
+ if not has_md:
137
+ _generate_markdown_fallback(xml_dir, markdown_dir)
138
+
139
+ makefile = latex_dir / "Makefile"
140
+ if makefile.exists():
141
+ from shell_scripts.utils import command_exists
142
+
143
+ if command_exists("make") and command_exists("pdflatex"):
144
+ require_commands("make", "pdflatex")
145
+ subprocess.run(["make", "-C", str(latex_dir)], stdout=subprocess.DEVNULL)
146
+ refman = latex_dir / "refman.pdf"
147
+ if refman.exists():
148
+ shutil.copy2(str(refman), str(pdf_dir / "refman.pdf"))
149
+ else:
150
+ print_error(f"PDF artifact not generated: {refman}")
151
+ else:
152
+ print_error("'make' or 'pdflatex' not found; skipping PDF build.")
153
+
154
+ print(f"Generated: {html_dir}")
155
+ print(f"Generated: {markdown_dir}")
156
+ if (pdf_dir / "refman.pdf").exists():
157
+ print(f"Generated: {pdf_dir / 'refman.pdf'}")
158
+
159
+ return 0
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env python3
2
+ """@brief MIME-based edit command wrapper.
3
+
4
+ @details Exposes the `edit` CLI command and delegates category-based executable
5
+ selection to shared `_dc_common.dispatch` logic.
6
+ @satisfies PRJ-003, DES-007, REQ-023, REQ-024
7
+ """
8
+
9
+ import sys
10
+
11
+ from shell_scripts.config import get_dispatch_profile
12
+ from shell_scripts.commands._dc_common import dispatch
13
+
14
+ PROGRAM = "shellscripts"
15
+ DESCRIPTION = "File editor dispatcher by MIME type."
16
+
17
+
18
+ def print_help(version):
19
+ """@brief Render command help for `edit`.
20
+
21
+ @details Prints usage, required file argument semantics, and argument
22
+ forwarding contract for the selected external editor executable.
23
+ @param version {str} Version string appended in usage output.
24
+ @return {None} Writes help text to stdout.
25
+ @satisfies DES-008
26
+ """
27
+ print(f"Usage: {PROGRAM} edit <file> [args...] ({version})")
28
+ print()
29
+ print("edit options:")
30
+ print(" <file> - File to edit (required).")
31
+ print(" Additional arguments are passed to the selected editor.")
32
+ print(" --help - Show this help message.")
33
+
34
+
35
+ def run(args):
36
+ """@brief Execute MIME-routed edit dispatch.
37
+
38
+ @details Validates that a file argument exists; on missing argument prints
39
+ error plus help and returns status code `2`; otherwise resolves runtime
40
+ dispatch profile and delegates by file category through shared `_dc_common`.
41
+ @param args {list[str]} CLI args where `args[0]` is file path.
42
+ @return {int} Return code `2` on missing file; otherwise delegated dispatch result.
43
+ @satisfies REQ-023, REQ-024
44
+ """
45
+ if not args:
46
+ print("Error: file argument required.", file=sys.stderr)
47
+ print_help("")
48
+ return 2
49
+ category_cmds, fallback = get_dispatch_profile("edit")
50
+ return dispatch(category_cmds, fallback, args[0], args[1:])
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env python3
2
+ """@brief Google Gemini CLI launcher in project context.
3
+
4
+ @details Ensures project-root prerequisite and executable availability before
5
+ blocking subprocess invocation of `gemini`.
6
+ @satisfies REQ-016, REQ-055, REQ-056, REQ-064
7
+ """
8
+
9
+ import subprocess
10
+
11
+ from shell_scripts.utils import require_project_root, require_commands
12
+
13
+ ## @var PROGRAM
14
+ # @brief Base CLI program name used in help output.
15
+ # @details Constant identifier for usage-line rendering in command help.
16
+ PROGRAM = "shellscripts"
17
+ ## @var DESCRIPTION
18
+ # @brief One-line command description for dispatcher help surfaces.
19
+ # @details Exposed by command registry introspection (`get_all_commands`).
20
+ DESCRIPTION = "Launch Google Gemini CLI in the project context."
21
+
22
+
23
+ def print_help(version):
24
+ """@brief Print command-specific help for `gemini`.
25
+
26
+ @details Emits usage and pass-through argument behavior for deterministic
27
+ terminal rendering; does not mutate process state.
28
+ @param version {str} CLI version string propagated by dispatcher.
29
+ @return {None} Writes help text to stdout.
30
+ @satisfies DES-008
31
+ """
32
+
33
+ print(f"Usage: {PROGRAM} gemini [args...] ({version})")
34
+ print()
35
+ print("gemini options:")
36
+ print(" All arguments are passed through to the Gemini CLI.")
37
+ print(" --help - Show this help message.")
38
+
39
+
40
+ def run(args):
41
+ """@brief Launch Gemini CLI after external executable validation.
42
+
43
+ @details Resolves project root, checks executable availability for
44
+ `gemini`, then executes pass-through args through blocking subprocess run.
45
+ @param args {list[str]} Additional CLI args forwarded to Gemini.
46
+ @return {int} Child process return code.
47
+ @satisfies REQ-016, REQ-055, REQ-056, REQ-064
48
+ """
49
+
50
+ require_project_root()
51
+ cmd = ["gemini", "--yolo"] + args
52
+ cmd[0] = require_commands(cmd[0])
53
+ result = subprocess.run(cmd)
54
+ return result.returncode
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env python3
2
+ """@brief Kiro CLI launcher in project context.
3
+
4
+ @details Ensures project-root prerequisite and executable availability before
5
+ blocking subprocess invocation of `kiro-cli`.
6
+ @satisfies REQ-019, REQ-055, REQ-056, REQ-064
7
+ """
8
+
9
+ import subprocess
10
+
11
+ from shell_scripts.utils import require_project_root, require_commands
12
+
13
+ ## @var PROGRAM
14
+ # @brief Base CLI program name used in help output.
15
+ # @details Constant identifier for usage-line rendering in command help.
16
+ PROGRAM = "shellscripts"
17
+ ## @var DESCRIPTION
18
+ # @brief One-line command description for dispatcher help surfaces.
19
+ # @details Exposed by command registry introspection (`get_all_commands`).
20
+ DESCRIPTION = "Launch Kiro CLI in the project context."
21
+
22
+
23
+ def print_help(version):
24
+ """@brief Print command-specific help for `kiro`.
25
+
26
+ @details Emits usage and pass-through argument behavior for deterministic
27
+ terminal rendering; does not mutate process state.
28
+ @param version {str} CLI version string propagated by dispatcher.
29
+ @return {None} Writes help text to stdout.
30
+ @satisfies DES-008
31
+ """
32
+
33
+ print(f"Usage: {PROGRAM} kiro [args...] ({version})")
34
+ print()
35
+ print("kiro options:")
36
+ print(" All arguments are passed through to the Kiro CLI.")
37
+ print(" --help - Show this help message.")
38
+
39
+
40
+ def run(args):
41
+ """@brief Launch Kiro CLI after external executable validation.
42
+
43
+ @details Resolves project root, validates executable availability for
44
+ `kiro-cli`, then executes pass-through args through blocking subprocess run.
45
+ @param args {list[str]} Additional CLI args forwarded to Kiro.
46
+ @return {int} Child process return code.
47
+ @satisfies REQ-019, REQ-055, REQ-056, REQ-064
48
+ """
49
+
50
+ require_project_root()
51
+ cmd = ["kiro-cli"] + args
52
+ cmd[0] = require_commands(cmd[0])
53
+ result = subprocess.run(cmd)
54
+ return result.returncode
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env python3
2
+ """@brief OpenCode CLI launcher in project context.
3
+
4
+ @details Ensures project-root prerequisite and executable availability before
5
+ blocking subprocess invocation of `opencode`.
6
+ @satisfies REQ-018, REQ-055, REQ-056, REQ-064
7
+ """
8
+
9
+ import subprocess
10
+
11
+ from shell_scripts.utils import require_project_root, require_commands
12
+
13
+ ## @var PROGRAM
14
+ # @brief Base CLI program name used in help output.
15
+ # @details Constant identifier for usage-line rendering in command help.
16
+ PROGRAM = "shellscripts"
17
+ ## @var DESCRIPTION
18
+ # @brief One-line command description for dispatcher help surfaces.
19
+ # @details Exposed by command registry introspection (`get_all_commands`).
20
+ DESCRIPTION = "Launch OpenCode CLI in the project context."
21
+
22
+
23
+ def print_help(version):
24
+ """@brief Print command-specific help for `opencode`.
25
+
26
+ @details Emits usage and pass-through argument behavior for deterministic
27
+ terminal rendering; does not mutate process state.
28
+ @param version {str} CLI version string propagated by dispatcher.
29
+ @return {None} Writes help text to stdout.
30
+ @satisfies DES-008
31
+ """
32
+
33
+ print(f"Usage: {PROGRAM} opencode [args...] ({version})")
34
+ print()
35
+ print("opencode options:")
36
+ print(" All arguments are passed through to the OpenCode CLI.")
37
+ print(" --help - Show this help message.")
38
+
39
+
40
+ def run(args):
41
+ """@brief Launch OpenCode CLI after external executable validation.
42
+
43
+ @details Resolves project root, checks executable availability for
44
+ `opencode`, then executes pass-through args through blocking subprocess run.
45
+ @param args {list[str]} Additional CLI args forwarded to OpenCode.
46
+ @return {int} Child process return code.
47
+ @satisfies REQ-018, REQ-055, REQ-056, REQ-064
48
+ """
49
+
50
+ require_project_root()
51
+ cmd = ["opencode"] + args
52
+ cmd[0] = require_commands(cmd[0])
53
+ result = subprocess.run(cmd)
54
+ return result.returncode