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.

Files changed (268) hide show
  1. machineconfig/cluster/cloud_manager.py +22 -29
  2. machineconfig/cluster/data_transfer.py +2 -3
  3. machineconfig/cluster/distribute.py +0 -2
  4. machineconfig/cluster/file_manager.py +4 -5
  5. machineconfig/cluster/job_params.py +1 -4
  6. machineconfig/cluster/loader_runner.py +8 -11
  7. machineconfig/cluster/remote_machine.py +4 -5
  8. machineconfig/cluster/script_execution.py +2 -2
  9. machineconfig/cluster/script_notify_upon_completion.py +0 -1
  10. machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +4 -6
  11. machineconfig/cluster/sessions_managers/archive/session_managers.py +0 -1
  12. machineconfig/cluster/sessions_managers/enhanced_command_runner.py +35 -75
  13. machineconfig/cluster/sessions_managers/wt_local.py +113 -185
  14. machineconfig/cluster/sessions_managers/wt_local_manager.py +127 -197
  15. machineconfig/cluster/sessions_managers/wt_remote.py +60 -67
  16. machineconfig/cluster/sessions_managers/wt_remote_manager.py +110 -149
  17. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +61 -64
  18. machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +72 -172
  19. machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +27 -60
  20. machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +58 -137
  21. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +46 -74
  22. machineconfig/cluster/sessions_managers/zellij_local.py +91 -147
  23. machineconfig/cluster/sessions_managers/zellij_local_manager.py +165 -190
  24. machineconfig/cluster/sessions_managers/zellij_remote.py +51 -58
  25. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +40 -46
  26. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +19 -17
  27. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +30 -31
  28. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +64 -134
  29. machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +7 -11
  30. machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +27 -55
  31. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +14 -13
  32. machineconfig/cluster/templates/cli_click.py +0 -1
  33. machineconfig/cluster/templates/cli_gooey.py +0 -2
  34. machineconfig/cluster/templates/cli_trogon.py +0 -1
  35. machineconfig/cluster/templates/run_cloud.py +0 -1
  36. machineconfig/cluster/templates/run_cluster.py +0 -1
  37. machineconfig/cluster/templates/run_remote.py +0 -1
  38. machineconfig/cluster/templates/utils.py +27 -11
  39. machineconfig/jobs/__pycache__/__init__.cpython-313.pyc +0 -0
  40. machineconfig/jobs/linux/msc/cli_agents.sh +16 -0
  41. machineconfig/jobs/python/check_installations.py +9 -9
  42. machineconfig/jobs/python/create_bootable_media.py +0 -2
  43. machineconfig/jobs/python/python_cargo_build_share.py +2 -2
  44. machineconfig/jobs/python/python_ve_symlink.py +9 -11
  45. machineconfig/jobs/python/tasks.py +0 -1
  46. machineconfig/jobs/python/vscode/api.py +5 -5
  47. machineconfig/jobs/python/vscode/link_ve.py +20 -21
  48. machineconfig/jobs/python/vscode/select_interpreter.py +28 -29
  49. machineconfig/jobs/python/vscode/sync_code.py +14 -18
  50. machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  51. machineconfig/jobs/python_custom_installers/archive/ngrok.py +15 -15
  52. machineconfig/jobs/python_custom_installers/dev/aider.py +10 -18
  53. machineconfig/jobs/python_custom_installers/dev/alacritty.py +12 -21
  54. machineconfig/jobs/python_custom_installers/dev/brave.py +13 -22
  55. machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +13 -20
  56. machineconfig/jobs/python_custom_installers/dev/code.py +17 -24
  57. machineconfig/jobs/python_custom_installers/dev/cursor.py +10 -21
  58. machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +12 -11
  59. machineconfig/jobs/python_custom_installers/dev/espanso.py +19 -23
  60. machineconfig/jobs/python_custom_installers/dev/goes.py +9 -16
  61. machineconfig/jobs/python_custom_installers/dev/lvim.py +13 -21
  62. machineconfig/jobs/python_custom_installers/dev/nerdfont.py +15 -22
  63. machineconfig/jobs/python_custom_installers/dev/redis.py +15 -23
  64. machineconfig/jobs/python_custom_installers/dev/wezterm.py +15 -22
  65. machineconfig/jobs/python_custom_installers/dev/winget.py +32 -50
  66. machineconfig/jobs/python_custom_installers/docker.py +15 -24
  67. machineconfig/jobs/python_custom_installers/gh.py +18 -26
  68. machineconfig/jobs/python_custom_installers/hx.py +33 -17
  69. machineconfig/jobs/python_custom_installers/warp-cli.py +15 -23
  70. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  71. machineconfig/jobs/python_generic_installers/config.json +412 -389
  72. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  73. machineconfig/jobs/python_windows_installers/dev/config.json +1 -1
  74. machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +1 -1
  75. machineconfig/jobs/windows/msc/cli_agents.bat +0 -0
  76. machineconfig/jobs/windows/msc/cli_agents.ps1 +0 -0
  77. machineconfig/jobs/windows/start_terminal.ps1 +1 -1
  78. machineconfig/logger.py +50 -0
  79. machineconfig/profile/create.py +50 -36
  80. machineconfig/profile/create_hardlinks.py +33 -26
  81. machineconfig/profile/shell.py +87 -60
  82. machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  83. machineconfig/scripts/cloud/init.sh +2 -2
  84. machineconfig/scripts/linux/checkout_versions +1 -1
  85. machineconfig/scripts/linux/choose_wezterm_theme +1 -1
  86. machineconfig/scripts/linux/cloud_copy +1 -1
  87. machineconfig/scripts/linux/cloud_manager +1 -1
  88. machineconfig/scripts/linux/cloud_mount +1 -1
  89. machineconfig/scripts/linux/cloud_repo_sync +1 -1
  90. machineconfig/scripts/linux/cloud_sync +1 -1
  91. machineconfig/scripts/linux/croshell +1 -1
  92. machineconfig/scripts/linux/devops +3 -5
  93. machineconfig/scripts/linux/fire +2 -1
  94. machineconfig/scripts/linux/fire_agents +3 -3
  95. machineconfig/scripts/linux/ftpx +1 -1
  96. machineconfig/scripts/linux/gh_models +1 -1
  97. machineconfig/scripts/linux/kill_process +1 -1
  98. machineconfig/scripts/linux/mcinit +2 -2
  99. machineconfig/scripts/linux/repos +1 -1
  100. machineconfig/scripts/linux/scheduler +1 -1
  101. machineconfig/scripts/linux/start_slidev +1 -1
  102. machineconfig/scripts/linux/start_terminals +1 -1
  103. machineconfig/scripts/linux/url2md +1 -1
  104. machineconfig/scripts/linux/warp-cli.sh +122 -0
  105. machineconfig/scripts/linux/wifi_conn +1 -1
  106. machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
  107. machineconfig/scripts/python/__pycache__/croshell.cpython-313.pyc +0 -0
  108. machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
  109. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-313.pyc +0 -0
  110. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
  111. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-313.pyc +0 -0
  112. machineconfig/scripts/python/ai/__init__.py +0 -0
  113. machineconfig/scripts/python/ai/__pycache__/__init__.cpython-313.pyc +0 -0
  114. machineconfig/scripts/python/ai/__pycache__/generate_files.cpython-313.pyc +0 -0
  115. machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-313.pyc +0 -0
  116. machineconfig/scripts/python/ai/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
  117. machineconfig/scripts/python/ai/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
  118. machineconfig/scripts/python/ai/chatmodes/deepResearch.chatmode.md +81 -0
  119. machineconfig/scripts/python/ai/configs/.gemini/settings.json +81 -0
  120. machineconfig/scripts/python/ai/generate_files.py +84 -0
  121. machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +45 -0
  122. machineconfig/scripts/python/ai/mcinit.py +107 -0
  123. machineconfig/scripts/python/ai/prompts/allLintersAndTypeCheckers.prompt.md +5 -0
  124. machineconfig/scripts/python/ai/prompts/research-report-skeleton.prompt.md +38 -0
  125. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +52 -0
  126. machineconfig/scripts/python/archive/tmate_conn.py +5 -5
  127. machineconfig/scripts/python/archive/tmate_start.py +3 -3
  128. machineconfig/scripts/python/choose_wezterm_theme.py +2 -2
  129. machineconfig/scripts/python/cloud_copy.py +20 -19
  130. machineconfig/scripts/python/cloud_mount.py +10 -8
  131. machineconfig/scripts/python/cloud_repo_sync.py +15 -15
  132. machineconfig/scripts/python/cloud_sync.py +1 -1
  133. machineconfig/scripts/python/croshell.py +18 -16
  134. machineconfig/scripts/python/devops.py +6 -6
  135. machineconfig/scripts/python/devops_add_identity.py +9 -7
  136. machineconfig/scripts/python/devops_add_ssh_key.py +19 -19
  137. machineconfig/scripts/python/devops_backup_retrieve.py +14 -14
  138. machineconfig/scripts/python/devops_devapps_install.py +3 -3
  139. machineconfig/scripts/python/devops_update_repos.py +141 -53
  140. machineconfig/scripts/python/dotfile.py +3 -3
  141. machineconfig/scripts/python/fire_agents.py +202 -41
  142. machineconfig/scripts/python/fire_jobs.py +20 -21
  143. machineconfig/scripts/python/ftpx.py +4 -3
  144. machineconfig/scripts/python/gh_models.py +94 -94
  145. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-313.pyc +0 -0
  146. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-313.pyc +0 -0
  147. machineconfig/scripts/python/helpers/cloud_helpers.py +3 -3
  148. machineconfig/scripts/python/helpers/helpers2.py +3 -3
  149. machineconfig/scripts/python/helpers/helpers4.py +8 -7
  150. machineconfig/scripts/python/helpers/helpers5.py +7 -7
  151. machineconfig/scripts/python/helpers/repo_sync_helpers.py +2 -2
  152. machineconfig/scripts/python/mount_nfs.py +4 -3
  153. machineconfig/scripts/python/mount_nw_drive.py +4 -4
  154. machineconfig/scripts/python/mount_ssh.py +4 -3
  155. machineconfig/scripts/python/repos.py +9 -9
  156. machineconfig/scripts/python/scheduler.py +1 -1
  157. machineconfig/scripts/python/start_slidev.py +9 -8
  158. machineconfig/scripts/python/start_terminals.py +1 -1
  159. machineconfig/scripts/python/viewer.py +40 -40
  160. machineconfig/scripts/python/wifi_conn.py +65 -66
  161. machineconfig/scripts/python/wsl_windows_transfer.py +2 -2
  162. machineconfig/scripts/windows/checkout_version.ps1 +1 -3
  163. machineconfig/scripts/windows/choose_wezterm_theme.ps1 +1 -3
  164. machineconfig/scripts/windows/cloud_copy.ps1 +2 -6
  165. machineconfig/scripts/windows/cloud_manager.ps1 +1 -1
  166. machineconfig/scripts/windows/cloud_repo_sync.ps1 +1 -2
  167. machineconfig/scripts/windows/cloud_sync.ps1 +2 -2
  168. machineconfig/scripts/windows/croshell.ps1 +2 -2
  169. machineconfig/scripts/windows/devops.ps1 +1 -4
  170. machineconfig/scripts/windows/dotfile.ps1 +1 -3
  171. machineconfig/scripts/windows/fire.ps1 +1 -1
  172. machineconfig/scripts/windows/ftpx.ps1 +2 -2
  173. machineconfig/scripts/windows/gpt.ps1 +1 -1
  174. machineconfig/scripts/windows/kill_process.ps1 +1 -2
  175. machineconfig/scripts/windows/mcinit.ps1 +2 -2
  176. machineconfig/scripts/windows/mount_nfs.ps1 +1 -1
  177. machineconfig/scripts/windows/mount_ssh.ps1 +1 -1
  178. machineconfig/scripts/windows/pomodoro.ps1 +1 -1
  179. machineconfig/scripts/windows/py2exe.ps1 +1 -3
  180. machineconfig/scripts/windows/repos.ps1 +1 -1
  181. machineconfig/scripts/windows/scheduler.ps1 +1 -1
  182. machineconfig/scripts/windows/snapshot.ps1 +2 -2
  183. machineconfig/scripts/windows/start_slidev.ps1 +1 -1
  184. machineconfig/scripts/windows/start_terminals.ps1 +1 -1
  185. machineconfig/scripts/windows/wifi_conn.ps1 +1 -1
  186. machineconfig/scripts/windows/wsl_windows_transfer.ps1 +1 -3
  187. machineconfig/settings/lf/linux/lfrc +1 -1
  188. machineconfig/settings/linters/.ruff.toml +2 -2
  189. machineconfig/settings/linters/.ruff_cache/.gitignore +2 -0
  190. machineconfig/settings/linters/.ruff_cache/CACHEDIR.TAG +1 -0
  191. machineconfig/settings/lvim/windows/archive/config_additional.lua +1 -1
  192. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +71 -71
  193. machineconfig/settings/shells/wt/settings.json +8 -8
  194. machineconfig/settings/svim/linux/init.toml +1 -1
  195. machineconfig/settings/svim/windows/init.toml +1 -1
  196. machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -54
  197. machineconfig/setup_linux/web_shortcuts/interactive.sh +6 -6
  198. machineconfig/setup_linux/web_shortcuts/tmp.sh +2 -0
  199. machineconfig/setup_windows/web_shortcuts/all.ps1 +2 -2
  200. machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +1 -1
  201. machineconfig/setup_windows/web_shortcuts/croshell.ps1 +1 -1
  202. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +5 -5
  203. machineconfig/setup_windows/wt_and_pwsh/install_fonts.ps1 +51 -15
  204. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +75 -18
  205. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +52 -42
  206. machineconfig/utils/ai/browser_user_wrapper.py +5 -5
  207. machineconfig/utils/ai/generate_file_checklist.py +19 -22
  208. machineconfig/utils/ai/url2md.py +5 -3
  209. machineconfig/utils/cloud/onedrive/setup_oauth.py +5 -4
  210. machineconfig/utils/cloud/onedrive/transaction.py +192 -227
  211. machineconfig/utils/code.py +71 -43
  212. machineconfig/utils/installer.py +77 -85
  213. machineconfig/utils/installer_utils/installer_abc.py +29 -17
  214. machineconfig/utils/installer_utils/installer_class.py +188 -83
  215. machineconfig/utils/io_save.py +3 -15
  216. machineconfig/utils/links.py +22 -11
  217. machineconfig/utils/notifications.py +197 -0
  218. machineconfig/utils/options.py +38 -25
  219. machineconfig/utils/path.py +18 -6
  220. machineconfig/utils/path_reduced.py +637 -316
  221. machineconfig/utils/procs.py +69 -63
  222. machineconfig/utils/scheduling.py +11 -13
  223. machineconfig/utils/ssh.py +351 -0
  224. machineconfig/utils/terminal.py +225 -0
  225. machineconfig/utils/utils.py +13 -12
  226. machineconfig/utils/utils2.py +43 -10
  227. machineconfig/utils/utils5.py +242 -46
  228. machineconfig/utils/ve.py +11 -6
  229. {machineconfig-1.97.dist-info → machineconfig-2.1.dist-info}/METADATA +15 -9
  230. {machineconfig-1.97.dist-info → machineconfig-2.1.dist-info}/RECORD +232 -235
  231. machineconfig/cluster/self_ssh.py +0 -57
  232. machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
  233. machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
  234. machineconfig/jobs/python/archive/python_tools.txt +0 -12
  235. machineconfig/jobs/python/vscode/__pycache__/select_interpreter.cpython-311.pyc +0 -0
  236. machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  237. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  238. machineconfig/jobs/python_generic_installers/update.py +0 -3
  239. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
  240. machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
  241. machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
  242. machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
  243. machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  244. machineconfig/scripts/linux/activate_ve +0 -87
  245. machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
  246. machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
  247. machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
  248. machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
  249. machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
  250. machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
  251. machineconfig/scripts/python/__pycache__/devops_backup_retrieve.cpython-311.pyc +0 -0
  252. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
  253. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
  254. machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
  255. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
  256. machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-311.pyc +0 -0
  257. machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
  258. machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
  259. machineconfig/scripts/python/ai/init.py +0 -56
  260. machineconfig/scripts/python/ai/rules/python/dev.md +0 -31
  261. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
  262. machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
  263. machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
  264. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
  265. machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-311.pyc +0 -0
  266. machineconfig/scripts/windows/activate_ve.ps1 +0 -54
  267. {machineconfig-1.97.dist-info → machineconfig-2.1.dist-info}/WHEEL +0 -0
  268. {machineconfig-1.97.dist-info → machineconfig-2.1.dist-info}/top_level.txt +0 -0
