machineconfig 1.97__py3-none-any.whl ā 2.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.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/cloud_manager.py +22 -29
- machineconfig/cluster/data_transfer.py +2 -3
- machineconfig/cluster/distribute.py +0 -2
- machineconfig/cluster/file_manager.py +4 -5
- machineconfig/cluster/job_params.py +1 -4
- machineconfig/cluster/loader_runner.py +8 -11
- machineconfig/cluster/remote_machine.py +4 -5
- machineconfig/cluster/script_execution.py +2 -2
- machineconfig/cluster/script_notify_upon_completion.py +0 -1
- machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +4 -6
- machineconfig/cluster/sessions_managers/archive/session_managers.py +0 -1
- machineconfig/cluster/sessions_managers/enhanced_command_runner.py +35 -75
- machineconfig/cluster/sessions_managers/wt_local.py +113 -185
- machineconfig/cluster/sessions_managers/wt_local_manager.py +127 -197
- machineconfig/cluster/sessions_managers/wt_remote.py +60 -67
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +110 -149
- machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +61 -64
- machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +72 -172
- machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +27 -60
- machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +58 -137
- machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +46 -74
- machineconfig/cluster/sessions_managers/zellij_local.py +91 -147
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +165 -190
- machineconfig/cluster/sessions_managers/zellij_remote.py +51 -58
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +40 -46
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +19 -17
- machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +30 -31
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +64 -134
- machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +7 -11
- machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +27 -55
- machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +14 -13
- machineconfig/cluster/templates/cli_click.py +0 -1
- machineconfig/cluster/templates/cli_gooey.py +0 -2
- machineconfig/cluster/templates/cli_trogon.py +0 -1
- machineconfig/cluster/templates/run_cloud.py +0 -1
- machineconfig/cluster/templates/run_cluster.py +0 -1
- machineconfig/cluster/templates/run_remote.py +0 -1
- machineconfig/cluster/templates/utils.py +27 -11
- machineconfig/jobs/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/linux/msc/cli_agents.sh +16 -0
- machineconfig/jobs/python/check_installations.py +9 -9
- machineconfig/jobs/python/create_bootable_media.py +0 -2
- machineconfig/jobs/python/python_cargo_build_share.py +2 -2
- machineconfig/jobs/python/python_ve_symlink.py +9 -11
- machineconfig/jobs/python/tasks.py +0 -1
- machineconfig/jobs/python/vscode/api.py +5 -5
- machineconfig/jobs/python/vscode/link_ve.py +20 -21
- machineconfig/jobs/python/vscode/select_interpreter.py +28 -29
- machineconfig/jobs/python/vscode/sync_code.py +14 -18
- machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/python_custom_installers/archive/ngrok.py +15 -15
- machineconfig/jobs/python_custom_installers/dev/aider.py +10 -18
- machineconfig/jobs/python_custom_installers/dev/alacritty.py +12 -21
- machineconfig/jobs/python_custom_installers/dev/brave.py +13 -22
- machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +13 -20
- machineconfig/jobs/python_custom_installers/dev/code.py +17 -24
- machineconfig/jobs/python_custom_installers/dev/cursor.py +10 -21
- machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +12 -11
- machineconfig/jobs/python_custom_installers/dev/espanso.py +19 -23
- machineconfig/jobs/python_custom_installers/dev/goes.py +9 -16
- machineconfig/jobs/python_custom_installers/dev/lvim.py +13 -21
- machineconfig/jobs/python_custom_installers/dev/nerdfont.py +15 -22
- machineconfig/jobs/python_custom_installers/dev/redis.py +15 -23
- machineconfig/jobs/python_custom_installers/dev/wezterm.py +15 -22
- machineconfig/jobs/python_custom_installers/dev/winget.py +32 -50
- machineconfig/jobs/python_custom_installers/docker.py +15 -24
- machineconfig/jobs/python_custom_installers/gh.py +18 -26
- machineconfig/jobs/python_custom_installers/hx.py +33 -17
- machineconfig/jobs/python_custom_installers/warp-cli.py +15 -23
- machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/python_generic_installers/config.json +412 -389
- machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/python_windows_installers/dev/config.json +1 -1
- machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +1 -1
- machineconfig/jobs/windows/msc/cli_agents.bat +0 -0
- machineconfig/jobs/windows/msc/cli_agents.ps1 +0 -0
- machineconfig/jobs/windows/start_terminal.ps1 +1 -1
- machineconfig/logger.py +50 -0
- machineconfig/profile/create.py +50 -36
- machineconfig/profile/create_hardlinks.py +33 -26
- machineconfig/profile/shell.py +87 -60
- machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/cloud/init.sh +2 -2
- machineconfig/scripts/linux/checkout_versions +1 -1
- machineconfig/scripts/linux/choose_wezterm_theme +1 -1
- machineconfig/scripts/linux/cloud_copy +1 -1
- machineconfig/scripts/linux/cloud_manager +1 -1
- machineconfig/scripts/linux/cloud_mount +1 -1
- machineconfig/scripts/linux/cloud_repo_sync +1 -1
- machineconfig/scripts/linux/cloud_sync +1 -1
- machineconfig/scripts/linux/croshell +1 -1
- machineconfig/scripts/linux/devops +3 -5
- machineconfig/scripts/linux/fire +2 -1
- machineconfig/scripts/linux/fire_agents +3 -3
- machineconfig/scripts/linux/ftpx +1 -1
- machineconfig/scripts/linux/gh_models +1 -1
- machineconfig/scripts/linux/kill_process +1 -1
- machineconfig/scripts/linux/mcinit +2 -2
- machineconfig/scripts/linux/repos +1 -1
- machineconfig/scripts/linux/scheduler +1 -1
- machineconfig/scripts/linux/start_slidev +1 -1
- machineconfig/scripts/linux/start_terminals +1 -1
- machineconfig/scripts/linux/url2md +1 -1
- machineconfig/scripts/linux/warp-cli.sh +122 -0
- machineconfig/scripts/linux/wifi_conn +1 -1
- machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/croshell.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_jobs.cpython-313.pyc +0 -0
- machineconfig/scripts/python/ai/__init__.py +0 -0
- machineconfig/scripts/python/ai/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/generate_files.cpython-313.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-313.pyc +0 -0
- machineconfig/scripts/python/ai/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
- machineconfig/scripts/python/ai/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
- machineconfig/scripts/python/ai/chatmodes/deepResearch.chatmode.md +81 -0
- machineconfig/scripts/python/ai/configs/.gemini/settings.json +81 -0
- machineconfig/scripts/python/ai/generate_files.py +84 -0
- machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +45 -0
- machineconfig/scripts/python/ai/mcinit.py +107 -0
- machineconfig/scripts/python/ai/prompts/allLintersAndTypeCheckers.prompt.md +5 -0
- machineconfig/scripts/python/ai/prompts/research-report-skeleton.prompt.md +38 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +52 -0
- machineconfig/scripts/python/archive/tmate_conn.py +5 -5
- machineconfig/scripts/python/archive/tmate_start.py +3 -3
- machineconfig/scripts/python/choose_wezterm_theme.py +2 -2
- machineconfig/scripts/python/cloud_copy.py +20 -19
- machineconfig/scripts/python/cloud_mount.py +10 -8
- machineconfig/scripts/python/cloud_repo_sync.py +15 -15
- machineconfig/scripts/python/cloud_sync.py +1 -1
- machineconfig/scripts/python/croshell.py +18 -16
- machineconfig/scripts/python/devops.py +6 -6
- machineconfig/scripts/python/devops_add_identity.py +9 -7
- machineconfig/scripts/python/devops_add_ssh_key.py +19 -19
- machineconfig/scripts/python/devops_backup_retrieve.py +14 -14
- machineconfig/scripts/python/devops_devapps_install.py +3 -3
- machineconfig/scripts/python/devops_update_repos.py +141 -53
- machineconfig/scripts/python/dotfile.py +3 -3
- machineconfig/scripts/python/fire_agents.py +202 -41
- machineconfig/scripts/python/fire_jobs.py +20 -21
- machineconfig/scripts/python/ftpx.py +4 -3
- machineconfig/scripts/python/gh_models.py +94 -94
- machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-313.pyc +0 -0
- machineconfig/scripts/python/helpers/cloud_helpers.py +3 -3
- machineconfig/scripts/python/helpers/helpers2.py +3 -3
- machineconfig/scripts/python/helpers/helpers4.py +8 -7
- machineconfig/scripts/python/helpers/helpers5.py +7 -7
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +2 -2
- machineconfig/scripts/python/mount_nfs.py +4 -3
- machineconfig/scripts/python/mount_nw_drive.py +4 -4
- machineconfig/scripts/python/mount_ssh.py +4 -3
- machineconfig/scripts/python/repos.py +9 -9
- machineconfig/scripts/python/scheduler.py +1 -1
- machineconfig/scripts/python/start_slidev.py +9 -8
- machineconfig/scripts/python/start_terminals.py +1 -1
- machineconfig/scripts/python/viewer.py +40 -40
- machineconfig/scripts/python/wifi_conn.py +65 -66
- machineconfig/scripts/python/wsl_windows_transfer.py +2 -2
- machineconfig/scripts/windows/checkout_version.ps1 +1 -3
- machineconfig/scripts/windows/choose_wezterm_theme.ps1 +1 -3
- machineconfig/scripts/windows/cloud_copy.ps1 +2 -6
- machineconfig/scripts/windows/cloud_manager.ps1 +1 -1
- machineconfig/scripts/windows/cloud_repo_sync.ps1 +1 -2
- machineconfig/scripts/windows/cloud_sync.ps1 +2 -2
- machineconfig/scripts/windows/croshell.ps1 +2 -2
- machineconfig/scripts/windows/devops.ps1 +1 -4
- machineconfig/scripts/windows/dotfile.ps1 +1 -3
- machineconfig/scripts/windows/fire.ps1 +1 -1
- machineconfig/scripts/windows/ftpx.ps1 +2 -2
- machineconfig/scripts/windows/gpt.ps1 +1 -1
- machineconfig/scripts/windows/kill_process.ps1 +1 -2
- machineconfig/scripts/windows/mcinit.ps1 +2 -2
- machineconfig/scripts/windows/mount_nfs.ps1 +1 -1
- machineconfig/scripts/windows/mount_ssh.ps1 +1 -1
- machineconfig/scripts/windows/pomodoro.ps1 +1 -1
- machineconfig/scripts/windows/py2exe.ps1 +1 -3
- machineconfig/scripts/windows/repos.ps1 +1 -1
- machineconfig/scripts/windows/scheduler.ps1 +1 -1
- machineconfig/scripts/windows/snapshot.ps1 +2 -2
- machineconfig/scripts/windows/start_slidev.ps1 +1 -1
- machineconfig/scripts/windows/start_terminals.ps1 +1 -1
- machineconfig/scripts/windows/wifi_conn.ps1 +1 -1
- machineconfig/scripts/windows/wsl_windows_transfer.ps1 +1 -3
- machineconfig/settings/lf/linux/lfrc +1 -1
- machineconfig/settings/linters/.ruff.toml +2 -2
- machineconfig/settings/linters/.ruff_cache/.gitignore +2 -0
- machineconfig/settings/linters/.ruff_cache/CACHEDIR.TAG +1 -0
- machineconfig/settings/lvim/windows/archive/config_additional.lua +1 -1
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +71 -71
- machineconfig/settings/shells/wt/settings.json +8 -8
- machineconfig/settings/svim/linux/init.toml +1 -1
- machineconfig/settings/svim/windows/init.toml +1 -1
- machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -54
- machineconfig/setup_linux/web_shortcuts/interactive.sh +6 -6
- machineconfig/setup_linux/web_shortcuts/tmp.sh +2 -0
- machineconfig/setup_windows/web_shortcuts/all.ps1 +2 -2
- machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +1 -1
- machineconfig/setup_windows/web_shortcuts/croshell.ps1 +1 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +5 -5
- machineconfig/setup_windows/wt_and_pwsh/install_fonts.ps1 +51 -15
- machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +75 -18
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +52 -42
- machineconfig/utils/ai/browser_user_wrapper.py +5 -5
- machineconfig/utils/ai/generate_file_checklist.py +19 -22
- machineconfig/utils/ai/url2md.py +5 -3
- machineconfig/utils/cloud/onedrive/setup_oauth.py +5 -4
- machineconfig/utils/cloud/onedrive/transaction.py +192 -227
- machineconfig/utils/code.py +71 -43
- machineconfig/utils/installer.py +77 -85
- machineconfig/utils/installer_utils/installer_abc.py +29 -17
- machineconfig/utils/installer_utils/installer_class.py +188 -83
- machineconfig/utils/io_save.py +3 -15
- machineconfig/utils/links.py +22 -11
- machineconfig/utils/notifications.py +197 -0
- machineconfig/utils/options.py +38 -25
- machineconfig/utils/path.py +18 -6
- machineconfig/utils/path_reduced.py +637 -316
- machineconfig/utils/procs.py +69 -63
- machineconfig/utils/scheduling.py +11 -13
- machineconfig/utils/ssh.py +351 -0
- machineconfig/utils/terminal.py +225 -0
- machineconfig/utils/utils.py +13 -12
- machineconfig/utils/utils2.py +43 -10
- machineconfig/utils/utils5.py +242 -46
- machineconfig/utils/ve.py +11 -6
- {machineconfig-1.97.dist-info ā machineconfig-2.1.dist-info}/METADATA +15 -9
- {machineconfig-1.97.dist-info ā machineconfig-2.1.dist-info}/RECORD +232 -235
- machineconfig/cluster/self_ssh.py +0 -57
- machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python/archive/python_tools.txt +0 -12
- machineconfig/jobs/python/vscode/__pycache__/select_interpreter.cpython-311.pyc +0 -0
- machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python_generic_installers/update.py +0 -3
- machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
- machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/linux/activate_ve +0 -87
- machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_backup_retrieve.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/init.py +0 -56
- machineconfig/scripts/python/ai/rules/python/dev.md +0 -31
- machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-311.pyc +0 -0
- machineconfig/scripts/windows/activate_ve.ps1 +0 -54
- {machineconfig-1.97.dist-info ā machineconfig-2.1.dist-info}/WHEEL +0 -0
- {machineconfig-1.97.dist-info ā machineconfig-2.1.dist-info}/top_level.txt +0 -0
machineconfig/utils/code.py
CHANGED
|
@@ -1,85 +1,113 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
1
|
import platform
|
|
2
|
+
from typing import Optional
|
|
3
|
+
import subprocess
|
|
3
4
|
from rich.console import Console
|
|
4
5
|
from rich.panel import Panel
|
|
5
6
|
from rich.syntax import Syntax
|
|
6
7
|
from machineconfig.utils.utils2 import randstr
|
|
7
|
-
from machineconfig.utils.
|
|
8
|
-
from
|
|
8
|
+
from machineconfig.utils.ve import get_ve_activate_line
|
|
9
|
+
from machineconfig.utils.path_reduced import PathExtended as PathExtended
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
PROGRAM_PATH =
|
|
12
|
+
PROGRAM_PATH = PathExtended.home().joinpath("tmp_results", "shells", "python_return_command") + (".ps1" if platform.system() == "Windows" else ".sh")
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
def get_shell_script_executing_python_file(python_file: str, func: Optional[str]
|
|
15
|
-
if func is None:
|
|
16
|
-
|
|
15
|
+
def get_shell_script_executing_python_file(python_file: str, func: Optional[str], ve_path: str, strict_execution: bool = True):
|
|
16
|
+
if func is None:
|
|
17
|
+
exec_line = f"""python {python_file}"""
|
|
18
|
+
else:
|
|
19
|
+
exec_line = f"""python -m fire {python_file} {func}"""
|
|
17
20
|
shell_script = f"""
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
echo "Executing `{exec_line}`"
|
|
22
|
+
{get_ve_activate_line(ve_path)}
|
|
20
23
|
{exec_line}
|
|
21
24
|
deactivate || true
|
|
22
25
|
"""
|
|
23
26
|
|
|
24
27
|
if strict_execution:
|
|
25
|
-
if platform.system() == "Windows":
|
|
26
|
-
|
|
28
|
+
if platform.system() == "Windows":
|
|
29
|
+
shell_script = """$ErrorActionPreference = "Stop" """ + "\n" + shell_script
|
|
30
|
+
if platform.system() in ["Linux", "Darwin"]:
|
|
31
|
+
shell_script = "set -e" + "\n" + shell_script
|
|
27
32
|
|
|
28
|
-
if platform.system() in ["Linux", "Darwin"]:
|
|
33
|
+
if platform.system() in ["Linux", "Darwin"]:
|
|
34
|
+
shell_script = "#!/bin/bash" + "\n" + shell_script # vs #!/usr/bin/env bash
|
|
29
35
|
return shell_script
|
|
30
36
|
|
|
31
37
|
|
|
38
|
+
def get_shell_file_executing_python_script(python_script: str, ve_path: str, verbose: bool = True):
|
|
39
|
+
if verbose:
|
|
40
|
+
python_script = (
|
|
41
|
+
f"""
|
|
42
|
+
code = r'''{python_script}''' """
|
|
43
|
+
+ """
|
|
44
|
+
try:
|
|
45
|
+
from machineconfig.utils.utils import print_code
|
|
46
|
+
print_code(code=code, lexer="python", desc="Python Script")
|
|
47
|
+
except ImportError:
|
|
48
|
+
from rich.console import Console
|
|
49
|
+
from rich.panel import Panel
|
|
50
|
+
console = Console()
|
|
51
|
+
console.print(Panel(f'''š PYTHON SCRIPT:\n\n{{code}}''', title="Python Script", expand=False))
|
|
52
|
+
"""
|
|
53
|
+
+ python_script
|
|
54
|
+
)
|
|
55
|
+
python_file = PathExtended.tmp().joinpath("tmp_scripts", "python", randstr() + ".py")
|
|
56
|
+
python_file.parent.mkdir(parents=True, exist_ok=True)
|
|
57
|
+
python_file.write_text(python_script, encoding="utf-8")
|
|
58
|
+
shell_script = get_shell_script_executing_python_file(python_file=str(python_file), func=None, ve_path=ve_path)
|
|
59
|
+
shell_file = write_shell_script_to_file(shell_script)
|
|
60
|
+
return shell_file
|
|
61
|
+
|
|
62
|
+
|
|
32
63
|
def write_shell_script_to_file(shell_script: str):
|
|
33
|
-
if platform.system() in ["Linux", "Darwin"]:
|
|
34
|
-
|
|
35
|
-
|
|
64
|
+
if platform.system() in ["Linux", "Darwin"]:
|
|
65
|
+
suffix = ".sh"
|
|
66
|
+
elif platform.system() == "Windows":
|
|
67
|
+
suffix = ".ps1"
|
|
68
|
+
else:
|
|
69
|
+
raise NotImplementedError(f"Platform {platform.system()} not implemented.")
|
|
36
70
|
shell_file = PathExtended.tmp().joinpath("tmp_scripts", "shell", randstr() + suffix)
|
|
37
71
|
shell_file.parent.mkdir(parents=True, exist_ok=True)
|
|
38
|
-
shell_file.write_text(shell_script)
|
|
72
|
+
shell_file.write_text(shell_script, encoding="utf-8")
|
|
39
73
|
return shell_file
|
|
40
74
|
|
|
75
|
+
|
|
41
76
|
# Enhanced print/log/error/exception statements for better clarity and consistency
|
|
42
77
|
# Improved formatting and language of messages
|
|
43
78
|
# Ensured consistent use of f-strings with triple quotes where applicable
|
|
44
79
|
|
|
80
|
+
|
|
45
81
|
def write_shell_script_to_default_program_path(program: str, desc: str, preserve_cwd: bool, display: bool, execute: bool):
|
|
46
82
|
if preserve_cwd:
|
|
47
83
|
if platform.system() == "Windows":
|
|
48
84
|
program = "$orig_path = $pwd\n" + program + "\ncd $orig_path"
|
|
49
85
|
else:
|
|
50
86
|
program = 'orig_path=$(cd -- "." && pwd)\n' + program + '\ncd "$orig_path" || exit'
|
|
51
|
-
if display:
|
|
87
|
+
if display:
|
|
88
|
+
print_code(code=program, lexer="shell", desc=desc, subtitle=str(PROGRAM_PATH))
|
|
52
89
|
PROGRAM_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
53
|
-
PROGRAM_PATH.write_text(program)
|
|
90
|
+
PROGRAM_PATH.write_text(program, encoding="utf-8")
|
|
54
91
|
if execute:
|
|
55
|
-
|
|
92
|
+
result = subprocess.run(f". {PROGRAM_PATH}", shell=True, capture_output=True, text=True)
|
|
93
|
+
success = result.returncode == 0 and result.stderr == ""
|
|
94
|
+
if not success:
|
|
95
|
+
print("ā š ļø EXECUTION | Shell script running failed")
|
|
96
|
+
if result.stdout:
|
|
97
|
+
print(f"STDOUT: {result.stdout}")
|
|
98
|
+
if result.stderr:
|
|
99
|
+
print(f"STDERR: {result.stderr}")
|
|
100
|
+
print(f"Return code: {result.returncode}")
|
|
56
101
|
return None
|
|
57
102
|
|
|
58
|
-
def get_shell_file_executing_python_script(python_script: str, ve_name: str, verbose: bool=True):
|
|
59
|
-
if verbose:
|
|
60
|
-
python_script = f"""
|
|
61
|
-
code = r'''{python_script}''' """ + """
|
|
62
|
-
try:
|
|
63
|
-
from machineconfig.utils.utils import print_code
|
|
64
|
-
print_code(code=code, lexer="python", desc="Python Script")
|
|
65
|
-
except ImportError:
|
|
66
|
-
from rich.console import Console
|
|
67
|
-
from rich.panel import Panel
|
|
68
|
-
console = Console()
|
|
69
|
-
console.print(Panel(f'''š PYTHON SCRIPT:\n\n{{code}}''', title="Python Script", expand=False))
|
|
70
|
-
""" + python_script
|
|
71
|
-
python_file = PathExtended.tmp().joinpath("tmp_scripts", "python", randstr() + ".py")
|
|
72
|
-
python_file.parent.mkdir(parents=True, exist_ok=True)
|
|
73
|
-
python_file.write_text(python_script)
|
|
74
|
-
shell_script = get_shell_script_executing_python_file(python_file=str(python_file), ve_name=ve_name)
|
|
75
|
-
shell_file = write_shell_script_to_file(shell_script)
|
|
76
|
-
return shell_file
|
|
77
103
|
|
|
78
|
-
def print_code(code: str, lexer: str, desc: str, subtitle: str=""):
|
|
104
|
+
def print_code(code: str, lexer: str, desc: str, subtitle: str = ""):
|
|
79
105
|
if lexer == "shell":
|
|
80
|
-
if platform.system() == "Windows":
|
|
81
|
-
|
|
82
|
-
|
|
106
|
+
if platform.system() == "Windows":
|
|
107
|
+
lexer = "powershell"
|
|
108
|
+
elif platform.system() in ["Linux", "Darwin"]:
|
|
109
|
+
lexer = "sh"
|
|
110
|
+
else:
|
|
111
|
+
raise NotImplementedError(f"Platform {platform.system()} not supported for lexer {lexer}")
|
|
83
112
|
console = Console()
|
|
84
113
|
console.print(Panel(Syntax(code=code, lexer=lexer), title=f"š {desc}", subtitle=subtitle), style="bold red")
|
|
85
|
-
|
machineconfig/utils/installer.py
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
"""package manager
|
|
2
|
-
|
|
1
|
+
"""package manager"""
|
|
2
|
+
|
|
3
3
|
from machineconfig.utils.installer_utils.installer_abc import LINUX_INSTALL_PATH, CATEGORY
|
|
4
4
|
from machineconfig.utils.installer_utils.installer_class import Installer
|
|
5
5
|
from rich.console import Console
|
|
6
|
-
from rich.panel import Panel
|
|
6
|
+
from rich.panel import Panel # Added import
|
|
7
7
|
|
|
8
|
-
from machineconfig.utils.path_reduced import
|
|
9
|
-
from crocodile.meta import Terminal
|
|
8
|
+
from machineconfig.utils.path_reduced import PathExtended as PathExtended
|
|
10
9
|
from machineconfig.utils.utils import INSTALL_VERSION_ROOT
|
|
11
10
|
from machineconfig.utils.utils2 import read_json
|
|
12
11
|
|
|
@@ -17,20 +16,20 @@ from joblib import Parallel, delayed
|
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
def check_latest():
|
|
20
|
-
console = Console()
|
|
21
|
-
console.print(Panel("š CHECKING FOR LATEST VERSIONS", title="Status", expand=False))
|
|
19
|
+
console = Console() # Added console initialization
|
|
20
|
+
console.print(Panel("š CHECKING FOR LATEST VERSIONS", title="Status", expand=False)) # Replaced print with Panel
|
|
22
21
|
installers = get_installers(system=platform.system(), dev=False)
|
|
23
22
|
# installers += get_installers(system=platform.system(), dev=True)
|
|
24
23
|
installers_github = []
|
|
25
24
|
for inst__ in installers:
|
|
26
|
-
if "ntop" in inst__.name:
|
|
25
|
+
if "ntop" in inst__.name:
|
|
27
26
|
print(f"āļø Skipping {inst__.name} (ntop)")
|
|
28
27
|
continue
|
|
29
28
|
if "github" not in inst__.repo_url:
|
|
30
29
|
print(f"āļø Skipping {inst__.name} (not a GitHub release)")
|
|
31
30
|
continue
|
|
32
31
|
installers_github.append(inst__)
|
|
33
|
-
|
|
32
|
+
|
|
34
33
|
print(f"\nš Checking {len(installers_github)} GitHub-based installers...\n")
|
|
35
34
|
|
|
36
35
|
def func(inst: Installer):
|
|
@@ -41,29 +40,24 @@ def check_latest():
|
|
|
41
40
|
|
|
42
41
|
print("\nā³ Processing installers...\n")
|
|
43
42
|
res = [func(inst) for inst in installers_github]
|
|
44
|
-
|
|
43
|
+
|
|
45
44
|
print("\nš Generating results table...\n")
|
|
46
|
-
|
|
45
|
+
|
|
47
46
|
# Convert to list of dictionaries and group by status
|
|
48
47
|
result_data = []
|
|
49
48
|
for tool, status, current_ver, new_ver in res:
|
|
50
|
-
result_data.append({
|
|
51
|
-
|
|
52
|
-
"Status": status,
|
|
53
|
-
"Current Version": current_ver,
|
|
54
|
-
"New Version": new_ver
|
|
55
|
-
})
|
|
56
|
-
|
|
49
|
+
result_data.append({"Tool": tool, "Status": status, "Current Version": current_ver, "New Version": new_ver})
|
|
50
|
+
|
|
57
51
|
# Group by status
|
|
58
|
-
grouped_data = {}
|
|
52
|
+
grouped_data: dict[str, list[dict[str, Any]]] = {}
|
|
59
53
|
for item in result_data:
|
|
60
54
|
status = item["Status"]
|
|
61
55
|
if status not in grouped_data:
|
|
62
56
|
grouped_data[status] = []
|
|
63
57
|
grouped_data[status].append(item)
|
|
64
|
-
|
|
58
|
+
|
|
65
59
|
console.print(Panel("š INSTALLATION STATUS SUMMARY", title="Status", expand=False))
|
|
66
|
-
|
|
60
|
+
|
|
67
61
|
# Print each group
|
|
68
62
|
for status, items in grouped_data.items():
|
|
69
63
|
print(f"\n{status.upper()}:")
|
|
@@ -71,31 +65,31 @@ def check_latest():
|
|
|
71
65
|
for item in items:
|
|
72
66
|
print(f" {item['Tool']:<20} | Current: {item['Current Version']:<15} | New: {item['New Version']}")
|
|
73
67
|
print("-" * 60)
|
|
74
|
-
print(f"{'ā'*80}")
|
|
68
|
+
print(f"{'ā' * 80}")
|
|
75
69
|
|
|
76
70
|
|
|
77
71
|
def get_installed_cli_apps():
|
|
78
|
-
print(f"\n{'='*80}\nš LISTING INSTALLED CLI APPS š\n{'='*80}")
|
|
79
|
-
if platform.system() == "Windows":
|
|
72
|
+
print(f"\n{'=' * 80}\nš LISTING INSTALLED CLI APPS š\n{'=' * 80}")
|
|
73
|
+
if platform.system() == "Windows":
|
|
80
74
|
print("šŖ Searching for Windows executables...")
|
|
81
75
|
apps = PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps").search("*.exe", not_in=["notepad"])
|
|
82
|
-
elif platform.system() in ["Linux", "Darwin"]:
|
|
76
|
+
elif platform.system() in ["Linux", "Darwin"]:
|
|
83
77
|
print(f"š§ Searching for {platform.system()} executables...")
|
|
84
78
|
if platform.system() == "Linux":
|
|
85
79
|
apps = PathExtended(LINUX_INSTALL_PATH).search("*") + PathExtended("/usr/local/bin").search("*")
|
|
86
80
|
else: # Darwin/macOS
|
|
87
81
|
apps = PathExtended("/usr/local/bin").search("*") + PathExtended("/opt/homebrew/bin").search("*")
|
|
88
|
-
else:
|
|
82
|
+
else:
|
|
89
83
|
error_msg = f"ā ERROR: System {platform.system()} not supported"
|
|
90
84
|
print(error_msg)
|
|
91
85
|
raise NotImplementedError(error_msg)
|
|
92
86
|
apps = [app for app in apps if app.size("kb") > 0.1 and not app.is_symlink()] # no symlinks like paint and wsl and bash
|
|
93
|
-
print(f"ā
Found {len(apps)} installed applications\n{'='*80}")
|
|
87
|
+
print(f"ā
Found {len(apps)} installed applications\n{'=' * 80}")
|
|
94
88
|
return apps
|
|
95
89
|
|
|
96
90
|
|
|
97
91
|
def get_installers(system: str, dev: bool) -> list[Installer]:
|
|
98
|
-
print(f"\n{'='*80}\nš LOADING INSTALLER CONFIGURATIONS š\n{'='*80}")
|
|
92
|
+
print(f"\n{'=' * 80}\nš LOADING INSTALLER CONFIGURATIONS š\n{'=' * 80}")
|
|
99
93
|
res_all = get_all_dicts(system=system)
|
|
100
94
|
if not dev:
|
|
101
95
|
print("ā¹ļø Excluding development installers...")
|
|
@@ -105,21 +99,22 @@ def get_installers(system: str, dev: bool) -> list[Installer]:
|
|
|
105
99
|
res_final = {}
|
|
106
100
|
for _k, v in res_all.items():
|
|
107
101
|
res_final.update(v)
|
|
108
|
-
print(f"ā
Loaded {len(res_final)} installer configurations\n{'='*80}")
|
|
102
|
+
print(f"ā
Loaded {len(res_final)} installer configurations\n{'=' * 80}")
|
|
109
103
|
return [Installer.from_dict(d=vd, name=k) for k, vd in res_final.items()]
|
|
110
104
|
|
|
111
105
|
|
|
112
106
|
def get_all_dicts(system: str) -> dict[CATEGORY, dict[str, dict[str, Any]]]:
|
|
113
|
-
print(f"\n{'='*80}\nš LOADING CONFIGURATION FILES š\n{'='*80}")
|
|
114
|
-
|
|
107
|
+
print(f"\n{'=' * 80}\nš LOADING CONFIGURATION FILES š\n{'=' * 80}")
|
|
108
|
+
|
|
115
109
|
print(f"š Importing OS-specific installers for {system}...")
|
|
116
|
-
if system == "Windows":
|
|
110
|
+
if system == "Windows":
|
|
117
111
|
import machineconfig.jobs.python_windows_installers as os_specific_installer
|
|
118
|
-
else:
|
|
112
|
+
else:
|
|
119
113
|
import machineconfig.jobs.python_linux_installers as os_specific_installer
|
|
120
114
|
|
|
121
115
|
print("š Importing generic installers...")
|
|
122
116
|
import machineconfig.jobs.python_generic_installers as generic_installer
|
|
117
|
+
|
|
123
118
|
path_os_specific = PathExtended(os_specific_installer.__file__).parent
|
|
124
119
|
path_os_generic = PathExtended(generic_installer.__file__).parent
|
|
125
120
|
|
|
@@ -128,15 +123,15 @@ def get_all_dicts(system: str) -> dict[CATEGORY, dict[str, dict[str, Any]]]:
|
|
|
128
123
|
|
|
129
124
|
print("š Loading configuration files...")
|
|
130
125
|
res_final: dict[CATEGORY, dict[str, dict[str, Any]]] = {}
|
|
131
|
-
print(f"""š Loading OS-specific config from: {path_os_specific.joinpath(
|
|
126
|
+
print(f"""š Loading OS-specific config from: {path_os_specific.joinpath("config.json")}""")
|
|
132
127
|
res_final["OS_SPECIFIC"] = read_json(path=path_os_specific.joinpath("config.json"))
|
|
133
128
|
|
|
134
129
|
print(f"""š Loading OS-generic config from: {path_os_generic.joinpath("config.json")}""")
|
|
135
130
|
res_final["OS_GENERIC"] = read_json(path=path_os_generic.joinpath("config.json"))
|
|
136
|
-
|
|
131
|
+
|
|
137
132
|
print(f"""š Loading OS-specific dev config from: {path_os_specific_dev.joinpath("config.json")}""")
|
|
138
133
|
res_final["OS_SPECIFIC_DEV"] = read_json(path=path_os_specific_dev.joinpath("config.json"))
|
|
139
|
-
|
|
134
|
+
|
|
140
135
|
print(f"""š Loading OS-generic dev config from: {path_os_generic_dev.joinpath("config.json")}""")
|
|
141
136
|
res_final["OS_GENERIC_DEV"] = read_json(path=path_os_generic_dev.joinpath("config.json"))
|
|
142
137
|
|
|
@@ -145,11 +140,12 @@ def get_all_dicts(system: str) -> dict[CATEGORY, dict[str, dict[str, Any]]]:
|
|
|
145
140
|
|
|
146
141
|
print(f"š Loading custom installers from: {path_custom_installer}")
|
|
147
142
|
import runpy
|
|
143
|
+
|
|
148
144
|
res_custom: dict[str, dict[str, Any]] = {}
|
|
149
145
|
for item in path_custom_installer.search("*.py", r=False, not_in=["__init__"]):
|
|
150
146
|
try:
|
|
151
147
|
print(f"š Loading custom installer: {item.name}")
|
|
152
|
-
config_dict = runpy.run_path(str(item), run_name=None)[
|
|
148
|
+
config_dict = runpy.run_path(str(item), run_name=None)["config_dict"]
|
|
153
149
|
res_custom[item.stem] = config_dict
|
|
154
150
|
except Exception as ex:
|
|
155
151
|
print(f"ā Failed to load {item}: {ex}")
|
|
@@ -159,84 +155,80 @@ def get_all_dicts(system: str) -> dict[CATEGORY, dict[str, dict[str, Any]]]:
|
|
|
159
155
|
for item in path_custom_installer_dev.search("*.py", r=False, not_in=["__init__"]):
|
|
160
156
|
try:
|
|
161
157
|
print(f"š Loading custom dev installer: {item.name}")
|
|
162
|
-
config_dict = runpy.run_path(str(item), run_name=None)[
|
|
158
|
+
config_dict = runpy.run_path(str(item), run_name=None)["config_dict"]
|
|
163
159
|
res_custom_dev[item.stem] = config_dict
|
|
164
160
|
except Exception as ex:
|
|
165
161
|
print(f"ā Failed to load {item}: {ex}")
|
|
166
162
|
|
|
167
163
|
res_final["CUSTOM"] = res_custom
|
|
168
164
|
res_final["CUSTOM_DEV"] = res_custom_dev
|
|
169
|
-
|
|
170
|
-
print(f"ā
Configuration loading complete:\n - OS_SPECIFIC: {len(res_final['OS_SPECIFIC'])} items\n - OS_GENERIC: {len(res_final['OS_GENERIC'])} items\n - CUSTOM: {len(res_final['CUSTOM'])} items\n{'='*80}")
|
|
165
|
+
|
|
166
|
+
print(f"ā
Configuration loading complete:\n - OS_SPECIFIC: {len(res_final['OS_SPECIFIC'])} items\n - OS_GENERIC: {len(res_final['OS_GENERIC'])} items\n - CUSTOM: {len(res_final['CUSTOM'])} items\n{'=' * 80}")
|
|
171
167
|
return res_final
|
|
172
168
|
|
|
173
169
|
|
|
174
|
-
def install_all(installers: list[Installer], safe: bool=False, jobs: int = 10, fresh: bool=False):
|
|
175
|
-
print(f"\n{'='*80}\nš BULK INSTALLATION PROCESS š\n{'='*80}")
|
|
176
|
-
if fresh:
|
|
170
|
+
def install_all(installers: list[Installer], safe: bool = False, jobs: int = 10, fresh: bool = False):
|
|
171
|
+
print(f"\n{'=' * 80}\nš BULK INSTALLATION PROCESS š\n{'=' * 80}")
|
|
172
|
+
if fresh:
|
|
177
173
|
print("š§¹ Fresh install requested - clearing version cache...")
|
|
178
174
|
INSTALL_VERSION_ROOT.delete(sure=True)
|
|
179
175
|
print("ā
Version cache cleared")
|
|
180
|
-
|
|
176
|
+
|
|
181
177
|
if safe:
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
178
|
+
pass
|
|
179
|
+
# print("ā ļø Safe installation mode activated...")
|
|
180
|
+
# from machineconfig.jobs.python.check_installations import APP_SUMMARY_PATH
|
|
181
|
+
# if platform.system().lower() == "windows":
|
|
182
|
+
# print("šŖ Moving applications to Windows Apps folder...")
|
|
183
|
+
# # PathExtended.get_env().WindowsPaths().WindowsApps)
|
|
184
|
+
# folder = PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps")
|
|
185
|
+
# apps_dir.search("*").apply(lambda app: app.move(folder=folder))
|
|
186
|
+
# elif platform.system().lower() in ["linux", "darwin"]:
|
|
187
|
+
# system_name = "Linux" if platform.system().lower() == "linux" else "macOS"
|
|
188
|
+
# print(f"š§ Moving applications to {system_name} bin folder...")
|
|
189
|
+
# if platform.system().lower() == "linux":
|
|
190
|
+
# install_path = LINUX_INSTALL_PATH
|
|
191
|
+
# else: # Darwin/macOS
|
|
192
|
+
# install_path = "/usr/local/bin"
|
|
193
|
+
# Terminal().run(f"sudo mv {apps_dir.as_posix()}/* {install_path}/").capture().print_if_unsuccessful(desc=f"MOVING executable to {install_path}", strict_err=True, strict_returncode=True)
|
|
194
|
+
# else:
|
|
195
|
+
# error_msg = f"ā ERROR: System {platform.system()} not supported"
|
|
196
|
+
# print(error_msg)
|
|
197
|
+
# raise NotImplementedError(error_msg)
|
|
198
|
+
|
|
199
|
+
# apps_dir.delete(sure=True)
|
|
200
|
+
# print(f"ā
Safe installation completed\n{'='*80}")
|
|
201
|
+
# return None
|
|
202
|
+
|
|
208
203
|
print(f"š Starting installation of {len(installers)} packages...")
|
|
209
|
-
print(f"\n{'='*80}\nš¦ INSTALLING FIRST PACKAGE š¦\n{'='*80}")
|
|
204
|
+
print(f"\n{'=' * 80}\nš¦ INSTALLING FIRST PACKAGE š¦\n{'=' * 80}")
|
|
210
205
|
installers[0].install(version=None)
|
|
211
206
|
installers_remaining = installers[1:]
|
|
212
|
-
print(f"\n{'='*80}\nš¦ INSTALLING REMAINING PACKAGES š¦\n{'='*80}")
|
|
213
|
-
|
|
207
|
+
print(f"\n{'=' * 80}\nš¦ INSTALLING REMAINING PACKAGES š¦\n{'=' * 80}")
|
|
208
|
+
|
|
214
209
|
# Use joblib for parallel processing of remaining installers
|
|
215
|
-
res = Parallel(n_jobs=jobs)(
|
|
216
|
-
|
|
217
|
-
for installer in installers_remaining
|
|
218
|
-
)
|
|
219
|
-
|
|
210
|
+
res = Parallel(n_jobs=jobs)(delayed(lambda x: x.install_robust(version=None))(installer) for installer in installers_remaining)
|
|
211
|
+
|
|
220
212
|
console = Console()
|
|
221
|
-
|
|
213
|
+
|
|
222
214
|
print("\n")
|
|
223
215
|
console.rule("š INSTALLATION RESULTS SUMMARY š")
|
|
224
|
-
|
|
216
|
+
|
|
225
217
|
print("\n")
|
|
226
218
|
console.rule("ā Same Version Apps")
|
|
227
|
-
same_version_results = [r for r in res if r and
|
|
219
|
+
same_version_results = [r for r in res if r and "same version" in str(r)]
|
|
228
220
|
for result in same_version_results:
|
|
229
221
|
print(f" {result}")
|
|
230
|
-
|
|
222
|
+
|
|
231
223
|
print("\n")
|
|
232
224
|
console.rule("ā¬ļø Updated Apps")
|
|
233
|
-
updated_results = [r for r in res if r and
|
|
225
|
+
updated_results = [r for r in res if r and "updated from" in str(r)]
|
|
234
226
|
for result in updated_results:
|
|
235
227
|
print(f" {result}")
|
|
236
|
-
|
|
228
|
+
|
|
237
229
|
print("\n")
|
|
238
230
|
console.rule("ā Failed Apps")
|
|
239
|
-
failed_results = [r for r in res if r and
|
|
231
|
+
failed_results = [r for r in res if r and "Failed at" in str(r)]
|
|
240
232
|
for result in failed_results:
|
|
241
233
|
print(f" {result}")
|
|
242
234
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from machineconfig.utils.path_reduced import
|
|
2
|
-
from crocodile.meta import Terminal
|
|
1
|
+
from machineconfig.utils.path_reduced import PathExtended as PathExtended
|
|
3
2
|
from typing import Optional, TypeAlias, Literal
|
|
3
|
+
import subprocess
|
|
4
4
|
|
|
5
5
|
# LINUX_INSTALL_PATH = '/usr/local/bin'
|
|
6
6
|
# LINUX_INSTALL_PATH = '~/.local/bin'
|
|
@@ -9,21 +9,22 @@ WINDOWS_INSTALL_PATH = PathExtended.home().joinpath("AppData/Local/Microsoft/Win
|
|
|
9
9
|
CATEGORY: TypeAlias = Literal["OS_SPECIFIC", "OS_GENERIC", "CUSTOM", "OS_SPECIFIC_DEV", "OS_GENERIC_DEV", "CUSTOM_DEV"]
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optional[str] = None, delete: bool=True, rename_to: Optional[str] = None):
|
|
13
|
-
print(f"\n{'='*80}\nš PROCESSING WINDOWS EXECUTABLE š\n{'='*80}")
|
|
14
|
-
if exe_name is not None and ".exe" in exe_name:
|
|
12
|
+
def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optional[str] = None, delete: bool = True, rename_to: Optional[str] = None):
|
|
13
|
+
print(f"\n{'=' * 80}\nš PROCESSING WINDOWS EXECUTABLE š\n{'=' * 80}")
|
|
14
|
+
if exe_name is not None and ".exe" in exe_name:
|
|
15
|
+
exe_name = exe_name.replace(".exe", "")
|
|
15
16
|
if downloaded_file_path.is_file():
|
|
16
17
|
exe = downloaded_file_path
|
|
17
18
|
print(f"š Found direct executable file: {exe}")
|
|
18
19
|
else:
|
|
19
20
|
print(f"š Searching for executable in: {downloaded_file_path}")
|
|
20
21
|
if exe_name is None:
|
|
21
|
-
exe = downloaded_file_path.search("*.exe", r=True)
|
|
22
|
+
exe = downloaded_file_path.search("*.exe", r=True)[0]
|
|
22
23
|
print(f"ā
Found executable: {exe}")
|
|
23
24
|
else:
|
|
24
25
|
tmp = downloaded_file_path.search(f"{exe_name}.exe", r=True)
|
|
25
26
|
if len(tmp) == 1:
|
|
26
|
-
exe = tmp
|
|
27
|
+
exe = tmp[0]
|
|
27
28
|
print(f"ā
Found exact match for {exe_name}.exe: {exe}")
|
|
28
29
|
else:
|
|
29
30
|
search_res = downloaded_file_path.search("*.exe", r=True)
|
|
@@ -31,10 +32,10 @@ def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optio
|
|
|
31
32
|
print(f"ā ERROR: No executable found in {downloaded_file_path}")
|
|
32
33
|
raise IndexError(f"No executable found in {downloaded_file_path}")
|
|
33
34
|
elif len(search_res) == 1:
|
|
34
|
-
exe = search_res
|
|
35
|
+
exe = search_res[0]
|
|
35
36
|
print(f"ā
Found single executable: {exe}")
|
|
36
37
|
else:
|
|
37
|
-
exe = search_res
|
|
38
|
+
exe = max(search_res, key=lambda x: x.size("kb"))
|
|
38
39
|
print(f"ā
Selected largest executable ({exe.size('kb')} KB): {exe}")
|
|
39
40
|
if rename_to and exe.name != rename_to:
|
|
40
41
|
print(f"š·ļø Renaming '{exe.name}' to '{rename_to}'")
|
|
@@ -49,12 +50,12 @@ def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optio
|
|
|
49
50
|
downloaded_file_path.delete(sure=True)
|
|
50
51
|
print("ā
Temporary files removed")
|
|
51
52
|
|
|
52
|
-
print(f"{'='*80}")
|
|
53
|
+
print(f"{'=' * 80}")
|
|
53
54
|
return exe_new_location
|
|
54
55
|
|
|
55
56
|
|
|
56
57
|
def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Optional[bool] = True, rename_to: Optional[str] = None):
|
|
57
|
-
print(f"\n{'='*80}\nš PROCESSING LINUX EXECUTABLE š\n{'='*80}")
|
|
58
|
+
print(f"\n{'=' * 80}\nš PROCESSING LINUX EXECUTABLE š\n{'=' * 80}")
|
|
58
59
|
if downloaded.is_file():
|
|
59
60
|
exe = downloaded
|
|
60
61
|
print(f"š Found direct executable file: {exe}")
|
|
@@ -62,7 +63,7 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Opt
|
|
|
62
63
|
print(f"š Searching for executable in: {downloaded}")
|
|
63
64
|
res = downloaded.search(f"*{tool_name}*", folders=False, r=True)
|
|
64
65
|
if len(res) == 1:
|
|
65
|
-
exe = res
|
|
66
|
+
exe = res[0]
|
|
66
67
|
print(f"ā
Found match for pattern '*{tool_name}*': {exe}")
|
|
67
68
|
else:
|
|
68
69
|
exe_search_res = downloaded.search(tool_name, folders=False, r=True)
|
|
@@ -70,10 +71,10 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Opt
|
|
|
70
71
|
print(f"ā ERROR: No search results for `{tool_name}` in `{downloaded}`")
|
|
71
72
|
raise IndexError(f"No executable found in {downloaded}")
|
|
72
73
|
elif len(exe_search_res) == 1:
|
|
73
|
-
exe = exe_search_res
|
|
74
|
+
exe = exe_search_res[0]
|
|
74
75
|
print(f"ā
Found exact match for '{tool_name}': {exe}")
|
|
75
76
|
else:
|
|
76
|
-
exe = exe_search_res
|
|
77
|
+
exe = max(exe_search_res, key=lambda x: x.size("kb"))
|
|
77
78
|
print(f"ā
Selected largest executable ({exe.size('kb')} KB): {exe}")
|
|
78
79
|
|
|
79
80
|
if rename_to and exe.name != rename_to:
|
|
@@ -87,7 +88,18 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Opt
|
|
|
87
88
|
# exe.move(folder=LINUX_INSTALL_PATH, overwrite=False)
|
|
88
89
|
if "/usr" in LINUX_INSTALL_PATH:
|
|
89
90
|
print("š Using sudo to move file to system directory...")
|
|
90
|
-
|
|
91
|
+
cmd = f"sudo mv {exe} {LINUX_INSTALL_PATH}/"
|
|
92
|
+
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
|
93
|
+
success = result.returncode == 0 and result.stderr == ""
|
|
94
|
+
if not success:
|
|
95
|
+
desc = f"MOVING executable `{exe}` to {LINUX_INSTALL_PATH}"
|
|
96
|
+
print(f"ā {desc} failed")
|
|
97
|
+
if result.stdout:
|
|
98
|
+
print(f"STDOUT: {result.stdout}")
|
|
99
|
+
if result.stderr:
|
|
100
|
+
print(f"STDERR: {result.stderr}")
|
|
101
|
+
print(f"Return code: {result.returncode}")
|
|
102
|
+
raise RuntimeError(f"Failed to move executable: {result.stderr or result.stdout}")
|
|
91
103
|
else:
|
|
92
104
|
exe.move(folder=LINUX_INSTALL_PATH, overwrite=True)
|
|
93
105
|
|
|
@@ -97,5 +109,5 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Opt
|
|
|
97
109
|
print("ā
Temporary files removed")
|
|
98
110
|
|
|
99
111
|
exe_new_location = PathExtended(LINUX_INSTALL_PATH).joinpath(exe.name)
|
|
100
|
-
print(f"ā
Executable installed at: {exe_new_location}\n{'='*80}")
|
|
101
|
-
return exe_new_location
|
|
112
|
+
print(f"ā
Executable installed at: {exe_new_location}\n{'=' * 80}")
|
|
113
|
+
return exe_new_location
|