machineconfig 2.6__py3-none-any.whl → 2.8__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 (120) hide show
  1. machineconfig/cluster/remote/remote_machine.py +0 -1
  2. machineconfig/cluster/sessions_managers/wt_local.py +1 -1
  3. machineconfig/cluster/sessions_managers/wt_local_manager.py +1 -1
  4. machineconfig/cluster/sessions_managers/wt_remote.py +1 -1
  5. machineconfig/cluster/sessions_managers/wt_remote_manager.py +1 -1
  6. machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +1 -1
  7. machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +1 -1
  8. machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +1 -1
  9. machineconfig/cluster/sessions_managers/zellij_local.py +1 -1
  10. machineconfig/cluster/sessions_managers/zellij_local_manager.py +1 -1
  11. machineconfig/cluster/sessions_managers/zellij_remote.py +1 -1
  12. machineconfig/cluster/sessions_managers/zellij_remote_manager.py +1 -1
  13. machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +1 -1
  14. machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +1 -1
  15. machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +1 -1
  16. machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +1 -1
  17. machineconfig/jobs/__pycache__/__init__.cpython-313.pyc +0 -0
  18. machineconfig/jobs/python/check_installations.py +0 -2
  19. machineconfig/jobs/python/vscode/sync_code.py +0 -1
  20. machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  21. machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  22. machineconfig/profile/create.py +8 -16
  23. machineconfig/profile/shell.py +140 -179
  24. machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  25. machineconfig/scripts/linux/choose_wezterm_theme +1 -1
  26. machineconfig/scripts/linux/cloud_copy +1 -1
  27. machineconfig/scripts/linux/cloud_mount +1 -1
  28. machineconfig/scripts/linux/cloud_repo_sync +1 -1
  29. machineconfig/scripts/linux/cloud_sync +1 -1
  30. machineconfig/scripts/linux/croshell +2 -1
  31. machineconfig/scripts/linux/devops +1 -1
  32. machineconfig/scripts/linux/fire +1 -1
  33. machineconfig/scripts/linux/fire_agents +1 -1
  34. machineconfig/scripts/linux/ftpx +1 -1
  35. machineconfig/scripts/linux/gh_models +1 -1
  36. machineconfig/scripts/linux/kill_process +1 -1
  37. machineconfig/scripts/linux/mcinit +1 -1
  38. machineconfig/scripts/linux/mount_nfs +1 -1
  39. machineconfig/scripts/linux/mount_nw_drive +1 -11
  40. machineconfig/scripts/linux/repos +1 -1
  41. machineconfig/scripts/linux/scheduler +1 -1
  42. machineconfig/scripts/linux/start_slidev +1 -1
  43. machineconfig/scripts/linux/start_terminals +1 -1
  44. machineconfig/scripts/linux/wifi_conn +1 -1
  45. machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
  46. machineconfig/scripts/python/__pycache__/cloud_repo_sync.cpython-313.pyc +0 -0
  47. machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
  48. machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-313.pyc +0 -0
  49. machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
  50. machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-313.pyc +0 -0
  51. machineconfig/scripts/python/__pycache__/repos.cpython-313.pyc +0 -0
  52. machineconfig/scripts/python/__pycache__/repos_helper_record.cpython-313.pyc +0 -0
  53. machineconfig/scripts/python/ai/mcinit.py +16 -2
  54. machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +1 -1
  55. machineconfig/scripts/python/croshell.py +0 -1
  56. machineconfig/scripts/python/devops.py +1 -13
  57. machineconfig/scripts/python/devops_devapps_install.py +14 -2
  58. machineconfig/scripts/python/devops_update_repos.py +39 -19
  59. machineconfig/scripts/python/fire_agents.py +1 -1
  60. machineconfig/scripts/python/fire_jobs.py +8 -3
  61. machineconfig/scripts/python/fire_jobs_layout_helper.py +1 -1
  62. machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-313.pyc +0 -0
  63. machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-313.pyc +0 -0
  64. machineconfig/scripts/python/repos.py +10 -227
  65. machineconfig/scripts/python/repos_helper_record.py +270 -0
  66. machineconfig/scripts/windows/choose_wezterm_theme.ps1 +1 -1
  67. machineconfig/scripts/windows/cloud_copy.ps1 +1 -1
  68. machineconfig/scripts/windows/cloud_mount.ps1 +1 -1
  69. machineconfig/scripts/windows/cloud_repo_sync.ps1 +1 -1
  70. machineconfig/scripts/windows/cloud_sync.ps1 +1 -1
  71. machineconfig/scripts/windows/croshell.ps1 +1 -1
  72. machineconfig/scripts/windows/devops.ps1 +1 -29
  73. machineconfig/scripts/windows/dotfile.ps1 +1 -1
  74. machineconfig/scripts/windows/fire.ps1 +1 -45
  75. machineconfig/scripts/windows/ftpx.ps1 +1 -1
  76. machineconfig/scripts/windows/gpt.ps1 +1 -23
  77. machineconfig/scripts/windows/kill_process.ps1 +1 -1
  78. machineconfig/scripts/windows/mcinit.ps1 +1 -1
  79. machineconfig/scripts/windows/mount_ssh.ps1 +1 -1
  80. machineconfig/scripts/windows/pomodoro.ps1 +1 -1
  81. machineconfig/scripts/windows/repos.ps1 +1 -1
  82. machineconfig/scripts/windows/scheduler.ps1 +1 -1
  83. machineconfig/scripts/windows/snapshot.ps1 +1 -1
  84. machineconfig/scripts/windows/start_slidev.ps1 +1 -1
  85. machineconfig/scripts/windows/start_terminals.ps1 +1 -1
  86. machineconfig/scripts/windows/wifi_conn.ps1 +1 -2
  87. machineconfig/settings/shells/pwsh/init.ps1 +0 -4
  88. machineconfig/setup_linux/web_shortcuts/croshell.sh +1 -1
  89. machineconfig/setup_linux/web_shortcuts/interactive.sh +7 -13
  90. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +9 -18
  91. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +1 -66
  92. machineconfig/utils/links.py +1 -2
  93. machineconfig/utils/options.py +8 -5
  94. machineconfig/utils/procs.py +50 -31
  95. machineconfig/utils/scheduling.py +0 -1
  96. machineconfig/{cluster/sessions_managers → utils/schemas/layouts}/layout_types.py +0 -1
  97. machineconfig/utils/schemas/repos/repos_types.py +28 -0
  98. machineconfig/utils/source_of_truth.py +1 -4
  99. machineconfig/utils/ssh.py +30 -8
  100. {machineconfig-2.6.dist-info → machineconfig-2.8.dist-info}/METADATA +1 -2
  101. {machineconfig-2.6.dist-info → machineconfig-2.8.dist-info}/RECORD +105 -112
  102. {machineconfig-2.6.dist-info → machineconfig-2.8.dist-info}/entry_points.txt +1 -1
  103. machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-313.pyc +0 -0
  104. machineconfig/profile/create_hardlinks.py +0 -140
  105. machineconfig/scripts/linux/checkout_versions +0 -2
  106. machineconfig/scripts/linux/cloud_manager +0 -2
  107. machineconfig/scripts/linux/url2md +0 -2
  108. machineconfig/scripts/python/__pycache__/croshell.cpython-313.pyc +0 -0
  109. machineconfig/scripts/windows/checkout_version.ps1 +0 -1
  110. machineconfig/scripts/windows/cloud_manager.ps1 +0 -1
  111. machineconfig/scripts/windows/neofetch.ps1 +0 -2
  112. machineconfig/scripts/windows/wsl_windows_transfer.ps1 +0 -1
  113. machineconfig/settings/__pycache__/__init__.cpython-313.pyc +0 -0
  114. machineconfig/settings/shells/ipy/profiles/default/__pycache__/__init__.cpython-313.pyc +0 -0
  115. machineconfig/settings/shells/ipy/profiles/default/startup/__pycache__/__init__.cpython-313.pyc +0 -0
  116. machineconfig/utils/ai/browser_user_wrapper.py +0 -66
  117. machineconfig/utils/ai/url2md.py +0 -85
  118. /machineconfig/setup_windows/wt_and_pwsh/{set_pwsh_theme.py → install_nerd_fonts.py} +0 -0
  119. {machineconfig-2.6.dist-info → machineconfig-2.8.dist-info}/WHEEL +0 -0
  120. {machineconfig-2.6.dist-info → machineconfig-2.8.dist-info}/top_level.txt +0 -0
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -m machineconfig.scripts.python.cloud_copy "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig cloud_copy "$@"
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -m machineconfig.scripts.python.cloud_mount "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig cloud_mount "$@"
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python $(dirname $(dirname $0))/python/cloud_repo_sync.py "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig cloud_repo_sync "$@"
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -m machineconfig.scripts.python.cloud_sync "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig cloud_sync
@@ -1,2 +1,3 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -m machineconfig.scripts.python.croshell "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig croshell "$@"
3
+
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig devops
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig devops
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig fire "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig fire "$@"
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -m machineconfig.scripts.python.fire_agents "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig fire_agents "$@"
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python $(dirname $(dirname $0))/python/ftpx.py "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig ftpx "$@"
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -m machineconfig.scripts.python.gh_models "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig gh_models "$@"
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -c "from machineconfig.utils.procs import ProcessManager; ProcessManager().choose_and_kill()"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig kill_process "$@"
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -m machineconfig.scripts.python.ai.mcinit "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig mcinit "$@"
@@ -5,7 +5,7 @@
5
5
  # mkdir ~/data/local