@@ -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.path_reduced import P as PathExtended
8
- from crocodile.meta import Terminal
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 = (PathExtended.home().joinpath("tmp_results", "shells", "python_return_command") + (".ps1" if platform.system() == "Windows" else ".sh"))
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] = None, ve_name: str="ve", strict_execution: bool=True):
15
- if func is None: exec_line = f"""python {python_file}"""
16
- else: exec_line = f"""python -m fire {python_file} {func}"""
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
- . $HOME/scripts/activate_ve {ve_name}
19
- echo "Executing {exec_line}"
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": shell_script = """$ErrorActionPreference = "Stop" """ + "\n" + shell_script
26
- if platform.system() in ["Linux", "Darwin"]: shell_script = "set -e" + "\n" + shell_script
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"]: shell_script = "#!/bin/bash" + "\n" + shell_script # vs #!/usr/bin/env bash
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"]: suffix = ".sh"
34
- elif platform.system() == "Windows": suffix = ".ps1"
35
- else: raise NotImplementedError(f"Platform {platform.system()} not implemented.")
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: print_code(code=program, lexer="shell", desc=desc, subtitle=str(PROGRAM_PATH))
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
- Terminal().run(f". {PROGRAM_PATH}", shell="powershell").capture().print_if_unsuccessful(desc="šŸ› ļø EXECUTION | Shell script running", strict_err=True, strict_returncode=True)
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": lexer = "powershell"
81
- elif platform.system() in ["Linux", "Darwin"]: lexer = "sh"
82
- else: raise NotImplementedError(f"Platform {platform.system()} not supported for lexer {lexer}")
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
-
@@ -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 # Added import
6
+ from rich.panel import Panel # Added import
7
7
 
8
- from machineconfig.utils.path_reduced import P as PathExtended
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() # Added console initialization
21
- console.print(Panel("šŸ” CHECKING FOR LATEST VERSIONS", title="Status", expand=False)) # Replaced print with Panel
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
- "Tool": tool,
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('config.json')}""")
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)['config_dict']
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)['config_dict']
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
- print("āš ļø Safe installation mode activated...")
183
- from machineconfig.jobs.python.check_installations import APP_SUMMARY_PATH
184
- apps_dir = APP_SUMMARY_PATH.readit()
185
-
186
- if platform.system().lower() == "windows":
187
- print("🪟 Moving applications to Windows Apps folder...")
188
- # PathExtended.get_env().WindowsPaths().WindowsApps)
189
- folder = PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps")
190
- apps_dir.search("*").apply(lambda app: app.move(folder=folder))
191
- elif platform.system().lower() in ["linux", "darwin"]:
192
- system_name = "Linux" if platform.system().lower() == "linux" else "macOS"
193
- print(f"🐧 Moving applications to {system_name} bin folder...")
194
- if platform.system().lower() == "linux":
195
- install_path = LINUX_INSTALL_PATH
196
- else: # Darwin/macOS
197
- install_path = "/usr/local/bin"
198
- 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)
199
- else:
200
- error_msg = f"āŒ ERROR: System {platform.system()} not supported"
201
- print(error_msg)
202
- raise NotImplementedError(error_msg)
203
-
204
- apps_dir.delete(sure=True)
205
- print(f"āœ… Safe installation completed\n{'='*80}")
206
- return None
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
- delayed(lambda x: x.install_robust(version=None))(installer)
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 'same version' in str(r)]
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 'updated from' in str(r)]
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 'Failed at' in str(r)]
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 P as PathExtended
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: exe_name = exe_name.replace(".exe", "")
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).list[0]
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.list[0]
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.list[0]
35
+ exe = search_res[0]
35
36
  print(f"āœ… Found single executable: {exe}")
36
37
  else:
37
- exe = search_res.sort(lambda x: x.size("kb")).list[-1]
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.list[0]
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.list[0]
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.sort(lambda x: x.size("kb")).list[-1]
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
- Terminal().run(f"sudo mv {exe} {LINUX_INSTALL_PATH}/").capture().print_if_unsuccessful(desc=f"MOVING executable `{exe}` to {LINUX_INSTALL_PATH}", strict_err=True, strict_returncode=True)
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