machineconfig 1.96__py3-none-any.whl → 2.0__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 (164) hide show
  1. machineconfig/cluster/cloud_manager.py +22 -26
  2. machineconfig/cluster/data_transfer.py +2 -2
  3. machineconfig/cluster/distribute.py +0 -2
  4. machineconfig/cluster/file_manager.py +4 -4
  5. machineconfig/cluster/job_params.py +1 -1
  6. machineconfig/cluster/loader_runner.py +8 -8
  7. machineconfig/cluster/remote_machine.py +4 -4
  8. machineconfig/cluster/script_execution.py +2 -2
  9. machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +1 -1
  10. machineconfig/cluster/sessions_managers/enhanced_command_runner.py +23 -23
  11. machineconfig/cluster/sessions_managers/wt_local.py +78 -76
  12. machineconfig/cluster/sessions_managers/wt_local_manager.py +91 -91
  13. machineconfig/cluster/sessions_managers/wt_remote.py +39 -39
  14. machineconfig/cluster/sessions_managers/wt_remote_manager.py +94 -91
  15. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +56 -54
  16. machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +49 -49
  17. machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +18 -18
  18. machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +42 -42
  19. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +36 -36
  20. machineconfig/cluster/sessions_managers/zellij_local.py +43 -46
  21. machineconfig/cluster/sessions_managers/zellij_local_manager.py +139 -120
  22. machineconfig/cluster/sessions_managers/zellij_remote.py +35 -35
  23. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +33 -33
  24. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +15 -15
  25. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +25 -26
  26. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +49 -49
  27. machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +5 -5
  28. machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +15 -15
  29. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +11 -11
  30. machineconfig/cluster/templates/utils.py +3 -3
  31. machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
  32. machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
  33. machineconfig/jobs/python/__pycache__/python_ve_symlink.cpython-311.pyc +0 -0
  34. machineconfig/jobs/python/check_installations.py +8 -9
  35. machineconfig/jobs/python/python_cargo_build_share.py +2 -2
  36. machineconfig/jobs/python/vscode/link_ve.py +7 -7
  37. machineconfig/jobs/python/vscode/select_interpreter.py +7 -7
  38. machineconfig/jobs/python/vscode/sync_code.py +5 -5
  39. machineconfig/jobs/python_custom_installers/archive/ngrok.py +2 -2
  40. machineconfig/jobs/python_custom_installers/dev/aider.py +3 -3
  41. machineconfig/jobs/python_custom_installers/dev/alacritty.py +3 -3
  42. machineconfig/jobs/python_custom_installers/dev/brave.py +3 -3
  43. machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +5 -5
  44. machineconfig/jobs/python_custom_installers/dev/code.py +3 -3
  45. machineconfig/jobs/python_custom_installers/dev/cursor.py +9 -9
  46. machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +4 -4
  47. machineconfig/jobs/python_custom_installers/dev/espanso.py +4 -4
  48. machineconfig/jobs/python_custom_installers/dev/goes.py +4 -4
  49. machineconfig/jobs/python_custom_installers/dev/lvim.py +4 -4
  50. machineconfig/jobs/python_custom_installers/dev/nerdfont.py +3 -3
  51. machineconfig/jobs/python_custom_installers/dev/redis.py +3 -3
  52. machineconfig/jobs/python_custom_installers/dev/wezterm.py +3 -3
  53. machineconfig/jobs/python_custom_installers/dev/winget.py +27 -27
  54. machineconfig/jobs/python_custom_installers/docker.py +3 -3
  55. machineconfig/jobs/python_custom_installers/gh.py +7 -7
  56. machineconfig/jobs/python_custom_installers/hx.py +1 -1
  57. machineconfig/jobs/python_custom_installers/warp-cli.py +3 -3
  58. machineconfig/jobs/python_generic_installers/config.json +412 -389
  59. machineconfig/jobs/python_windows_installers/dev/config.json +1 -1
  60. machineconfig/logger.py +50 -0
  61. machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
  62. machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
  63. machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
  64. machineconfig/profile/create.py +23 -16
  65. machineconfig/profile/create_hardlinks.py +8 -8
  66. machineconfig/profile/shell.py +41 -37
  67. machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
  68. machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  69. machineconfig/scripts/linux/devops +2 -2
  70. machineconfig/scripts/linux/fire +1 -0
  71. machineconfig/scripts/linux/fire_agents +0 -1
  72. machineconfig/scripts/linux/mcinit +27 -0
  73. machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
  74. machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
  75. machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
  76. machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
  77. machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
  78. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
  79. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
  80. machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
  81. machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
  82. machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
  83. machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
  84. machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-311.pyc +0 -0
  85. machineconfig/scripts/python/ai/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
  86. machineconfig/scripts/python/ai/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
  87. machineconfig/scripts/python/ai/chatmodes/deepResearch.chatmode.md +81 -0
  88. machineconfig/scripts/python/ai/configs/.gemini/settings.json +81 -0
  89. machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +45 -0
  90. machineconfig/scripts/python/ai/mcinit.py +103 -0
  91. machineconfig/scripts/python/ai/prompts/allLintersAndTypeCheckers.prompt.md +5 -0
  92. machineconfig/scripts/python/ai/prompts/research-report-skeleton.prompt.md +38 -0
  93. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +47 -0
  94. machineconfig/scripts/python/archive/tmate_conn.py +5 -5
  95. machineconfig/scripts/python/archive/tmate_start.py +3 -3
  96. machineconfig/scripts/python/choose_wezterm_theme.py +2 -2
  97. machineconfig/scripts/python/cloud_copy.py +19 -18
  98. machineconfig/scripts/python/cloud_mount.py +9 -7
  99. machineconfig/scripts/python/cloud_repo_sync.py +11 -11
  100. machineconfig/scripts/python/cloud_sync.py +1 -1
  101. machineconfig/scripts/python/croshell.py +14 -14
  102. machineconfig/scripts/python/devops.py +6 -6
  103. machineconfig/scripts/python/devops_add_identity.py +8 -6
  104. machineconfig/scripts/python/devops_add_ssh_key.py +18 -18
  105. machineconfig/scripts/python/devops_backup_retrieve.py +13 -13
  106. machineconfig/scripts/python/devops_devapps_install.py +3 -3
  107. machineconfig/scripts/python/devops_update_repos.py +1 -1
  108. machineconfig/scripts/python/dotfile.py +2 -2
  109. machineconfig/scripts/python/fire_agents.py +183 -41
  110. machineconfig/scripts/python/fire_jobs.py +17 -11
  111. machineconfig/scripts/python/ftpx.py +2 -2
  112. machineconfig/scripts/python/gh_models.py +94 -94
  113. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
  114. machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
  115. machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
  116. machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
  117. machineconfig/scripts/python/helpers/cloud_helpers.py +3 -3
  118. machineconfig/scripts/python/helpers/helpers2.py +1 -1
  119. machineconfig/scripts/python/helpers/helpers4.py +8 -6
  120. machineconfig/scripts/python/helpers/helpers5.py +7 -7
  121. machineconfig/scripts/python/helpers/repo_sync_helpers.py +1 -1
  122. machineconfig/scripts/python/mount_nfs.py +3 -2
  123. machineconfig/scripts/python/mount_nw_drive.py +4 -4
  124. machineconfig/scripts/python/mount_ssh.py +3 -2
  125. machineconfig/scripts/python/repos.py +8 -8
  126. machineconfig/scripts/python/scheduler.py +1 -1
  127. machineconfig/scripts/python/start_slidev.py +8 -7
  128. machineconfig/scripts/python/start_terminals.py +1 -1
  129. machineconfig/scripts/python/viewer.py +40 -40
  130. machineconfig/scripts/python/wifi_conn.py +65 -66
  131. machineconfig/scripts/python/wsl_windows_transfer.py +1 -1
  132. machineconfig/scripts/windows/mcinit.ps1 +4 -0
  133. machineconfig/settings/linters/.ruff.toml +2 -2
  134. machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +71 -71
  135. machineconfig/settings/shells/wt/settings.json +8 -8
  136. machineconfig/setup_linux/web_shortcuts/tmp.sh +2 -0
  137. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +10 -7
  138. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +9 -7
  139. machineconfig/utils/ai/browser_user_wrapper.py +5 -5
  140. machineconfig/utils/ai/generate_file_checklist.py +11 -12
  141. machineconfig/utils/ai/url2md.py +1 -1
  142. machineconfig/utils/cloud/onedrive/setup_oauth.py +4 -4
  143. machineconfig/utils/cloud/onedrive/transaction.py +129 -129
  144. machineconfig/utils/code.py +13 -6
  145. machineconfig/utils/installer.py +51 -53
  146. machineconfig/utils/installer_utils/installer_abc.py +21 -10
  147. machineconfig/utils/installer_utils/installer_class.py +42 -16
  148. machineconfig/utils/io_save.py +3 -15
  149. machineconfig/utils/options.py +10 -3
  150. machineconfig/utils/path.py +5 -0
  151. machineconfig/utils/path_reduced.py +201 -149
  152. machineconfig/utils/procs.py +23 -23
  153. machineconfig/utils/scheduling.py +11 -12
  154. machineconfig/utils/ssh.py +270 -0
  155. machineconfig/utils/terminal.py +180 -0
  156. machineconfig/utils/utils.py +1 -2
  157. machineconfig/utils/utils2.py +43 -0
  158. machineconfig/utils/utils5.py +163 -34
  159. machineconfig/utils/ve.py +2 -2
  160. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/METADATA +13 -8
  161. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/RECORD +163 -144
  162. machineconfig/cluster/self_ssh.py +0 -57
  163. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/WHEEL +0 -0
  164. {machineconfig-1.96.dist-info → machineconfig-2.0.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,3 @@
1
1
  {
2
-
2
+
3
3
  }
@@ -0,0 +1,50 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ import os
5
+ import sys
6
+ from typing import Optional
7
+
8
+
9
+ def _configure_root_logger() -> logging.Logger:
10
+ """Create and configure the root logger for the machineconfig package.
11
+
12
+ The logger writes to stdout, honors MC_LOG_LEVEL env var, and avoids
13
+ duplicate handlers on repeated imports.
14
+ """
15
+ root = logging.getLogger("machineconfig")
16
+ if root.handlers:
17
+ return root
18
+
19
+ level_name = os.getenv("MC_LOG_LEVEL", "INFO").upper()
20
+ level = getattr(logging, level_name, logging.INFO)
21
+ root.setLevel(level)
22
+
23
+ handler = logging.StreamHandler(stream=sys.stdout)
24
+ fmt = "%(asctime)s | %(levelname)s | %(name)s | %(message)s"
25
+ datefmt = "%H:%M:%S"
26
+ handler.setFormatter(logging.Formatter(fmt=fmt, datefmt=datefmt))
27
+ root.addHandler(handler)
28
+ root.propagate = False
29
+ return root
30
+
31
+
32
+ _ROOT_LOGGER = _configure_root_logger()
33
+
34
+
35
+ def get_logger(name: Optional[str] = None) -> logging.Logger:
36
+ """Return a child logger of the package root.
37
+
38
+ Inputs:
39
+ - name: Optional dotted logger name; when None, returns the package root.
40
+
41
+ Returns:
42
+ - logging.Logger configured under the 'machineconfig' hierarchy.
43
+ """
44
+ if name is None:
45
+ return _ROOT_LOGGER
46
+ return _ROOT_LOGGER.getChild(name)
47
+
48
+
49
+ # Convenience alias for simple imports: `from machineconfig.logger import logger`
50
+ logger: logging.Logger = get_logger()
@@ -5,12 +5,14 @@ This script Takes away all config files from the computer, place them in one dir
5
5
  """
6
6
 
7
7
 
8
- from crocodile.meta import Terminal
9
8
  from machineconfig.utils.path_reduced import P as PathExtended
10
9
  from machineconfig.utils.utils import symlink_func, symlink_copy, LIBRARY_ROOT, REPO_ROOT, display_options
10
+ from machineconfig.utils.utils2 import read_toml
11
11
  from machineconfig.profile.shell import create_default_shell_profile
12
12
  # import os
13
13
  import platform
14
+ import os
15
+ import ctypes
14
16
  import subprocess
15
17
  from rich.console import Console
16
18
  from typing import Optional, Any, TypedDict
@@ -29,10 +31,7 @@ class SymlinkMapper(TypedDict):
29
31
 
30
32
 
31
33
  def main_symlinks(choice: Optional[str] = None):
32
- symlink_mapper = LIBRARY_ROOT.joinpath("profile/mapper.toml").readit()
33
- # symlink_mapper['wsl_windows']['home']["to_this"] = symlink_mapper['wsl_windows']['home']["to_this"].replace("username", UserName)
34
- # symlink_mapper['wsl_linux']['home']["to_this"] = symlink_mapper['wsl_linux']['home']["to_this"].replace("username", UserName)
35
-
34
+ symlink_mapper: dict[str, dict[str, SymlinkMapper]] = read_toml(LIBRARY_ROOT.joinpath("profile/mapper.toml"))
36
35
  overwrite = True
37
36
  exclude: list[str] = [] # "wsl_linux", "wsl_windows"
38
37
 
@@ -55,16 +54,24 @@ def main_symlinks(choice: Optional[str] = None):
55
54
  else: choice_selected = choice
56
55
 
57
56
  if isinstance(choice_selected, str):
58
- if str(choice_selected) == "all" and system == "Windows" and not Terminal.is_user_admin():
59
- print(f"""
57
+ if str(choice_selected) == "all" and system == "Windows":
58
+ if os.name == 'nt':
59
+ try:
60
+ is_admin = ctypes.windll.shell32.IsUserAnAdmin()
61
+ except Exception:
62
+ is_admin = False
63
+ else:
64
+ is_admin = False
65
+ if not is_admin:
66
+ print(f"""
60
67
  {'*' * 80}
61
68
  ⚠️ WARNING: Administrator privileges required
62
69
  {'*' * 80}
63
70
  """)
64
- raise RuntimeError("Run terminal as admin and try again, otherwise, there will be too many popups for admin requests and no chance to terminate the program.")
71
+ raise RuntimeError("Run terminal as admin and try again, otherwise, there will be too many popups for admin requests and no chance to terminate the program.")
65
72
  elif choice_selected == "all":
66
73
  print(f"""
67
- 🔍 Processing all program keys:
74
+ 🔍 Processing all program keys:
68
75
  {program_keys}
69
76
  """)
70
77
  pass # i.e. program_keys = program_keys
@@ -80,17 +87,17 @@ def main_symlinks(choice: Optional[str] = None):
80
87
  try:
81
88
  for a_target in to_this.expanduser().search("*"):
82
89
  symlink_func(this=this.joinpath(a_target.name), to_this=a_target, prioritize_to_this=overwrite)
83
- except Exception as ex:
90
+ except Exception as ex:
84
91
  print(f"❌ Config error: {program_key} | {file_key} | missing keys 'this ==> to_this'. {ex}")
85
92
  if "copy" in file_map:
86
93
  try:
87
94
  symlink_copy(this=this, to_this=to_this, prioritize_to_this=overwrite)
88
- except Exception as ex:
95
+ except Exception as ex:
89
96
  print(f"❌ Config error: {program_key} | {file_key} | {ex}")
90
97
  else:
91
- try:
98
+ try:
92
99
  symlink_func(this=this, to_this=to_this, prioritize_to_this=overwrite)
93
- except Exception as ex:
100
+ except Exception as ex:
94
101
  print(f"❌ Config error: {program_key} | {file_key} | missing keys 'this ==> to_this'. {ex}")
95
102
 
96
103
  if program_key == "ssh" and system == "Linux": # permissions of ~/dotfiles/.ssh should be adjusted
@@ -106,9 +113,9 @@ def main_symlinks(choice: Optional[str] = None):
106
113
 
107
114
  if system == "Linux":
108
115
  print("\n📜 Setting executable permissions for scripts...")
109
- Terminal().run(f'chmod +x {LIBRARY_ROOT.joinpath(f"scripts/{system.lower()}")} -R')
116
+ subprocess.run(f'chmod +x {LIBRARY_ROOT.joinpath(f"scripts/{system.lower()}")} -R', shell=True, capture_output=True, text=True)
110
117
  print("✅ Script permissions updated")
111
-
118
+
112
119
  if len(ERROR_LIST) > 0:
113
120
  print(f"""
114
121
  {'*' * 80}
@@ -134,7 +141,7 @@ def main(choice: Optional[str] = None):
134
141
  print("\n")
135
142
  console.rule("[bold green]🐚 CREATING SHELL PROFILE 🐚")
136
143
  create_default_shell_profile()
137
-
144
+
138
145
  print(f"""
139
146
  {'=' * 80}
140
147
  ✨ Configuration setup complete! ✨
@@ -6,9 +6,9 @@ This script Takes away all config files from the computer, place them in one dir
6
6
 
7
7
 
8
8
  import platform
9
- from crocodile.meta import Terminal
10
9
  from machineconfig.utils.path_reduced import P as PathExtended
11
10
  from machineconfig.utils.utils import symlink_copy as symlink_func, LIBRARY_ROOT, REPO_ROOT, display_options
11
+ from machineconfig.utils.utils2 import read_toml
12
12
  from machineconfig.profile.shell import create_default_shell_profile
13
13
  # import os
14
14
  import subprocess
@@ -23,7 +23,7 @@ SYSTEM = system.lower()
23
23
 
24
24
 
25
25
  def main_symlinks(choice: Optional[str] = None):
26
- symlink_mapper = LIBRARY_ROOT.joinpath("profile/mapper.toml").readit()
26
+ symlink_mapper = read_toml(LIBRARY_ROOT.joinpath("profile/mapper.toml"))
27
27
  # symlink_mapper['wsl_windows']['home']["to_this"] = symlink_mapper['wsl_windows']['home']["to_this"].replace("username", UserName)
28
28
  # symlink_mapper['wsl_linux']['home']["to_this"] = symlink_mapper['wsl_linux']['home']["to_this"].replace("username", UserName)
29
29
 
@@ -53,7 +53,7 @@ def main_symlinks(choice: Optional[str] = None):
53
53
  if isinstance(choice_selected, str):
54
54
  if choice_selected == "all":
55
55
  print(f"""
56
- 🔍 Processing all program keys:
56
+ 🔍 Processing all program keys:
57
57
  {program_keys}
58
58
  """)
59
59
  pass # i.e. program_keys = program_keys
@@ -69,13 +69,13 @@ def main_symlinks(choice: Optional[str] = None):
69
69
  try:
70
70
  for a_target in to_this.expanduser().search("*"):
71
71
  symlink_func(this=this.joinpath(a_target.name), to_this=a_target, prioritize_to_this=overwrite)
72
- except Exception as ex:
72
+ except Exception as ex:
73
73
  print(f"❌ Config error: {program_key} | {file_key} | missing keys 'this ==> to_this'. {ex}")
74
74
  else:
75
- try:
75
+ try:
76
76
  symlink_func(this=this, to_this=to_this, prioritize_to_this=overwrite)
77
77
  print(f" ✅ Created hardlink from {this} to {to_this}")
78
- except Exception as ex:
78
+ except Exception as ex:
79
79
  print(f"❌ Config error: {program_key} | {file_key} | missing keys 'this ==> to_this'. {ex}")
80
80
 
81
81
  if program_key == "ssh" and system == "Linux": # permissions of ~/dotfiles/.ssh should be adjusted
@@ -91,7 +91,7 @@ def main_symlinks(choice: Optional[str] = None):
91
91
 
92
92
  if system == "Linux":
93
93
  print("\n📜 Setting executable permissions for scripts...")
94
- Terminal().run(f'chmod +x {LIBRARY_ROOT.joinpath(f"scripts/{system.lower()}")} -R')
94
+ subprocess.run(f'chmod +x {LIBRARY_ROOT.joinpath(f"scripts/{system.lower()}")} -R', shell=True, capture_output=True, text=True)
95
95
  print("✅ Script permissions updated")
96
96
 
97
97
  if len(ERROR_LIST) > 0:
@@ -119,7 +119,7 @@ def main(choice: Optional[str] = None):
119
119
  print("\n")
120
120
  console.rule("[bold green]🐚 CREATING SHELL PROFILE 🐚")
121
121
  create_default_shell_profile()
122
-
122
+
123
123
  print(f"""
124
124
  {'=' * 80}
125
125
  ✨ Configuration setup complete! ✨
@@ -3,7 +3,7 @@
3
3
 
4
4
  from machineconfig.utils.utils2 import randstr
5
5
  from machineconfig.utils.path_reduced import P as PathExtended, modify_text
6
- from crocodile.meta import Terminal
6
+ from machineconfig.utils.terminal import Terminal
7
7
  from machineconfig.utils.utils import LIBRARY_ROOT, REPO_ROOT, display_options
8
8
  import platform
9
9
  import os
@@ -24,13 +24,13 @@ BOX_WIDTH = 100 # Define BOX_WIDTH or get it from a config
24
24
  # for windows it won't change the profile, if the profile was modified already e.g. due to syncing
25
25
 
26
26
 
27
- def create_default_shell_profile():
27
+ def create_default_shell_profile() -> None:
28
28
  profile_path = get_shell_profile_path()
29
- profile = profile_path.read_text()
30
- if system == "Windows": source = f". {str(LIBRARY_ROOT.joinpath('settings/shells/pwsh/init.ps1').collapseuser()).replace('~', '$HOME')}"
31
- else: source = f"source {str(LIBRARY_ROOT.joinpath('settings/shells/bash/init.sh').collapseuser()).replace('~', '$HOME')}"
29
+ profile = profile_path.read_text(encoding="utf-8")
30
+ if system == "Windows": source = f""". {str(LIBRARY_ROOT.joinpath('settings/shells/pwsh/init.ps1').collapseuser()).replace('~', '$HOME')}"""
31
+ else: source = f"""source {str(LIBRARY_ROOT.joinpath('settings/shells/bash/init.sh').collapseuser()).replace('~', '$HOME')}"""
32
32
 
33
- if source in profile:
33
+ if source in profile:
34
34
  console.print(Panel("🔄 PROFILE | Skipping init script sourcing - already present in profile", title="[bold blue]Profile[/bold blue]", border_style="blue"))
35
35
  else:
36
36
  console.print(Panel("📝 PROFILE | Adding init script sourcing to profile", title="[bold blue]Profile[/bold blue]", border_style="blue"))
@@ -38,28 +38,28 @@ def create_default_shell_profile():
38
38
  if system == "Linux":
39
39
  res = Terminal().run("cat /proc/version").op
40
40
  if "microsoft" in res.lower() or "wsl" in res.lower():
41
- profile += "\ncd ~" # this is to make sure that the current dir is not in the windows file system, which is terribly slow and its a bad idea to be there anyway.
41
+ profile += "\ncd ~"
42
42
  console.print("📌 WSL detected - adding 'cd ~' to profile to avoid Windows filesystem")
43
43
  profile_path.parent.mkdir(parents=True, exist_ok=True)
44
- profile_path.write_text(profile)
44
+ profile_path.write_text(profile, encoding="utf-8")
45
45
  console.print(Panel("✅ Profile updated successfully", title="[bold blue]Profile[/bold blue]", border_style="blue"))
46
46
 
47
47
 
48
- def get_shell_profile_path():
48
+ def get_shell_profile_path() -> PathExtended:
49
49
  if system == "Windows":
50
50
  obj = Terminal().run("$PROFILE", shell="pwsh")
51
51
  res = obj.op2path()
52
52
  if isinstance(res, PathExtended): profile_path = res
53
53
  else:
54
54
  obj.print(capture=False)
55
- raise ValueError(f"Could not get profile path for Windows. Got {res}")
55
+ raise ValueError(f"""Could not get profile path for Windows. Got {res}""")
56
56
  elif system == "Linux": profile_path = PathExtended("~/.bashrc").expanduser()
57
- else: raise ValueError(f"Not implemented for this system {system}")
58
- console.print(Panel(f"🐚 SHELL PROFILE | Working with path: `{profile_path}`", title="[bold blue]Shell Profile[/bold blue]", border_style="blue"))
57
+ else: raise ValueError(f"""Not implemented for this system {system}""")
58
+ console.print(Panel(f"""🐚 SHELL PROFILE | Working with path: `{profile_path}`""", title="[bold blue]Shell Profile[/bold blue]", border_style="blue"))
59
59
  return profile_path
60
60
 
61
61
 
62
- def append_temporarily(dirs: list[str], kind: Literal['append', 'prefix', 'replace'] = "append"):
62
+ def append_temporarily(dirs: list[str], kind: Literal['append', 'prefix', 'replace']) -> str:
63
63
  dirs_ = []
64
64
  for path in dirs:
65
65
  path_rel = PathExtended(path).collapseuser(strict=False)
@@ -81,8 +81,10 @@ def append_temporarily(dirs: list[str], kind: Literal['append', 'prefix', 'repla
81
81
  else: raise ValueError
82
82
  return result
83
83
 
84
- def main_env_path(choice: Optional[str] = None, profile_path: Optional[str] = None):
85
- env_path = LIBRARY_ROOT.joinpath("profile/env_path.toml").readit()
84
+ def main_env_path(choice: Optional[str], profile_path: Optional[str]) -> None:
85
+ from machineconfig.utils.utils2 import read_toml
86
+ env_path = read_toml(LIBRARY_ROOT.joinpath("profile/env_path.toml"))
87
+ # env_path = LIBRARY_ROOT.joinpath("profile/env_path.toml").readit()
86
88
  dirs = env_path[f'path_{system.lower()}']['extension']
87
89
 
88
90
  console.print(Panel("🔍 ENVIRONMENT | Current PATH variables:", title="[bold blue]Environment[/bold blue]", border_style="blue"))
@@ -95,19 +97,21 @@ def main_env_path(choice: Optional[str] = None, profile_path: Optional[str] = No
95
97
  if choice == "none(EXIT)": return
96
98
 
97
99
  console.print(f"\n📌 Adding directories to PATH: {dirs}")
98
- addition = append_temporarily(dirs=dirs)
100
+ addition = append_temporarily(dirs=dirs, kind="append")
99
101
  profile_path_obj = PathExtended(profile_path) if isinstance(profile_path, str) else get_shell_profile_path()
100
102
  profile_path_obj.copy(name=profile_path_obj.name + ".orig_" + randstr())
101
103
  console.print(f"💾 Created backup of profile: {profile_path_obj.name}.orig_*")
102
104
  # Inline deprecated P.modify_text: if file missing, seed with search text before modification
103
- current = profile_path_obj.read_text() if profile_path_obj.exists() else addition
105
+ current = profile_path_obj.read_text(encoding="utf-8") if profile_path_obj.exists() else addition
104
106
  updated = modify_text(current, addition, addition, replace_line=False, notfound_append=True)
105
- profile_path_obj.write_text(updated)
107
+ profile_path_obj.write_text(updated, encoding="utf-8")
106
108
  console.print(Panel("✅ PATH variables added to profile successfully", title="[bold blue]Environment[/bold blue]", border_style="blue"))
107
109
 
108
110
 
109
- def main_add_sources_to_shell_profile(profile_path: Optional[str] = None, choice: Optional[str] = None):
110
- sources: list[str] = LIBRARY_ROOT.joinpath("profile/sources.toml").readit()[system.lower()]['files']
111
+ def main_add_sources_to_shell_profile(profile_path: Optional[str], choice: Optional[str]) -> None:
112
+ # sources: list[str] = LIBRARY_ROOT.joinpath("profile/sources.toml").readit()[system.lower()]['files']
113
+ from machineconfig.utils.utils2 import read_toml
114
+ sources: list[str] = read_toml(LIBRARY_ROOT.joinpath("profile/sources.toml"))[system.lower()]['files']
111
115
 
112
116
  console.print(Panel("🔄 Adding sources to shell profile", title="[bold blue]Sources[/bold blue]", border_style="blue"))
113
117
 
@@ -124,52 +128,52 @@ def main_add_sources_to_shell_profile(profile_path: Optional[str] = None, choice
124
128
  if isinstance(profile_path, str):
125
129
  profile_path_obj = PathExtended(profile_path)
126
130
  else: profile_path_obj = get_shell_profile_path()
127
- profile = profile_path_obj.read_text()
131
+ profile = profile_path_obj.read_text(encoding="utf-8")
128
132
 
129
133
  for a_file in sources:
130
134
  tmp = a_file.replace("REPO_ROOT", REPO_ROOT.as_posix()).replace("LIBRARY_ROOT", LIBRARY_ROOT.as_posix())
131
135
  file = PathExtended(tmp).collapseuser() # this makes the shell profile interuseable across machines.
132
136
  file = file.as_posix() if system == "Linux" else str(file)
133
137
  if file not in profile:
134
- if system == "Windows":
138
+ if system == "Windows":
135
139
  profile += f"\n. {file}"
136
140
  console.print(f"➕ Added PowerShell source: {file}")
137
- elif system == "Linux":
141
+ elif system == "Linux":
138
142
  profile += f"\nsource {file}"
139
143
  console.print(f"➕ Added Bash source: {file}")
140
144
  else: raise ValueError(f"Not implemented for this system {system}")
141
- else:
145
+ else:
142
146
  console.print(f"⏭️ Source already present: {file}")
143
-
144
- profile_path_obj.write_text(profile)
147
+
148
+ profile_path_obj.write_text(profile, encoding="utf-8")
145
149
  console.print(Panel("✅ Shell profile updated with sources", title="[bold blue]Sources[/bold blue]", border_style="blue"))
146
150
 
147
151
 
148
- def main_add_patches_to_shell_profile(profile_path: Optional[str] = None, choice: Optional[str] = None):
149
- patches: list[str] = list(LIBRARY_ROOT.joinpath(f"profile/patches/{system.lower()}").search().apply(lambda x: x.as_posix()))
150
-
152
+ def main_add_patches_to_shell_profile(profile_path: Optional[str], choice: Optional[str]) -> None:
153
+ patches: list[str] = [item.as_posix() for item in LIBRARY_ROOT.joinpath(f"profile/patches/{system.lower()}").search()]
154
+
151
155
  console.print(Panel("🩹 Adding patches to shell profile", title="[bold blue]Patches[/bold blue]", border_style="blue"))
152
-
156
+
153
157
  if choice is None:
154
158
  choice_chosen = display_options(msg="Which patch to add?", options=list(patches) + ["all", "none(EXIT)"], default="none(EXIT)", multi=False)
155
159
  assert isinstance(choice_chosen, str), f"Choice must be a string or a list of strings, not {type(choice)}"
156
160
  choice = choice_chosen
157
161
  if choice == "none(EXIT)": return None
158
- elif str(choice) == "all":
162
+ elif str(choice) == "all":
159
163
  console.print("📌 Adding all patches to profile")
160
- else:
164
+ else:
161
165
  patches = [choice]
162
166
  console.print(f"📌 Adding selected patch: {choice}")
163
167
 
164
168
  profile_path_obj = PathExtended(profile_path) if isinstance(profile_path, str) else get_shell_profile_path()
165
- profile = profile_path_obj.read_text()
169
+ profile = profile_path_obj.read_text(encoding="utf-8")
166
170
 
167
171
  for patch_path in patches:
168
172
  patch_path_obj = PathExtended(patch_path)
169
- patch = patch_path_obj.read_text()
170
- if patch in profile:
173
+ patch = patch_path_obj.read_text(encoding="utf-8")
174
+ if patch in profile:
171
175
  console.print(f"⏭️ Patch already present: {patch_path_obj.name}")
172
- else:
176
+ else:
173
177
  profile += "\n" + patch
174
178
  console.print(f"➕ Added patch: {patch_path_obj.name}")
175
179
 
@@ -179,7 +183,7 @@ def main_add_patches_to_shell_profile(profile_path: Optional[str] = None, choice
179
183
  profile += "\ncd ~" # this is to make sure that the current dir is not in the windows file system, which is terribly slow and its a bad idea to be there anyway.
180
184
  console.print("📌 WSL detected - adding 'cd ~' to profile to avoid Windows filesystem")
181
185
 
182
- profile_path_obj.write_text(profile)
186
+ profile_path_obj.write_text(profile, encoding="utf-8")
183
187
  console.print(Panel("✅ Shell profile updated with patches", title="[bold blue]Patches[/bold blue]", border_style="blue"))
184
188
 
185
189
 
@@ -4,14 +4,14 @@
4
4
  # if [ -z "$VIRTUAL_ENV" ]; then
5
5
  # source ~/scripts/activate_ve ''
6
6
  # fi
7
- source ~/scripts/activate_ve ve # this script only works under ve default ve.
7
+ # source ~/scripts/activate_ve ve # this script only works under ve default ve.
8
8
 
9
9
  op_script=$HOME/tmp_results/shells/python_return_command.sh
10
10
  if [ -f "$op_script" ]; then
11
11
  rm $op_script
12
12
  fi
13
13
 
14
- python -m machineconfig.scripts.python.devops "$@"
14
+ uv run --no-dev --project ~/code/machineconfig python -m machineconfig.scripts.python.devops "$@"
15
15
  if [ -f "$op_script" ]; then
16
16
  chmod +x $op_script
17
17
  source $op_script
@@ -14,6 +14,7 @@ fi
14
14
 
15
15
  python -m machineconfig.scripts.python.fire_jobs "$@"
16
16
 
17
+
17
18
  if [ -f "$op_script" ]; then
18
19
  echo "Running $op_script"
19
20
  chmod +x $op_script
@@ -11,7 +11,6 @@ if [ -f "$op_script" ]; then
11
11
  rm $op_script
12
12
  fi
13
13
 
14
-
15
14
  python -m machineconfig.scripts.python.fire_agents "$@"
16
15
 
17
16
  if [ -f "$op_script" ]; then
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env bash
2
+
3
+ . $HOME/scripts/activate_ve 've'
4
+
5
+ # Generate random string of length 5
6
+ random_str=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 1)
7
+ export op_script=$HOME/tmp_results/shells/$random_str/python_return_command.sh
8
+ # op_script=$HOME/tmp_results/shells/$random_str/python_return_command.sh
9
+
10
+ if [ -f "$op_script" ]; then
11
+ rm $op_script
12
+ fi
13
+
14
+
15
+ python -m machineconfig.scripts.python.ai.mcinit "$@"
16
+
17
+ if [ -f "$op_script" ]; then
18
+ echo "Running $op_script"
19
+ chmod +x $op_script
20
+ set -- # clear all positional parameters
21
+ source $op_script # sourcing the script means the args passed to the this script are passed to the sourced script which cofuses the sources script as it contains activate_ve and it doesn't understand first.sh arguments.
22
+ fi
23
+
24
+
25
+ if [ -n "$VIRTUAL_ENV" ]; then
26
+ deactivate || true
27
+ fi