6
6
  # sudo mount -o nolock,noatime,nodiratime,proto=tcp,timeo=600,retrans=2,noac alex-p51s-5:/home/alex/data/local ./data/local
7
7
 
8
- uv run --python 3.13 --with machineconfig python -m machineconfig.scripts.python.mount_nfs
8
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig python -m machineconfig.scripts.python.mount_nfs
9
9
  # Check if remote server is reachable and share folder exists
10
10
  if ! ping -c 1 "$remote_server" &> /dev/null; then
11
11
  echo "💥 Error: Remote server $remote_server is not reachable."
@@ -18,17 +18,7 @@ mount_point=''
18
18
  username=''
19
19
  password=''
20
20
 
21
- op_script=$HOME/tmp_results/shells/python_return_command.sh
22
- if [ -f "$op_script" ]; then
23
- rm $op_script
24
- fi
25
- . activate_ve
26
- python -m machineconfig.scripts.python.mount_nw_drive
27
- #source $HOME/tmp_results/shells/python_return_command.sh
28
- if [ -f "$op_script" ]; then
29
- chmod +x $op_script
30
- source $op_script
31
- fi
21
+ uv run --PYTHON 3.13 --no-dev --project $HOME/code/machineconfig python -m machineconfig.scripts.python.mount_nw_drive
32
22
 
