machineconfig 7.57__py3-none-any.whl → 7.79__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/utils/maker.py +21 -9
- machineconfig/jobs/installer/custom/boxes.py +2 -2
- machineconfig/jobs/installer/custom/hx.py +3 -3
- machineconfig/jobs/installer/custom_dev/cloudflare_warp_cli.py +23 -0
- machineconfig/jobs/installer/custom_dev/dubdb_adbc.py +1 -1
- machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +1 -1
- machineconfig/jobs/installer/custom_dev/sysabc.py +36 -28
- machineconfig/jobs/installer/custom_dev/wezterm.py +0 -4
- machineconfig/jobs/installer/installer_data.json +127 -25
- machineconfig/jobs/installer/package_groups.py +20 -13
- machineconfig/profile/create_links_export.py +2 -2
- machineconfig/scripts/__init__.py +0 -4
- machineconfig/scripts/linux/wrap_mcfg +1 -1
- machineconfig/scripts/python/agents.py +22 -17
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +3 -0
- machineconfig/scripts/python/croshell.py +22 -17
- machineconfig/scripts/python/devops.py +3 -4
- machineconfig/scripts/python/devops_navigator.py +0 -4
- machineconfig/scripts/python/env_manager/path_manager_tui.py +1 -1
- machineconfig/scripts/python/fire_jobs.py +19 -18
- machineconfig/scripts/python/ftpx.py +36 -12
- machineconfig/scripts/python/helpers/ast_search.py +74 -0
- machineconfig/scripts/python/helpers/qr_code.py +166 -0
- machineconfig/scripts/python/helpers/repo_rag.py +325 -0
- machineconfig/scripts/python/helpers/symantic_search.py +25 -0
- machineconfig/scripts/python/helpers_cloud/cloud_copy.py +28 -21
- machineconfig/scripts/python/helpers_cloud/cloud_helpers.py +1 -1
- machineconfig/scripts/python/helpers_cloud/cloud_mount.py +19 -17
- machineconfig/scripts/python/helpers_cloud/cloud_sync.py +8 -7
- machineconfig/scripts/python/helpers_croshell/crosh.py +2 -2
- machineconfig/scripts/python/helpers_croshell/start_slidev.py +6 -7
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +4 -5
- machineconfig/scripts/python/helpers_devops/cli_nw.py +88 -7
- machineconfig/scripts/python/helpers_devops/cli_self.py +7 -6
- machineconfig/scripts/python/helpers_devops/cli_share_file.py +9 -9
- machineconfig/scripts/python/helpers_devops/cli_share_server.py +13 -12
- machineconfig/scripts/python/helpers_devops/cli_terminal.py +7 -6
- machineconfig/scripts/python/helpers_devops/cli_utils.py +2 -73
- machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +4 -4
- machineconfig/scripts/python/helpers_devops/devops_status.py +7 -19
- machineconfig/scripts/python/helpers_fire_command/file_wrangler.py +2 -3
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +23 -13
- machineconfig/scripts/python/helpers_navigator/command_tree.py +50 -18
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +7 -4
- machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +1 -1
- machineconfig/scripts/python/helpers_repos/entrypoint.py +2 -1
- machineconfig/scripts/python/helpers_repos/record.py +2 -1
- machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +5 -5
- machineconfig/scripts/python/helpers_utils/download.py +152 -0
- machineconfig/scripts/python/helpers_utils/path.py +81 -31
- machineconfig/scripts/python/interactive.py +2 -2
- machineconfig/scripts/python/{machineconfig.py → mcfg_entry.py} +4 -0
- machineconfig/scripts/python/msearch.py +21 -2
- machineconfig/scripts/python/nw/address.py +132 -0
- machineconfig/scripts/python/nw/devops_add_ssh_key.py +8 -5
- machineconfig/scripts/python/nw/ssh_debug_linux.py +7 -7
- machineconfig/scripts/python/nw/ssh_debug_windows.py +4 -4
- machineconfig/scripts/python/nw/wsl_windows_transfer.py +3 -2
- machineconfig/scripts/python/sessions.py +35 -20
- machineconfig/scripts/python/terminal.py +2 -2
- machineconfig/scripts/python/utils.py +12 -10
- machineconfig/scripts/windows/mounts/mount_ssh.ps1 +1 -1
- machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
- machineconfig/settings/shells/nushell/config.nu +2 -2
- machineconfig/settings/shells/nushell/env.nu +45 -6
- machineconfig/settings/shells/nushell/init.nu +282 -95
- machineconfig/settings/shells/pwsh/init.ps1 +1 -0
- machineconfig/settings/shells/zsh/init.sh +0 -7
- machineconfig/setup_linux/web_shortcuts/interactive.sh +10 -10
- machineconfig/setup_windows/uv.ps1 +8 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +10 -10
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +3 -2
- machineconfig/utils/accessories.py +7 -4
- machineconfig/utils/code.py +6 -4
- machineconfig/utils/files/headers.py +2 -2
- machineconfig/utils/installer_utils/install_from_url.py +180 -0
- machineconfig/utils/installer_utils/installer_class.py +53 -47
- machineconfig/utils/installer_utils/{installer.py → installer_cli.py} +71 -65
- machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +1 -25
- machineconfig/utils/links.py +2 -2
- machineconfig/utils/meta.py +30 -16
- machineconfig/utils/options.py +4 -4
- machineconfig/utils/path_extended.py +3 -3
- machineconfig/utils/path_helper.py +33 -31
- machineconfig/utils/schemas/layouts/layout_types.py +1 -1
- machineconfig/utils/ssh.py +143 -409
- machineconfig/utils/ssh_utils/abc.py +8 -0
- machineconfig/utils/ssh_utils/copy_from_here.py +110 -0
- machineconfig/utils/ssh_utils/copy_to_here.py +302 -0
- machineconfig/utils/ssh_utils/utils.py +141 -0
- machineconfig/utils/ssh_utils/wsl.py +168 -0
- machineconfig/utils/upgrade_packages.py +2 -1
- machineconfig/utils/ve.py +11 -4
- {machineconfig-7.57.dist-info → machineconfig-7.79.dist-info}/METADATA +1 -1
- {machineconfig-7.57.dist-info → machineconfig-7.79.dist-info}/RECORD +102 -92
- {machineconfig-7.57.dist-info → machineconfig-7.79.dist-info}/entry_points.txt +2 -2
- machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -41
- machineconfig/scripts/python/explore.py +0 -49
- /machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +0 -0
- /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers_fire_command/f.py} +0 -0
- /machineconfig/scripts/{Restore-ThunderbirdProfile.ps1 → windows/mounts/Restore-ThunderbirdProfile.ps1} +0 -0
- /machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +0 -0
- {machineconfig-7.57.dist-info → machineconfig-7.79.dist-info}/WHEEL +0 -0
- {machineconfig-7.57.dist-info → machineconfig-7.79.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import platform
|
|
3
|
+
import stat
|
|
4
|
+
import shutil
|
|
5
|
+
import subprocess
|
|
6
|
+
from pathlib import Path, PureWindowsPath
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _ensure_relative_path(requested: Path | str) -> Path:
|
|
10
|
+
path = Path(requested)
|
|
11
|
+
if path.is_absolute():
|
|
12
|
+
raise ValueError("paths must be relative to the home directory")
|
|
13
|
+
if any(part == ".." for part in path.parts):
|
|
14
|
+
raise ValueError("paths must stay within the home directory")
|
|
15
|
+
return path
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _remove_path(path: Path) -> None:
|
|
19
|
+
if path.is_symlink() or path.is_file():
|
|
20
|
+
path.unlink()
|
|
21
|
+
return
|
|
22
|
+
shutil.rmtree(path)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _ensure_wsl_environment() -> None:
|
|
26
|
+
if os.environ.get("WSL_DISTRO_NAME"):
|
|
27
|
+
return
|
|
28
|
+
if "microsoft" in platform.release().lower():
|
|
29
|
+
return
|
|
30
|
+
raise RuntimeError("copy_when_inside_wsl must run inside WSL")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _ensure_windows_environment() -> None:
|
|
34
|
+
if os.name != "nt":
|
|
35
|
+
raise RuntimeError("copy_when_inside_windows must run inside Windows")
|
|
36
|
+
if os.environ.get("WSL_DISTRO_NAME"):
|
|
37
|
+
raise RuntimeError("copy_when_inside_windows must run inside Windows")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _infer_windows_home_from_permissions() -> Path:
|
|
41
|
+
base_dir = Path("/mnt/c/Users")
|
|
42
|
+
try:
|
|
43
|
+
entries = list(base_dir.iterdir())
|
|
44
|
+
except FileNotFoundError as exc:
|
|
45
|
+
raise RuntimeError("unable to find /mnt/c/Users") from exc
|
|
46
|
+
candidates: list[Path] = []
|
|
47
|
+
for entry in entries:
|
|
48
|
+
if not entry.is_dir():
|
|
49
|
+
continue
|
|
50
|
+
if entry.name.lower() == "public" or entry.name.lower() == "all users":
|
|
51
|
+
continue
|
|
52
|
+
try:
|
|
53
|
+
mode = stat.S_IMODE(entry.stat().st_mode)
|
|
54
|
+
except OSError:
|
|
55
|
+
continue
|
|
56
|
+
if mode == 0o777:
|
|
57
|
+
candidates.append(entry)
|
|
58
|
+
if len(candidates) != 1:
|
|
59
|
+
options = ", ".join(sorted(candidate.name for candidate in candidates)) or "none"
|
|
60
|
+
raise RuntimeError(f"unable to infer Windows home directory (candidates: {options})")
|
|
61
|
+
return candidates[0]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _resolve_windows_home_from_wsl() -> Path:
|
|
65
|
+
user_profile = os.environ.get("USERPROFILE")
|
|
66
|
+
if user_profile:
|
|
67
|
+
windows_path = PureWindowsPath(user_profile)
|
|
68
|
+
drive = windows_path.drive
|
|
69
|
+
if drive:
|
|
70
|
+
drive_letter = drive.rstrip(":").lower()
|
|
71
|
+
tail = Path(*windows_path.parts[1:])
|
|
72
|
+
candidate = Path("/mnt") / drive_letter / tail
|
|
73
|
+
if candidate.exists():
|
|
74
|
+
return candidate
|
|
75
|
+
return _infer_windows_home_from_permissions()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _get_single_wsl_distribution() -> str:
|
|
79
|
+
process = subprocess.run(["wsl.exe", "-l"], capture_output=True, text=True, check=True)
|
|
80
|
+
distributions: list[str] = []
|
|
81
|
+
for raw_line in process.stdout.replace("\ufeff", "").splitlines():
|
|
82
|
+
line = raw_line.strip()
|
|
83
|
+
if not line or line.lower().startswith("windows subsystem for linux"):
|
|
84
|
+
continue
|
|
85
|
+
normalized = line.lstrip("* ").replace("(Default)", "").strip()
|
|
86
|
+
if normalized:
|
|
87
|
+
distributions.append(normalized)
|
|
88
|
+
if len(distributions) != 1:
|
|
89
|
+
raise RuntimeError("unable to pick a single WSL distribution")
|
|
90
|
+
return distributions[0]
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _resolve_wsl_home_on_windows() -> Path:
|
|
94
|
+
distribution = _get_single_wsl_distribution()
|
|
95
|
+
home_root = Path(rf"\\wsl$\{distribution}\home")
|
|
96
|
+
try:
|
|
97
|
+
entries = list(home_root.iterdir())
|
|
98
|
+
except FileNotFoundError as exc:
|
|
99
|
+
raise RuntimeError(f"unable to locate WSL home directories for {distribution}") from exc
|
|
100
|
+
except OSError as exc:
|
|
101
|
+
raise RuntimeError(f"unable to inspect WSL home directories for {distribution}") from exc
|
|
102
|
+
user_dirs = [entry for entry in entries if entry.is_dir()]
|
|
103
|
+
if len(user_dirs) != 1:
|
|
104
|
+
options = ", ".join(sorted(entry.name for entry in user_dirs)) or "none"
|
|
105
|
+
raise RuntimeError(f"unable to infer WSL user directory (candidates: {options})")
|
|
106
|
+
return user_dirs[0]
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _quote_for_powershell(path: Path) -> str:
|
|
110
|
+
return "'" + str(path).replace("'", "''") + "'"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _run_windows_copy_command(source_path: Path, target_path: Path) -> None:
|
|
114
|
+
source_is_dir = source_path.is_dir()
|
|
115
|
+
parent_literal = _quote_for_powershell(target_path.parent)
|
|
116
|
+
source_literal = _quote_for_powershell(source_path)
|
|
117
|
+
target_literal = _quote_for_powershell(target_path)
|
|
118
|
+
script = (
|
|
119
|
+
"$ErrorActionPreference = 'Stop'; "
|
|
120
|
+
f"New-Item -ItemType Directory -Path {parent_literal} -Force | Out-Null; "
|
|
121
|
+
f"Copy-Item -LiteralPath {source_literal} -Destination {target_literal}"
|
|
122
|
+
f"{' -Recurse' if source_is_dir else ''} -Force"
|
|
123
|
+
)
|
|
124
|
+
print(f"Copying {source_path} to {target_path}")
|
|
125
|
+
subprocess.run(
|
|
126
|
+
["powershell.exe", "-NoLogo", "-NoProfile", "-Command", script],
|
|
127
|
+
check=True,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def copy_when_inside_wsl(source: Path | str, target: Path | str, overwrite: bool) -> None:
|
|
132
|
+
_ensure_wsl_environment()
|
|
133
|
+
source_relative = _ensure_relative_path(source)
|
|
134
|
+
target_relative = _ensure_relative_path(target)
|
|
135
|
+
source_path = Path.home() / source_relative
|
|
136
|
+
target_path = _resolve_windows_home_from_wsl() / target_relative
|
|
137
|
+
if not source_path.exists():
|
|
138
|
+
raise FileNotFoundError(source_path)
|
|
139
|
+
if target_path.exists():
|
|
140
|
+
if not overwrite:
|
|
141
|
+
raise FileExistsError(target_path)
|
|
142
|
+
_remove_path(target_path)
|
|
143
|
+
target_path.parent.mkdir(parents=True, exist_ok=True)
|
|
144
|
+
if source_path.is_dir():
|
|
145
|
+
shutil.copytree(source_path, target_path, dirs_exist_ok=False)
|
|
146
|
+
return
|
|
147
|
+
print(f"Copying {source_path} to {target_path}")
|
|
148
|
+
shutil.copy2(source_path, target_path)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def copy_when_inside_windows(source: Path | str, target: Path | str, overwrite: bool) -> None:
|
|
152
|
+
_ensure_windows_environment()
|
|
153
|
+
source_relative = _ensure_relative_path(source)
|
|
154
|
+
target_relative = _ensure_relative_path(target)
|
|
155
|
+
source_path = Path.home() / source_relative
|
|
156
|
+
target_path = _resolve_wsl_home_on_windows() / target_relative
|
|
157
|
+
if not source_path.exists():
|
|
158
|
+
raise FileNotFoundError(source_path)
|
|
159
|
+
if target_path.exists():
|
|
160
|
+
if not overwrite:
|
|
161
|
+
raise FileExistsError(target_path)
|
|
162
|
+
_remove_path(target_path)
|
|
163
|
+
_run_windows_copy_command(source_path, target_path)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
if __name__ == "__main__":
|
|
167
|
+
copy_when_inside_wsl(Path("projects/source.txt"), Path("windows_projects/source.txt"), True)
|
|
168
|
+
copy_when_inside_windows(Path("documents/example.txt"), Path("linux_documents/example.txt"), True)
|
|
@@ -164,8 +164,9 @@ def upgrade_machine_config_version() -> None:
|
|
|
164
164
|
except (UnicodeDecodeError, PermissionError):
|
|
165
165
|
# Skip files that can't be read as text
|
|
166
166
|
pass
|
|
167
|
-
|
|
168
167
|
print(f"Updated {files_updated} files with version constraint")
|
|
168
|
+
from machineconfig.utils.code import exit_then_run_shell_script
|
|
169
|
+
exit_then_run_shell_script(f"cd current_dir; uv sync")
|
|
169
170
|
|
|
170
171
|
|
|
171
172
|
if __name__ == "__main__":
|
machineconfig/utils/ve.py
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
import platform
|
|
1
|
+
|
|
3
2
|
from typing import Optional
|
|
4
|
-
from pathlib import Path
|
|
5
3
|
|
|
6
4
|
|
|
7
|
-
def get_ve_path_and_ipython_profile(init_path: Path) -> tuple[Optional[str], Optional[str]]:
|
|
5
|
+
def get_ve_path_and_ipython_profile(init_path: "Path") -> tuple[Optional[str], Optional[str]]:
|
|
8
6
|
"""Works with .ve.ini .venv and .ve_path"""
|
|
9
7
|
ve_path: Optional[str] = None
|
|
10
8
|
ipy_profile: Optional[str] = None
|
|
11
9
|
tmp = init_path
|
|
10
|
+
|
|
11
|
+
from machineconfig.utils.io import read_ini
|
|
12
|
+
|
|
12
13
|
for _ in init_path.parents:
|
|
13
14
|
if tmp.joinpath(".ve.ini").exists():
|
|
14
15
|
ini = read_ini(tmp.joinpath(".ve.ini"))
|
|
@@ -39,6 +40,8 @@ def get_ve_path_and_ipython_profile(init_path: Path) -> tuple[Optional[str], Opt
|
|
|
39
40
|
|
|
40
41
|
|
|
41
42
|
def get_ve_activate_line(ve_root: str):
|
|
43
|
+
import platform
|
|
44
|
+
from pathlib import Path
|
|
42
45
|
if platform.system() == "Windows":
|
|
43
46
|
q = Path(ve_root).expanduser().relative_to(Path.home()).as_posix()
|
|
44
47
|
activate_ve_line = f". $HOME/{q}/Scripts/activate.ps1"
|
|
@@ -47,3 +50,7 @@ def get_ve_activate_line(ve_root: str):
|
|
|
47
50
|
else:
|
|
48
51
|
raise NotImplementedError(f"Platform {platform.system()} not supported.")
|
|
49
52
|
return activate_ve_line
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__":
|
|
56
|
+
from pathlib import Path
|