machineconfig 3.3__py3-none-any.whl → 3.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/sessions_managers/wt_local_manager.py +1 -1
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +1 -1
- machineconfig/cluster/templates/utils.py +1 -1
- machineconfig/jobs/linux/msc/cli_agents.sh +18 -2
- machineconfig/jobs/python/python_ve_symlink.py +1 -1
- machineconfig/jobs/python/vscode/api.py +1 -1
- machineconfig/jobs/python/vscode/select_interpreter.py +2 -2
- machineconfig/jobs/python/vscode/sync_code.py +1 -1
- machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +1 -1
- machineconfig/jobs/python_custom_installers/dev/espanso.py +1 -1
- machineconfig/jobs/python_custom_installers/hx.py +1 -1
- machineconfig/jobs/python_generic_installers/config.json +0 -11
- machineconfig/profile/create.py +3 -3
- machineconfig/profile/shell.py +1 -1
- machineconfig/scripts/python/ai/mcinit.py +23 -67
- machineconfig/scripts/python/ai/solutions/__init__.py +0 -0
- machineconfig/scripts/python/ai/solutions/_shared.py +5 -0
- machineconfig/scripts/python/ai/solutions/claude/claude.py +8 -0
- machineconfig/scripts/python/ai/solutions/cline/cline.py +10 -0
- machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +35 -0
- machineconfig/scripts/python/ai/solutions/copilot/privacy.md +4 -0
- machineconfig/scripts/python/ai/solutions/crush/crush.json +216 -0
- machineconfig/scripts/python/ai/solutions/crush/crush.py +25 -0
- machineconfig/scripts/python/ai/solutions/crush/privacy.md +2 -0
- machineconfig/scripts/python/ai/solutions/cursor/cursors.py +10 -0
- machineconfig/scripts/python/ai/solutions/gemini/gemini.py +14 -0
- machineconfig/scripts/python/ai/solutions/generic.py +41 -0
- machineconfig/scripts/python/ai/solutions/kilocode/privacy.md +3 -0
- machineconfig/scripts/python/ai/solutions/opencode/opencode.json +4 -0
- machineconfig/scripts/python/ai/solutions/opencode/opencode.py +1 -0
- machineconfig/scripts/python/choose_wezterm_theme.py +1 -1
- machineconfig/scripts/python/cloud_copy.py +2 -2
- machineconfig/scripts/python/cloud_mount.py +2 -2
- machineconfig/scripts/python/cloud_repo_sync.py +3 -2
- machineconfig/scripts/python/croshell.py +12 -7
- machineconfig/scripts/python/devops_add_identity.py +1 -1
- machineconfig/scripts/python/devops_add_ssh_key.py +1 -1
- machineconfig/scripts/python/devops_backup_retrieve.py +4 -3
- machineconfig/scripts/python/devops_update_repos.py +2 -2
- machineconfig/scripts/python/dotfile.py +1 -1
- machineconfig/scripts/python/fire_agents.py +3 -3
- machineconfig/scripts/python/fire_agents_help_launch.py +2 -2
- machineconfig/scripts/python/fire_jobs.py +8 -8
- machineconfig/scripts/python/fire_jobs_layout_helper.py +2 -2
- machineconfig/scripts/python/ftpx.py +2 -2
- machineconfig/scripts/python/helpers/cloud_helpers.py +2 -1
- machineconfig/scripts/python/helpers/helpers2.py +4 -3
- machineconfig/scripts/python/helpers/helpers4.py +1 -1
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +2 -2
- machineconfig/scripts/python/mount_nfs.py +1 -1
- machineconfig/scripts/python/mount_ssh.py +1 -1
- machineconfig/scripts/python/repos.py +6 -3
- machineconfig/scripts/python/repos_helper_clone.py +121 -0
- machineconfig/scripts/python/repos_helper_record.py +2 -2
- machineconfig/scripts/python/start_slidev.py +1 -1
- machineconfig/scripts/python/wsl_windows_transfer.py +1 -1
- machineconfig/setup_windows/wt_and_pwsh/install_nerd_fonts.py +1 -1
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +3 -3
- machineconfig/utils/{utils2.py → accessories.py} +13 -29
- machineconfig/utils/code.py +2 -2
- machineconfig/utils/installer.py +2 -2
- machineconfig/utils/installer_utils/installer_abc.py +1 -1
- machineconfig/utils/installer_utils/installer_class.py +2 -2
- machineconfig/utils/io.py +94 -0
- machineconfig/utils/links.py +2 -2
- machineconfig/utils/notifications.py +0 -9
- machineconfig/utils/{path_reduced.py → path_extended.py} +1 -1
- machineconfig/utils/{path.py → path_helper.py} +1 -1
- machineconfig/utils/procs.py +1 -1
- machineconfig/utils/{utils5.py → scheduler.py} +3 -8
- machineconfig/utils/ssh.py +2 -2
- machineconfig/utils/terminal.py +12 -2
- machineconfig/utils/ve.py +2 -16
- {machineconfig-3.3.dist-info → machineconfig-3.5.dist-info}/METADATA +1 -4
- {machineconfig-3.3.dist-info → machineconfig-3.5.dist-info}/RECORD +87 -71
- machineconfig/utils/io_save.py +0 -95
- /machineconfig/scripts/python/ai/{chatmodes → solutions/copilot/chatmodes}/Thinking-Beast-Mode.chatmode.md +0 -0
- /machineconfig/scripts/python/ai/{chatmodes → solutions/copilot/chatmodes}/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +0 -0
- /machineconfig/scripts/python/ai/{chatmodes → solutions/copilot/chatmodes}/deepResearch.chatmode.md +0 -0
- /machineconfig/scripts/python/ai/{instructions → solutions/copilot/instructions}/python/dev.instructions.md +0 -0
- /machineconfig/scripts/python/ai/{prompts → solutions/copilot/prompts}/allLintersAndTypeCheckers.prompt.md +0 -0
- /machineconfig/scripts/python/ai/{prompts → solutions/copilot/prompts}/research-report-skeleton.prompt.md +0 -0
- /machineconfig/scripts/python/ai/{configs/.gemini → solutions/gemini}/settings.json +0 -0
- {machineconfig-3.3.dist-info → machineconfig-3.5.dist-info}/WHEEL +0 -0
- {machineconfig-3.3.dist-info → machineconfig-3.5.dist-info}/entry_points.txt +0 -0
- {machineconfig-3.3.dist-info → machineconfig-3.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from machineconfig.scripts.python.ai.solutions._shared import get_generic_instructions_path
|
|
4
|
+
from machineconfig.utils.source_of_truth import LIBRARY_ROOT
|
|
5
|
+
|
|
6
|
+
def build_configuration(repo_root: Path) -> None:
|
|
7
|
+
instructions_path = get_generic_instructions_path()
|
|
8
|
+
repo_root.joinpath("GEMINI.md").write_text(data=instructions_path.read_text(encoding="utf-8"), encoding="utf-8")
|
|
9
|
+
|
|
10
|
+
gemini_dir = repo_root.joinpath(".gemini")
|
|
11
|
+
settings_source_path = LIBRARY_ROOT.joinpath("scripts/python/ai/solutions/gemini/settings.json")
|
|
12
|
+
gemini_dir.mkdir(parents=True, exist_ok=True)
|
|
13
|
+
|
|
14
|
+
settings_source_path.write_text(data=settings_source_path.read_text(encoding="utf-8"), encoding="utf-8")
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from machineconfig.utils.source_of_truth import LIBRARY_ROOT
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def create_dot_scripts(repo_root: Path) -> None:
|
|
7
|
+
scripts_dir = LIBRARY_ROOT.joinpath("scripts/python/ai/scripts")
|
|
8
|
+
target_dir = repo_root.joinpath(".scripts")
|
|
9
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
|
10
|
+
for script_path in scripts_dir.iterdir():
|
|
11
|
+
target_dir.joinpath(script_path.name).write_text(data=script_path.read_text(encoding="utf-8"), encoding="utf-8")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def adjust_gitignore(repo_root: Path) -> None:
|
|
15
|
+
dot_git_ignore_path = repo_root.joinpath(".gitignore")
|
|
16
|
+
if dot_git_ignore_path.exists() is False:
|
|
17
|
+
return
|
|
18
|
+
|
|
19
|
+
dot_git_ignore_content = dot_git_ignore_path.read_text(encoding="utf-8")
|
|
20
|
+
entries_to_add: list[str] = []
|
|
21
|
+
required_entries: list[str] = [
|
|
22
|
+
".links",
|
|
23
|
+
"notebooks",
|
|
24
|
+
".ai",
|
|
25
|
+
".scripts",
|
|
26
|
+
"GEMINI.md",
|
|
27
|
+
"CLAUDE.md",
|
|
28
|
+
".cursor",
|
|
29
|
+
".github/instructions",
|
|
30
|
+
".github/chatmodes",
|
|
31
|
+
".github/prompts",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
for entry in required_entries:
|
|
35
|
+
if entry not in dot_git_ignore_content:
|
|
36
|
+
entries_to_add.append(entry)
|
|
37
|
+
|
|
38
|
+
if len(entries_to_add) == 0:
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
dot_git_ignore_path.write_text(data=dot_git_ignore_content + "\n" + "\n".join(entries_to_add), encoding="utf-8")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -3,7 +3,7 @@ Choose a theme for Wezterm
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from machineconfig.utils.options import choose_one_option
|
|
6
|
-
from machineconfig.utils.
|
|
6
|
+
from machineconfig.utils.path_extended import PathExtended
|
|
7
7
|
from typing import Any
|
|
8
8
|
import time
|
|
9
9
|
from rich.panel import Panel
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
CC
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from machineconfig.utils.
|
|
5
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
6
6
|
from tenacity import retry, stop_after_attempt, wait_chain, wait_fixed
|
|
7
7
|
import getpass
|
|
8
8
|
import argparse
|
|
@@ -14,7 +14,7 @@ from machineconfig.scripts.python.helpers.cloud_helpers import ArgsDefaults, Arg
|
|
|
14
14
|
from rich.console import Console
|
|
15
15
|
from rich.panel import Panel
|
|
16
16
|
from rich.progress import Progress
|
|
17
|
-
from machineconfig.utils.
|
|
17
|
+
from machineconfig.utils.accessories import pprint
|
|
18
18
|
|
|
19
19
|
console = Console()
|
|
20
20
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"""Cloud mount script"""
|
|
2
2
|
|
|
3
3
|
from machineconfig.utils.options import choose_one_option
|
|
4
|
-
from machineconfig.utils.
|
|
5
|
-
from machineconfig.utils.
|
|
4
|
+
from machineconfig.utils.io import read_ini
|
|
5
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
6
6
|
|
|
7
7
|
import platform
|
|
8
8
|
import argparse
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
import git
|
|
5
|
-
from machineconfig.utils.
|
|
5
|
+
from machineconfig.utils.io import read_ini
|
|
6
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
6
7
|
from machineconfig.utils.terminal import Terminal
|
|
7
|
-
from machineconfig.utils.
|
|
8
|
+
from machineconfig.utils.accessories import randstr
|
|
8
9
|
|
|
9
10
|
from machineconfig.scripts.python.helpers.repo_sync_helpers import fetch_dotfiles
|
|
10
11
|
from machineconfig.utils.source_of_truth import CONFIG_PATH, DEFAULTS_PATH
|
|
@@ -5,8 +5,8 @@ croshell
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import argparse
|
|
8
|
-
from machineconfig.utils.
|
|
9
|
-
from machineconfig.utils.
|
|
8
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
9
|
+
from machineconfig.utils.accessories import randstr
|
|
10
10
|
|
|
11
11
|
from machineconfig.utils.options import display_options
|
|
12
12
|
from machineconfig.utils.ve import get_ve_activate_line
|
|
@@ -21,8 +21,10 @@ console = Console()
|
|
|
21
21
|
|
|
22
22
|
def add_print_header_pycode(path: str, title: str):
|
|
23
23
|
return f"""
|
|
24
|
-
|
|
25
|
-
from crocodile.file_management import P as PathExtended
|
|
24
|
+
try:
|
|
25
|
+
from crocodile.file_management import P as PathExtended
|
|
26
|
+
except ImportError:
|
|
27
|
+
from machineconfig.utils.path_reduced import PathExtended
|
|
26
28
|
pycode = PathExtended(r'{path}').read_text(encoding="utf-8")
|
|
27
29
|
pycode = pycode.split("except Exception: print(pycode)")[2]
|
|
28
30
|
|
|
@@ -160,10 +162,13 @@ def build_parser():
|
|
|
160
162
|
preprogram = """
|
|
161
163
|
|
|
162
164
|
#%%
|
|
163
|
-
|
|
165
|
+
try:
|
|
166
|
+
from crocodile.croshell import *
|
|
167
|
+
print_header()
|
|
168
|
+
print_logo(logo="crocodile")
|
|
169
|
+
except ImportError:
|
|
170
|
+
print("Crocodile not found, skipping import.")
|
|
164
171
|
from pathlib import Path
|
|
165
|
-
print_header()
|
|
166
|
-
print_logo(logo="crocodile")
|
|
167
172
|
print(f"🐊 Crocodile Shell | Running @ {Path.cwd()}")
|
|
168
173
|
"""
|
|
169
174
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""ID"""
|
|
2
2
|
|
|
3
3
|
# from platform import system
|
|
4
|
-
from machineconfig.utils.
|
|
4
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
5
5
|
from machineconfig.utils.options import display_options
|
|
6
6
|
from rich.panel import Panel
|
|
7
7
|
from rich.text import Text
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from platform import system
|
|
4
4
|
from machineconfig.utils.source_of_truth import LIBRARY_ROOT
|
|
5
5
|
from machineconfig.utils.options import display_options
|
|
6
|
-
from machineconfig.utils.
|
|
6
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
7
7
|
from rich.console import Console
|
|
8
8
|
from rich.panel import Panel
|
|
9
9
|
from rich import box # Import box
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"""BR: Backup and Retrieve"""
|
|
2
2
|
|
|
3
3
|
# import subprocess
|
|
4
|
-
from machineconfig.utils.
|
|
5
|
-
from machineconfig.utils.
|
|
4
|
+
from machineconfig.utils.io import read_ini
|
|
5
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
6
6
|
from machineconfig.utils.source_of_truth import LIBRARY_ROOT, DEFAULTS_PATH
|
|
7
7
|
from machineconfig.utils.code import print_code
|
|
8
8
|
from machineconfig.utils.options import choose_cloud_interactively, choose_multiple_options
|
|
@@ -11,6 +11,7 @@ from platform import system
|
|
|
11
11
|
from typing import Any, Literal, Optional
|
|
12
12
|
from rich.console import Console
|
|
13
13
|
from rich.panel import Panel
|
|
14
|
+
import tomllib
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
OPTIONS = Literal["BACKUP", "RETRIEVE"]
|
|
@@ -26,7 +27,7 @@ def main_backup_retrieve(direction: OPTIONS, which: Optional[str] = None) -> Non
|
|
|
26
27
|
console.print(Panel("🔍 DEFAULT CLOUD NOT FOUND\n🔄 Please select a cloud configuration from the options below", title="[bold red]Error: Cloud Not Found[/bold red]", border_style="red"))
|
|
27
28
|
cloud = choose_cloud_interactively()
|
|
28
29
|
|
|
29
|
-
bu_file: dict[str, Any] =
|
|
30
|
+
bu_file: dict[str, Any] = tomllib.loads(LIBRARY_ROOT.joinpath("profile/backup.toml").read_text(encoding="utf-8"))
|
|
30
31
|
|
|
31
32
|
console.print(Panel(f"🧰 LOADING BACKUP CONFIGURATION\n📄 File: {LIBRARY_ROOT.joinpath('profile/backup.toml')}", title="[bold blue]Backup Configuration[/bold blue]", border_style="blue"))
|
|
32
33
|
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
import git
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from machineconfig.scripts.python.repos_helper_update import RepositoryUpdateResult, run_uv_sync, update_repository
|
|
6
|
-
from machineconfig.utils.
|
|
6
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
7
7
|
from machineconfig.utils.source_of_truth import DEFAULTS_PATH
|
|
8
|
-
from machineconfig.utils.
|
|
8
|
+
from machineconfig.utils.io import read_ini
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def _display_summary(results: list[RepositoryUpdateResult]) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Like yadm and dotter."""
|
|
2
2
|
|
|
3
|
-
from machineconfig.utils.
|
|
3
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
4
4
|
from machineconfig.utils.links import symlink_func
|
|
5
5
|
from machineconfig.utils.source_of_truth import LIBRARY_ROOT, REPO_ROOT
|
|
6
6
|
import argparse
|
|
@@ -17,7 +17,7 @@ from machineconfig.scripts.python.fire_agents_help_search import search_files_by
|
|
|
17
17
|
from machineconfig.scripts.python.fire_agents_load_balancer import chunk_prompts, SPLITTING_STRATEGY, DEFAULT_AGENT_CAP
|
|
18
18
|
from machineconfig.utils.options import choose_one_option
|
|
19
19
|
from machineconfig.utils.schemas.layouts.layout_types import TabConfig, LayoutConfig
|
|
20
|
-
from machineconfig.utils.
|
|
20
|
+
from machineconfig.utils.accessories import get_repo_root
|
|
21
21
|
|
|
22
22
|
SEARCH_STRATEGIES: TypeAlias = Literal["file_path", "keyword_search", "filename_pattern"]
|
|
23
23
|
|
|
@@ -151,7 +151,7 @@ manager.run_monitoring_routine()
|
|
|
151
151
|
|
|
152
152
|
|
|
153
153
|
def split_too_many_tabs_to_run_in_sequential_sessions(layout_tabs: list[TabConfig], every: int):
|
|
154
|
-
from machineconfig.utils.
|
|
154
|
+
from machineconfig.utils.accessories import split
|
|
155
155
|
from machineconfig.cluster.sessions_managers.zellij_local_manager import ZellijLocalManager
|
|
156
156
|
|
|
157
157
|
for idx, layout_tabs_chunk in enumerate(split(layout_tabs, every=every)):
|
|
@@ -163,7 +163,7 @@ def split_too_many_tabs_to_run_in_sequential_sessions(layout_tabs: list[TabConfi
|
|
|
163
163
|
|
|
164
164
|
|
|
165
165
|
def split_too_many_layouts_to_run_in_sequential_sessions(layouts: list[LayoutConfig], every: int):
|
|
166
|
-
from machineconfig.utils.
|
|
166
|
+
from machineconfig.utils.accessories import split
|
|
167
167
|
from machineconfig.cluster.sessions_managers.zellij_local_manager import ZellijLocalManager
|
|
168
168
|
|
|
169
169
|
for _idx, layout_chunk in enumerate(split(layouts, every=every)):
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from machineconfig.utils.
|
|
1
|
+
from machineconfig.utils.accessories import randstr
|
|
2
2
|
|
|
3
3
|
import random
|
|
4
4
|
import shlex
|
|
@@ -14,7 +14,7 @@ AGENT_NAME_FORMATTER = "agent_{idx}_cmd.sh" # e.g., agent_0_cmd.sh
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def get_gemini_api_keys() -> list[str]:
|
|
17
|
-
from machineconfig.utils.
|
|
17
|
+
from machineconfig.utils.io import read_ini
|
|
18
18
|
|
|
19
19
|
config = read_ini(Path.home().joinpath("dotfiles/creds/llm/gemini/api_keys.ini"))
|
|
20
20
|
res: list[str] = []
|
|
@@ -11,17 +11,17 @@ from machineconfig.scripts.python.helpers.helpers4 import search_for_files_of_in
|
|
|
11
11
|
from machineconfig.scripts.python.helpers.helpers4 import convert_kwargs_to_fire_kwargs_str
|
|
12
12
|
from machineconfig.scripts.python.helpers.helpers4 import parse_pyfile
|
|
13
13
|
from machineconfig.scripts.python.helpers.helpers4 import get_import_module_code
|
|
14
|
-
from machineconfig.utils.ve import
|
|
14
|
+
from machineconfig.utils.ve import get_ve_activate_line, get_ve_path_and_ipython_profile
|
|
15
15
|
from machineconfig.utils.options import display_options, choose_one_option
|
|
16
|
-
from machineconfig.utils.
|
|
16
|
+
from machineconfig.utils.path_helper import match_file_name, sanitize_path
|
|
17
17
|
|
|
18
|
-
from machineconfig.utils.
|
|
19
|
-
from machineconfig.utils.
|
|
20
|
-
from machineconfig.utils.utils2 import randstr, read_toml
|
|
18
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
19
|
+
from machineconfig.utils.accessories import get_repo_root, randstr
|
|
21
20
|
from machineconfig.scripts.python.fire_jobs_args_helper import get_args, FireJobArgs, extract_kwargs
|
|
22
21
|
import platform
|
|
23
22
|
from typing import Optional
|
|
24
23
|
from pathlib import Path
|
|
24
|
+
import tomllib
|
|
25
25
|
# import os
|
|
26
26
|
|
|
27
27
|
|
|
@@ -113,7 +113,7 @@ def route(args: FireJobArgs) -> None:
|
|
|
113
113
|
toml_path = toml_path_maybe
|
|
114
114
|
if toml_path is not None:
|
|
115
115
|
print(f"📄 Reading config.toml @ {toml_path}")
|
|
116
|
-
config =
|
|
116
|
+
config = tomllib.loads(toml_path.read_text(encoding="utf-8"))
|
|
117
117
|
if "server" in config:
|
|
118
118
|
if "port" in config["server"]:
|
|
119
119
|
port = config["server"]["port"]
|
|
@@ -121,7 +121,7 @@ def route(args: FireJobArgs) -> None:
|
|
|
121
121
|
if repo_root is not None:
|
|
122
122
|
secrets_template_path = PathExtended.home().joinpath(f"dotfiles/creds/streamlit/{PathExtended(repo_root).name}/{choice_file.name}/secrets.toml")
|
|
123
123
|
if args.environment != "" and not secrets_path.exists() and secrets_template_path.exists():
|
|
124
|
-
secrets_template =
|
|
124
|
+
secrets_template = tomllib.loads(secrets_template_path.read_text(encoding="utf-8"))
|
|
125
125
|
if args.environment == "ip":
|
|
126
126
|
host_url = f"http://{local_ip_v4}:{port}/oauth2callback"
|
|
127
127
|
elif args.environment == "localhost":
|
|
@@ -134,7 +134,7 @@ def route(args: FireJobArgs) -> None:
|
|
|
134
134
|
secrets_template["auth"]["redirect_uri"] = host_url
|
|
135
135
|
secrets_template["auth"]["cookie_secret"] = randstr(35)
|
|
136
136
|
secrets_template["auth"]["auth0"]["redirect_uri"] = host_url
|
|
137
|
-
save_toml(obj=secrets_template, path=secrets_path)
|
|
137
|
+
# save_toml(obj=secrets_template, path=secrets_path)
|
|
138
138
|
except Exception as ex:
|
|
139
139
|
print(ex)
|
|
140
140
|
raise ex
|
|
@@ -3,8 +3,8 @@ from machineconfig.utils.schemas.layouts.layout_types import LayoutConfig, Layou
|
|
|
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
|
|
6
|
-
from machineconfig.utils.
|
|
7
|
-
from machineconfig.utils.
|
|
6
|
+
from machineconfig.utils.path_helper import match_file_name, sanitize_path
|
|
7
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
10
|
from machineconfig.scripts.python.fire_jobs_args_helper import FireJobArgs
|
|
@@ -8,9 +8,9 @@ Currently, the only way to work around this is to predifine the host in ~/.ssh/c
|
|
|
8
8
|
|
|
9
9
|
import argparse
|
|
10
10
|
from machineconfig.utils.ssh import SSH
|
|
11
|
-
from machineconfig.utils.
|
|
11
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
12
12
|
from machineconfig.scripts.python.helpers.helpers2 import ES
|
|
13
|
-
from machineconfig.utils.
|
|
13
|
+
from machineconfig.utils.accessories import pprint
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def main():
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
-
from machineconfig.utils.
|
|
2
|
+
from machineconfig.utils.io import read_ini, read_json
|
|
3
|
+
from machineconfig.utils.accessories import pprint
|
|
3
4
|
from typing import Optional
|
|
4
5
|
import os
|
|
5
6
|
from machineconfig.utils.source_of_truth import DEFAULTS_PATH
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from machineconfig.scripts.python.helpers.cloud_helpers import Args, ArgsDefaults, absolute, find_cloud_config, get_secure_share_cloud_config
|
|
2
|
+
from machineconfig.utils.io import read_ini
|
|
2
3
|
from machineconfig.utils.source_of_truth import DEFAULTS_PATH
|
|
3
|
-
from machineconfig.utils.
|
|
4
|
+
from machineconfig.utils.accessories import pprint
|
|
4
5
|
from typing import Optional
|
|
5
6
|
from rich.console import Console
|
|
6
7
|
from rich.panel import Panel
|
|
@@ -103,7 +104,7 @@ def parse_cloud_source_target(args: Args, source: str, target: str) -> tuple[str
|
|
|
103
104
|
if len(source_parts) > 1 and source_parts[1] == ES: # the source path is to be inferred from target.
|
|
104
105
|
assert ES not in target, f"You can't use expand symbol `{ES}` in both source and target. Cyclical inference dependency arised."
|
|
105
106
|
target_obj = absolute(target)
|
|
106
|
-
from machineconfig.utils.
|
|
107
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
107
108
|
|
|
108
109
|
remote_path = PathExtended(target_obj).get_remote_path(os_specific=os_specific, root=root, rel2home=rel2home, strict=False)
|
|
109
110
|
source = f"{cloud}:{remote_path.as_posix()}"
|
|
@@ -123,7 +124,7 @@ def parse_cloud_source_target(args: Args, source: str, target: str) -> tuple[str
|
|
|
123
124
|
if len(target_parts) > 1 and target_parts[1] == ES: # the target path is to be inferred from source.
|
|
124
125
|
assert ES not in source, "You can't use $ in both source and target. Cyclical inference dependency arised."
|
|
125
126
|
source_obj = absolute(source)
|
|
126
|
-
from machineconfig.utils.
|
|
127
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
127
128
|
|
|
128
129
|
remote_path = PathExtended(source_obj).get_remote_path(os_specific=os_specific, root=root, rel2home=rel2home, strict=False)
|
|
129
130
|
target = f"{cloud}:{remote_path.as_posix()}"
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
from machineconfig.utils.
|
|
1
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
2
2
|
from machineconfig.utils.terminal import Terminal
|
|
3
3
|
from machineconfig.scripts.python.get_zellij_cmd import get_zellij_cmd
|
|
4
4
|
from machineconfig.utils.source_of_truth import CONFIG_PATH, DEFAULTS_PATH
|
|
5
|
-
from machineconfig.utils.
|
|
5
|
+
from machineconfig.utils.io import read_ini
|
|
6
6
|
from machineconfig.utils.code import write_shell_script_to_file
|
|
7
7
|
import platform
|
|
8
8
|
from rich.console import Console
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""NFS mounting script"""
|
|
2
2
|
|
|
3
|
-
from machineconfig.utils.
|
|
3
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
4
4
|
from machineconfig.utils.ssh import SSH
|
|
5
5
|
from machineconfig.utils.terminal import Terminal
|
|
6
6
|
from machineconfig.utils.options import display_options, choose_ssh_host
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from platform import system
|
|
4
4
|
from machineconfig.utils.ssh import SSH
|
|
5
5
|
from machineconfig.utils.terminal import Terminal
|
|
6
|
-
from machineconfig.utils.
|
|
6
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
7
7
|
|
|
8
8
|
from machineconfig.utils.options import choose_ssh_host
|
|
9
9
|
|
|
@@ -5,11 +5,13 @@ in the event that username@github.com is not mentioned in the remote url.
|
|
|
5
5
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from machineconfig.utils.io import read_ini
|
|
8
9
|
from machineconfig.utils.source_of_truth import CONFIG_PATH, DEFAULTS_PATH
|
|
9
|
-
from machineconfig.utils.
|
|
10
|
-
from machineconfig.utils.
|
|
10
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
11
|
+
from machineconfig.utils.accessories import randstr
|
|
11
12
|
from machineconfig.scripts.python.repos_helper_update import update_repository
|
|
12
13
|
from machineconfig.scripts.python.repos_helper_record import main as record_repos
|
|
14
|
+
from machineconfig.scripts.python.repos_helper_clone import clone_repos
|
|
13
15
|
|
|
14
16
|
import argparse
|
|
15
17
|
from enum import Enum
|
|
@@ -119,7 +121,7 @@ def main():
|
|
|
119
121
|
elif args.clone or args.checkout or args.checkout_to_branch:
|
|
120
122
|
print("\n📥 Cloning or checking out repositories...")
|
|
121
123
|
print(">>>>>>>>> Cloning Repos")
|
|
122
|
-
if not repos_root.exists() or repos_root.name != "repos.json":
|
|
124
|
+
if not repos_root.exists() or repos_root.name != "repos.json":
|
|
123
125
|
repos_root = PathExtended(CONFIG_PATH).joinpath("repos").joinpath(repos_root.rel2home()).joinpath("repos.json")
|
|
124
126
|
if not repos_root.exists():
|
|
125
127
|
if args.cloud is None:
|
|
@@ -130,6 +132,7 @@ def main():
|
|
|
130
132
|
assert cloud is not None, f"Path {repos_root} does not exist and cloud was not passed. You can't clone without one of them."
|
|
131
133
|
repos_root.from_cloud(cloud=cloud, rel2home=True)
|
|
132
134
|
assert (repos_root.exists() and repos_root.name == "repos.json") or args.cloud is not None, f"Path {repos_root} does not exist and cloud was not passed. You can't clone without one of them."
|
|
135
|
+
clone_repos(spec_path=repos_root, preferred_remote=None, checkout_branch_flag=args.checkout_to_branch, checkout_commit_flag=args.checkout)
|
|
133
136
|
|
|
134
137
|
elif args.all or args.commit or args.pull or args.push:
|
|
135
138
|
print(f"\n🔄 Performing Git actions on repositories @ `{repos_root}`...")
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal, Optional, cast
|
|
4
|
+
|
|
5
|
+
from git import Repo as GitRepo
|
|
6
|
+
from git.exc import GitCommandError
|
|
7
|
+
from rich import print as pprint
|
|
8
|
+
from rich.progress import BarColumn, MofNCompleteColumn, Progress, SpinnerColumn, TextColumn, TimeElapsedColumn
|
|
9
|
+
|
|
10
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
11
|
+
from machineconfig.utils.schemas.repos.repos_types import RepoRecordDict, RepoRecordFile, RepoRemote
|
|
12
|
+
from machineconfig.utils.io import read_json
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
CloneStatus = Literal["cloned", "skipped", "failed"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def choose_remote(remotes: list[RepoRemote], preferred_remote: Optional[str]) -> Optional[RepoRemote]:
|
|
19
|
+
if preferred_remote is not None:
|
|
20
|
+
for remote in remotes:
|
|
21
|
+
if remote["name"] == preferred_remote:
|
|
22
|
+
return remote
|
|
23
|
+
for remote in remotes:
|
|
24
|
+
if remote["name"] == "origin":
|
|
25
|
+
return remote
|
|
26
|
+
return remotes[0] if len(remotes) > 0 else None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def ensure_destination(parent_dir: str, name: str) -> PathExtended:
|
|
30
|
+
parent_path = PathExtended(parent_dir).expanduser().absolute()
|
|
31
|
+
parent_path.mkdir(parents=True, exist_ok=True)
|
|
32
|
+
return parent_path.joinpath(name)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def checkout_branch(repo: GitRepo, branch: str) -> bool:
|
|
36
|
+
if branch == "DETACHED":
|
|
37
|
+
return False
|
|
38
|
+
current_branch = repo.active_branch.name if not repo.head.is_detached else None
|
|
39
|
+
if current_branch == branch:
|
|
40
|
+
return False
|
|
41
|
+
repo.git.checkout(branch)
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def checkout_commit(repo: GitRepo, commit: str) -> bool:
|
|
46
|
+
if commit in {"", "UNKNOWN"}:
|
|
47
|
+
return False
|
|
48
|
+
current_commit = repo.head.commit.hexsha
|
|
49
|
+
if current_commit == commit:
|
|
50
|
+
return False
|
|
51
|
+
repo.git.checkout(commit)
|
|
52
|
+
return True
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def clone_single_repo(repo_spec: RepoRecordDict, preferred_remote: Optional[str], checkout_branch_flag: bool, checkout_commit_flag: bool) -> tuple[CloneStatus, str]:
|
|
56
|
+
destination = ensure_destination(parent_dir=repo_spec["parentDir"], name=repo_spec["name"])
|
|
57
|
+
repo_path = destination.joinpath(".git")
|
|
58
|
+
remotes = repo_spec["remotes"]
|
|
59
|
+
if len(remotes) == 0:
|
|
60
|
+
return ("failed", f"No remotes configured for {destination}")
|
|
61
|
+
remote = choose_remote(remotes=remotes, preferred_remote=preferred_remote)
|
|
62
|
+
if remote is None:
|
|
63
|
+
return ("failed", f"No usable remote for {destination}")
|
|
64
|
+
repo = None
|
|
65
|
+
status: CloneStatus
|
|
66
|
+
message: str
|
|
67
|
+
if destination.exists() and repo_path.exists():
|
|
68
|
+
status = "skipped"
|
|
69
|
+
repo = GitRepo(str(destination))
|
|
70
|
+
message = f"Skipped cloning for {destination}; existing repository reused"
|
|
71
|
+
elif destination.exists() and not repo_path.exists():
|
|
72
|
+
return ("failed", f"Destination exists but is not a git repository: {destination}")
|
|
73
|
+
else:
|
|
74
|
+
try:
|
|
75
|
+
pprint(f"📥 Cloning {repo_spec['name']} from {remote['url']}")
|
|
76
|
+
repo = GitRepo.clone_from(url=remote["url"], to_path=str(destination))
|
|
77
|
+
status = "cloned"
|
|
78
|
+
message = f"Cloned {destination}"
|
|
79
|
+
except Exception as err: # noqa: BLE001
|
|
80
|
+
return ("failed", f"Clone failed for {destination}: {err}")
|
|
81
|
+
assert repo is not None
|
|
82
|
+
checkout_summary: list[str] = []
|
|
83
|
+
try:
|
|
84
|
+
if checkout_branch_flag:
|
|
85
|
+
if checkout_branch(repo=repo, branch=repo_spec["version"]["branch"]):
|
|
86
|
+
checkout_summary.append(f"branch {repo_spec['version']['branch']}")
|
|
87
|
+
if checkout_commit_flag:
|
|
88
|
+
if checkout_commit(repo=repo, commit=repo_spec["version"]["commit"]):
|
|
89
|
+
checkout_summary.append(f"commit {repo_spec['version']['commit'][:8]}")
|
|
90
|
+
except GitCommandError as err:
|
|
91
|
+
return ("failed", f"Checkout failed for {destination}: {err}")
|
|
92
|
+
if len(checkout_summary) > 0:
|
|
93
|
+
message = f"{message} | Checked out {' & '.join(checkout_summary)}"
|
|
94
|
+
return (status, message)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def clone_repos(spec_path: PathExtended, preferred_remote: Optional[str], checkout_branch_flag: bool, checkout_commit_flag: bool) -> list[tuple[CloneStatus, str]]:
|
|
98
|
+
data = cast(RepoRecordFile, read_json(path=spec_path))
|
|
99
|
+
repos = data["repos"]
|
|
100
|
+
results: list[tuple[CloneStatus, str]] = []
|
|
101
|
+
with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), BarColumn(), MofNCompleteColumn(), TimeElapsedColumn()) as progress:
|
|
102
|
+
task_id = progress.add_task("Processing repositories...", total=len(repos))
|
|
103
|
+
for repo_spec in repos:
|
|
104
|
+
progress.update(task_id, description=f"Processing {repo_spec['name']}")
|
|
105
|
+
try:
|
|
106
|
+
result = clone_single_repo(repo_spec=repo_spec, preferred_remote=preferred_remote, checkout_branch_flag=checkout_branch_flag, checkout_commit_flag=checkout_commit_flag)
|
|
107
|
+
except Exception as err: # noqa: BLE001
|
|
108
|
+
result = ("failed", f"Unexpected error for {repo_spec['name']}: {err}")
|
|
109
|
+
results.append(result)
|
|
110
|
+
if result[0] == "failed":
|
|
111
|
+
pprint(f"❌ {result[1]}")
|
|
112
|
+
elif result[0] == "cloned":
|
|
113
|
+
pprint(f"✅ {result[1]}")
|
|
114
|
+
else:
|
|
115
|
+
pprint(f"⏭️ {result[1]}")
|
|
116
|
+
progress.update(task_id, advance=1)
|
|
117
|
+
success_count = len([status for status, _ in results if status == "cloned"])
|
|
118
|
+
skip_count = len([status for status, _ in results if status == "skipped"])
|
|
119
|
+
fail_count = len([status for status, _ in results if status == "failed"])
|
|
120
|
+
pprint(f"✅ Cloned: {success_count} | ⏭️ Skipped: {skip_count} | ❌ Failed: {fail_count}")
|
|
121
|
+
return results
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
from machineconfig.utils.
|
|
1
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
2
2
|
from machineconfig.utils.schemas.repos.repos_types import GitVersionInfo, RepoRecordDict, RepoRemote
|
|
3
3
|
|
|
4
4
|
from machineconfig.utils.schemas.repos.repos_types import RepoRecordFile
|
|
5
5
|
from machineconfig.utils.source_of_truth import CONFIG_PATH
|
|
6
|
-
from machineconfig.utils.
|
|
6
|
+
from machineconfig.utils.io import save_json
|
|
7
7
|
|
|
8
8
|
from typing import Optional
|
|
9
9
|
|
|
@@ -4,7 +4,7 @@ slidev
|
|
|
4
4
|
|
|
5
5
|
from machineconfig.utils.source_of_truth import CONFIG_PATH
|
|
6
6
|
from machineconfig.utils.code import print_code
|
|
7
|
-
from machineconfig.utils.
|
|
7
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
8
8
|
from machineconfig.utils.terminal import Terminal
|
|
9
9
|
import subprocess
|
|
10
10
|
import platform
|
|
@@ -4,7 +4,7 @@ https://glitchbone.github.io/vscode-base16-term/#/3024
|
|
|
4
4
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
from machineconfig.utils.
|
|
7
|
+
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
8
8
|
from machineconfig.utils.source_of_truth import LIBRARY_ROOT
|
|
9
9
|
from machineconfig.utils.installer_utils.installer_class import Installer
|
|
10
10
|
import subprocess
|