33
23
  # Check if mount point directory exists, create if not
34
24
  if [ ! -d "$mount_point" ]; then
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -m machineconfig.scripts.python.repos "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig repos "$@"
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -m machineconfig.scripts.python.scheduler "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig scheduler "$@"
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -m machineconfig.scripts.python.start_slidev "$@"
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig start_slidev "$@"
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python -m machineconfig.jobs.python.create_zellij_template
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig create_zellij_template
3
3
  zellij --layout $HOME/tmp_results/tmp_files/templates/zellij_template.kdl
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env bash
2
- uv run --python 3.13 --with machineconfig python machineconfig.scripts.python.wifi_conn
2
+ uv run --python 3.13 --no-dev --project $HOME/code/machineconfig wifi_conn
@@ -21,8 +21,7 @@ def get_repo_root(path: Path) -> Optional[Path]:
21
21
  return None
22
22
 
23
23
 
24
- def add_ai_configs():
25
- repo_root: Path = Path.cwd()
24
+ def add_ai_configs(repo_root: Path) -> None:
26
25
  import machineconfig as mc
27
26
 
28
27
  mc_root = Path(mc.__file__).parent
@@ -107,5 +106,20 @@ uv venv
107
106
  dot_git_ignore_path.write_text(data=dot_git_ignore_content + "\n" + "\n".join(to_add), encoding="utf-8")
108
107
 
109
108
 
109
+ def main() -> None:
110
+ # import argparse
111
+
112
+ # parser = argparse.ArgumentParser(description="Add AI configurations to a Python project.")
113
+ # parser.add_argument(
114
+ # "--repo-root",
115
+ # type=str,
116
+ # default=".",
117
+ # help="Path to the root of the repository. Defaults to the current working directory.",
118
+ # )
119
+ # args = parser.parse_args()
120
+ # repo_root = Path(args.repo_root).resolve()
121
+ repo_root = Path.cwd()
122
+ add_ai_configs(repo_root=repo_root)
123
+
110
124
  if __name__ == "__main__":
111
125
  add_ai_configs(repo_root=Path.cwd())
@@ -24,7 +24,7 @@ uv run -m cleanpy .
24
24
  uv run -m ruff clean
25
25
  # uv run -m ruff format .
26
26
  uv run -m ruff check . --fix
27
- uv run --with machineconfig -m machineconfig.scripts.python.ai.generate_files
27
+ uv run --no-dev --project $HOME/code/machineconfig -m machineconfig.scripts.python.ai.generate_files
28
28
 
29
29
  mkdir .linters
30
30
 
@@ -140,7 +140,6 @@ def build_parser():
140
140
  # py_file_path = run(data_path=args.read, data=None, get_figure=None)
141
141
  # final_program = f"""
142
142
  # #!/bin/bash
143
- # . $HOME/scripts/activate_ve '.venv'
144
143
  # streamlit run {py_file_path}
145
144
  # """
146
145
  # PROGRAM_PATH.write_text(data=final_program, encoding="utf-8")
@@ -18,14 +18,13 @@ BOX_WIDTH = 150 # width for box drawing
18
18
  class Options(Enum):
19
19
  update = "🔄 UPDATE essential repos"
20
20
  cli_install = "⚙️ DEVAPPS install"
21
- sym_path_shell = "🔗 SYMLINKS, PATH & SHELL PROFILE"
21
+ sym_path_shell = "🔗 SYMLINKS, SHELL PROFILE, FONT, TERMINAL SETTINGS."
22
22
  sym_new = "🆕 SYMLINKS new"
23
23
  ssh_add_pubkey = "🔑 SSH add pub key to this machine"
24
24
  ssh_add_id = "🗝️ SSH add identity (private key) to this machine"
25
25
  ssh_use_pair = "🔐 SSH use key pair to connect two machines"
26
26
  ssh_setup = "📡 SSH setup"
27
27
  ssh_setup_wsl = "🐧 SSH setup wsl"
28
- dot_files_sync = "🔗 DOTFILES sync"
29
28
  backup = "💾 BACKUP"
30
29
  retreive = "📥 RETRIEVE"
31
30
  scheduler = "⏰ SCHEDULER"
@@ -73,11 +72,8 @@ def display_task_success(success: str) -> None:
73
72
 
74
73
 
75
74
  def main(which: Optional[str] = None):
76
- from machineconfig.utils.path_reduced import PathExtended
77
-
78
75
  # PathExtended(PROGRAM_PATH).delete(sure=True, verbose=False)
79
76
  console.print(Panel("🚀 Initializing DevOps operation...", width=BOX_WIDTH, border_style="blue"))
80
-
81
77
  options = [op.value for op in Options]
82
78
  if which is None:
83
79
  try:
@@ -93,9 +89,7 @@ def main(which: Optional[str] = None):
93
89
  if choice_key == Options.update.value:
94
90
  console.print(Panel("🔄 Updating essential repositories...", width=BOX_WIDTH, border_style="blue"))
95
91
  import machineconfig.scripts.python.devops_update_repos as helper
96
-
97
92
  program = helper.main()
98
-
99
93
  elif choice_key == Options.cli_install.value:
100
94
  console.print(Panel("⚙️ Installing development applications...", width=BOX_WIDTH, border_style="blue"))
101
95
  import machineconfig.scripts.python.devops_devapps_install as helper
@@ -159,12 +153,6 @@ def main(which: Optional[str] = None):
159
153
  # program = helper()
160
154
  program = ""
161
155
 
162
- elif choice_key == Options.dot_files_sync.value:
163
- console.print(Panel("🔗 Synchronizing dotfiles...", width=BOX_WIDTH, border_style="blue"))
164
- from machineconfig.scripts.python.cloud_repo_sync import main as helper, PathExtended
165
-
166
- program = helper(cloud=None, path=str(PathExtended.home() / "dotfiles"), pwd=None, action="ask")
167
-
168
156
  else:
169
157
  console.print(Panel("❌ ERROR: Invalid choice", title_align="left", border_style="red", width=BOX_WIDTH))
170
158
  raise ValueError(f"Unimplemented choice: {choice_key}")
@@ -2,7 +2,7 @@
2
2
 
3
3
  # import subprocess
4
4
  from machineconfig.utils.installer_utils.installer_class import Installer
5
- from tqdm import tqdm
5
+ from rich.progress import Progress, SpinnerColumn, TextColumn
6
6
  from machineconfig.utils.source_of_truth import LIBRARY_ROOT
7
7
  from machineconfig.utils.options import choose_multiple_options
8
8
  from machineconfig.utils.installer import get_installers, install_all, get_all_dicts
@@ -38,7 +38,19 @@ def main(which: Optional[WHICH_CAT | str] = None):
38
38
 
39
39
  # interactive installation
40
40
  installers = [Installer.from_dict(d=vd, name=name) for __kat, vds in get_all_dicts(system=system()).items() for name, vd in vds.items()]
41
- options = [x.get_description() for x in tqdm(installers, desc="✅ Checking installed programs")] + list(get_args(WHICH_CAT))
41
+
42
+ # Check installed programs with progress indicator
43
+ with Progress(
44
+ SpinnerColumn(),
45
+ TextColumn("[progress.description]{task.description}"),
46
+ ) as progress:
47
+ task = progress.add_task("✅ Checking installed programs...", total=len(installers))
48
+ options = []
49
+ for x in installers:
50
+ options.append(x.get_description())
51
+ progress.update(task, advance=1)
52
+
53
+ options += list(get_args(WHICH_CAT))
42
54
  # print("s"*1000)
43
55
  program_names = choose_multiple_options(msg="", options=options, header="🚀 CHOOSE DEV APP", default="AllEssentials")
44
56
 
@@ -20,7 +20,6 @@ def set_permissions_recursive(path: Path, executable: bool = True) -> None:
20
20
  """Set permissions recursively for a directory."""
21
21
  if not path.exists():
22
22
  return
23
-
24
23
  if path.is_file():
25
24
  if executable:
26
25
  path.chmod(0o755)
@@ -36,26 +35,50 @@ def run_uv_sync(repo_path: Path) -> bool:
36
35
  """Run uv sync in the given repository path. Returns True if successful."""
37
36
  try:
38
37
  print(f"🔄 Running uv sync in {repo_path}")
39
- result = subprocess.run(["uv", "sync"], cwd=repo_path, capture_output=True, text=True, check=True)
38
+ # Run uv sync with output directly to terminal (no capture)
39
+ subprocess.run(["uv", "sync"], cwd=repo_path, check=True)
40
40
  print("✅ uv sync completed successfully")
41
- if result.stdout:
42
- print(f"📝 Output: {result.stdout}")
43
41
  return True
44
42
  except subprocess.CalledProcessError as e:
45
- print(f"❌ uv sync failed: {e}")
46
- if e.stderr:
47
- print(f"📝 Error: {e.stderr}")
43
+ print(f"❌ uv sync failed with return code {e.returncode}")
48
44
  return False
49
45
  except FileNotFoundError:
50
46
  print("⚠️ uv command not found. Please install uv first.")
51
47
  return False
52
48
 
53
49
 
54
- def update_repository(repo: git.Repo, auto_sync: bool = True, allow_password_prompt: bool = False) -> bool:
50
+ def update_repository(repo: git.Repo, auto_sync: bool, allow_password_prompt: bool) -> bool:
55
51
  """Update a single repository and return True if pyproject.toml or uv.lock changed."""
56
52
  repo_path = Path(repo.working_dir)
57
53
  print(f"🔄 {'Updating ' + str(repo_path):.^80}")
58
54
 
55
+ # Check git status first
56
+ print("📊 Checking git status...")
57
+ if repo.is_dirty():
58
+ # Get the list of modified files
59
+ changed_files_raw = [item.a_path for item in repo.index.diff(None)]
60
+ changed_files_raw.extend([item.a_path for item in repo.index.diff("HEAD")])
61
+ # Filter out None values and remove duplicates
62
+ changed_files = list(set(file for file in changed_files_raw if file is not None))
63
+
64
+ print(f"⚠️ Repository has uncommitted changes: {', '.join(changed_files)}")
65
+
66
+ # Check if the only change is uv.lock
67
+ if len(changed_files) == 1 and changed_files[0] == "uv.lock":
68
+ print("🔒 Only uv.lock has changes, resetting it...")
69
+ try:
70
+ # Reset uv.lock file
71
+ subprocess.run(["git", "checkout", "HEAD", "--", "uv.lock"], cwd=repo_path, check=True)
72
+ print("✅ uv.lock has been reset")
73
+ except subprocess.CalledProcessError as e:
74
+ print(f"❌ Failed to reset uv.lock: {e}")
75
+ return False
76
+ else:
77
+ # Multiple files or files other than uv.lock have changes
78
+ raise RuntimeError(f"❌ Cannot update repository - there are pending changes in: {', '.join(changed_files)}. Please commit or stash your changes first.")
79
+ else:
80
+ print("✅ Repository is clean")
81
+
59
82
  # Check if this repo has pyproject.toml or uv.lock
60
83
  pyproject_path = repo_path / "pyproject.toml"
61
84
  uv_lock_path = repo_path / "uv.lock"
@@ -210,12 +233,15 @@ def update_repository(repo: git.Repo, auto_sync: bool = True, allow_password_pro
210
233
  def main(verbose: bool = True, allow_password_prompt: bool = False) -> str:
211
234
  """Main function to update all configured repositories."""
212
235
  _ = verbose
213
- repos: list[str] = ["~/code/machineconfig", "~/code/crocodile"]
236
+ repos: list[PathExtended] = [PathExtended.home() / "code/machineconfig", PathExtended.home() / "code/crocodile"]
214
237
  try:
215
238
  tmp = read_ini(DEFAULTS_PATH)["general"]["repos"].split(",")
216
239
  if tmp[-1] == "":
217
240
  tmp = tmp[:-1]
218
- repos += tmp
241
+ for item in tmp:
242
+ item_obj = PathExtended(item).expanduser()
243
+ if item_obj not in repos:
244
+ repos.append(item_obj)
219
245
  except (FileNotFoundError, KeyError, IndexError):
220
246
  print(f"""
221
247
  ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -235,26 +261,20 @@ def main(verbose: bool = True, allow_password_prompt: bool = False) -> str:
235
261
 
236
262
  # Process repositories
237
263
  repos_with_changes = []
238
- for a_package_path in repos:
264
+ for expanded_path in repos:
239
265
  try:
240
- expanded_path = PathExtended(a_package_path).expanduser()
241
266
  repo = git.Repo(str(expanded_path), search_parent_directories=True)
242
-
243
267
  # Update repository and check if dependencies changed
244
- dependencies_changed = update_repository(repo, allow_password_prompt=allow_password_prompt)
245
-
268
+ dependencies_changed = update_repository(repo, allow_password_prompt=allow_password_prompt, auto_sync=True)
246
269
  if dependencies_changed:
247
270
  repos_with_changes.append(Path(repo.working_dir))
248
-
249
271
  except Exception as ex:
250
- print(f"""❌ Repository Error: Path: {a_package_path}
272
+ print(f"""❌ Repository Error: Path: {expanded_path}
251
273
  Exception: {ex}
252
274
  {"-" * 50}""")
253
-
254
275
  # Run uv sync for repositories where pyproject.toml or uv.lock changed
255
276
  for repo_path in repos_with_changes:
256
277
  run_uv_sync(repo_path)
257
-
258
278
  # print("\n🎉 All repositories updated successfully!")
259
279
  return """echo "🎉 All repositories updated successfully!" """
260
280
 
@@ -15,7 +15,7 @@ from math import ceil
15
15
  from typing import Literal, TypeAlias, get_args, Iterable
16
16
 
17
17
  from machineconfig.cluster.sessions_managers.zellij_local_manager import ZellijLocalManager
18
- from machineconfig.cluster.sessions_managers.layout_types import TabConfig, LayoutConfig
18
+ from machineconfig.utils.schemas.layouts.layout_types import TabConfig, LayoutConfig
19
19
  from machineconfig.utils.utils2 import randstr
20
20
  import random
21
21
  # import time
@@ -24,7 +24,7 @@ from typing import Optional
24
24
  # import os
25
25
 
26
26
 
27
- def main(args: FireJobArgs) -> None:
27
+ def route(args: FireJobArgs) -> None:
28
28
  if args.layout:
29
29
  from machineconfig.scripts.python.fire_jobs_layout_helper import handle_layout_args
30
30
 
@@ -257,7 +257,7 @@ python -m machineconfig.cluster.templates.cli_click --file {choice_file} """
257
257
 
258
258
  if args.Nprocess > 1:
259
259
  from machineconfig.cluster.sessions_managers.zellij_local import run_zellij_layout
260
- from machineconfig.cluster.sessions_managers.layout_types import LayoutConfig
260
+ from machineconfig.utils.schemas.layouts.layout_types import LayoutConfig
261
261
 
262
262
  layout: LayoutConfig = {"layoutName": "fireNprocess", "layoutTabs": []}
263
263
  for an_arg in range(args.Nprocess):
@@ -326,7 +326,12 @@ python -m machineconfig.cluster.templates.cli_click --file {choice_file} """
326
326
  subprocess.run(command, shell=True, check=True)
327
327
 
328
328
 
329
+ def main():
330
+ args = get_args()
331
+ route(args)
332
+
333
+
329
334
  if __name__ == "__main__":
330
335
  # options, func_args = parse_pyfile(file_path="C:/Users/aalsaf01/code/machineconfig/myresources/crocodile/core.py")
331
336
  args = get_args()
332
- main(args)
337
+ route(args)
@@ -1,5 +1,5 @@
1
1
  from pathlib import Path
2
- from machineconfig.cluster.sessions_managers.layout_types import LayoutConfig, LayoutsFile
2
+ from machineconfig.utils.schemas.layouts.layout_types import LayoutConfig, LayoutsFile
3
3
  from typing import Optional, TYPE_CHECKING
4
4
  from machineconfig.scripts.python.helpers.helpers4 import search_for_files_of_interest
5
5
  from machineconfig.utils.options import choose_one_option