machineconfig 5.85__py3-none-any.whl → 5.87__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/jobs/installer/installer_data.json +6 -6
- machineconfig/profile/create_links_export.py +9 -9
- machineconfig/scripts/python/agents.py +17 -17
- machineconfig/scripts/python/croshell.py +1 -1
- machineconfig/scripts/python/devops.py +8 -6
- machineconfig/scripts/python/devops_helpers/cli_config.py +10 -10
- machineconfig/scripts/python/devops_helpers/cli_nw.py +7 -6
- machineconfig/scripts/python/devops_helpers/cli_repos.py +20 -20
- machineconfig/scripts/python/devops_helpers/cli_self.py +6 -6
- machineconfig/scripts/python/devops_helpers/cli_share_server.py +2 -9
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +8 -8
- machineconfig/scripts/python/helpers_repos/grource.py +1 -1
- machineconfig/scripts/python/helpers_repos/secure_repo.py +6 -6
- machineconfig/scripts/python/interactive.py +2 -2
- machineconfig/scripts/python/nw/add_ssh_key.py +5 -5
- machineconfig/scripts/python/nw/devops_add_ssh_key.py +5 -5
- machineconfig/scripts/python/nw/mount_nfs +1 -1
- machineconfig/scripts/python/nw/ssh_debug_windows.py +338 -0
- machineconfig/scripts/python/repos_helpers/count_lines.py +4 -4
- machineconfig/scripts/python/repos_helpers/count_lines_frontend.py +3 -2
- machineconfig/scripts/python/sessions.py +15 -15
- machineconfig/scripts/python/sessions_helpers/sessions_multiprocess.py +4 -4
- machineconfig/scripts/windows/mounts/mount_ssh.ps1 +1 -1
- machineconfig/setup_linux/web_shortcuts/interactive.sh +1 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +1 -1
- machineconfig/utils/installer_utils/installer.py +5 -5
- machineconfig/utils/ssh.py +1 -1
- {machineconfig-5.85.dist-info → machineconfig-5.87.dist-info}/METADATA +2 -2
- {machineconfig-5.85.dist-info → machineconfig-5.87.dist-info}/RECORD +32 -31
- {machineconfig-5.85.dist-info → machineconfig-5.87.dist-info}/WHEEL +0 -0
- {machineconfig-5.85.dist-info → machineconfig-5.87.dist-info}/entry_points.txt +0 -0
- {machineconfig-5.85.dist-info → machineconfig-5.87.dist-info}/top_level.txt +0 -0
|
@@ -245,14 +245,14 @@
|
|
|
245
245
|
"doc": "🔗 Easy file sharing tool",
|
|
246
246
|
"fileNamePattern": {
|
|
247
247
|
"amd64": {
|
|
248
|
-
"linux": "npm
|
|
249
|
-
"windows": "npm
|
|
250
|
-
"macos": "npm
|
|
248
|
+
"linux": "npm i -g @ezshare/cli",
|
|
249
|
+
"windows": "npm i -g @ezshare/cli",
|
|
250
|
+
"macos": "npm i -g @ezshare/cli"
|
|
251
251
|
},
|
|
252
252
|
"arm64": {
|
|
253
|
-
"linux": "npm
|
|
254
|
-
"windows": "npm
|
|
255
|
-
"macos": "npm
|
|
253
|
+
"linux": "npm i -g @ezshare/cli",
|
|
254
|
+
"windows": "npm i -g @ezshare/cli",
|
|
255
|
+
"macos": "npm i -g @ezshare/cli"
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
},
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
|
|
2
2
|
import typer
|
|
3
|
-
from typing import Optional, Literal
|
|
3
|
+
from typing import Optional, Literal, Annotated
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
def main_public_from_parser(method: Literal["symlink", "copy"]
|
|
7
|
-
on_conflict: Literal["throwError", "overwriteDefaultPath", "backupDefaultPath"]
|
|
8
|
-
which: Optional[str]
|
|
9
|
-
interactive: bool
|
|
6
|
+
def main_public_from_parser(method: Annotated[Literal["symlink", "copy"], typer.Option(..., help="Method to use for setting up the config file.")],
|
|
7
|
+
on_conflict: Annotated[Literal["throwError", "overwriteDefaultPath", "backupDefaultPath"], typer.Option(..., help="Action to take on conflict")],
|
|
8
|
+
which: Annotated[Optional[str], typer.Option(..., help="Specific items to process")] = None,
|
|
9
|
+
interactive: Annotated[bool, typer.Option(..., help="Run in interactive mode")] = False):
|
|
10
10
|
"""Terminology:
|
|
11
11
|
SOURCE = Self-Managed-Config-File-Path
|
|
12
12
|
TARGET = Config-File-Default-Path
|
|
@@ -31,10 +31,10 @@ def main_public_from_parser(method: Literal["symlink", "copy"] = typer.Option(..
|
|
|
31
31
|
apply_mapper(mapper_data=items_objections, on_conflict=on_conflict, method=method)
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
def main_private_from_parser(method: Literal["symlink", "copy"]
|
|
35
|
-
on_conflict: Literal["throwError", "overwriteSelfManaged", "backupSelfManaged", "overwriteDefaultPath", "backupDefaultPath"]
|
|
36
|
-
which: Optional[str]
|
|
37
|
-
interactive: bool
|
|
34
|
+
def main_private_from_parser(method: Annotated[Literal["symlink", "copy"], typer.Option(..., help="Method to use for linking files")],
|
|
35
|
+
on_conflict: Annotated[Literal["throwError", "overwriteSelfManaged", "backupSelfManaged", "overwriteDefaultPath", "backupDefaultPath"], typer.Option(..., help="Action to take on conflict")] = "throwError",
|
|
36
|
+
which: Annotated[Optional[str], typer.Option(..., help="Specific items to process")] = None,
|
|
37
|
+
interactive: Annotated[bool, typer.Option(..., help="Run in interactive mode")] = False):
|
|
38
38
|
from machineconfig.profile.create_links import ConfigMapper, read_mapper
|
|
39
39
|
|
|
40
40
|
mapper_full = read_mapper()["private"]
|
|
@@ -3,25 +3,25 @@
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from typing import cast, Optional, get_args
|
|
6
|
+
from typing import cast, Optional, get_args, Annotated
|
|
7
7
|
import typer
|
|
8
8
|
from machineconfig.scripts.python.helpers_fire.fire_agents_helper_types import AGENTS, HOST, MODEL, PROVIDER
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def create(
|
|
12
|
-
agent: AGENTS
|
|
13
|
-
host: HOST
|
|
14
|
-
model: MODEL
|
|
15
|
-
provider: PROVIDER
|
|
16
|
-
context_path: Optional[Path]
|
|
17
|
-
separator: str
|
|
18
|
-
agent_load: int
|
|
19
|
-
prompt: Optional[str]
|
|
20
|
-
prompt_path: Optional[Path]
|
|
21
|
-
job_name: str
|
|
22
|
-
separate: bool
|
|
23
|
-
output_path: Optional[Path]
|
|
24
|
-
agents_dir: Optional[Path]
|
|
12
|
+
agent: Annotated[AGENTS, typer.Option(..., "--agents", "-a", help=f"Agent type. One of {', '.join(get_args(AGENTS)[:3])}")],
|
|
13
|
+
host: Annotated[HOST, typer.Option(..., "--host", "-h", help=f"Machine to run agents on. One of {', '.join(get_args(HOST))}")],
|
|
14
|
+
model: Annotated[MODEL, typer.Option(..., "--model", "-m", help=f"Model to use (for crush agent). One of {', '.join(get_args(MODEL)[:3])}")],
|
|
15
|
+
provider: Annotated[PROVIDER, typer.Option(..., "--provider", "-p", help=f"Provider to use (for crush agent). One of {', '.join(get_args(PROVIDER)[:3])}")],
|
|
16
|
+
context_path: Annotated[Optional[Path], typer.Option(..., "--context-path", "-c", help="Path to the context file/folder, defaults to .ai/todo/")] = None,
|
|
17
|
+
separator: Annotated[str, typer.Option(..., "--separator", "-s", help="Separator for context")] = "\n",
|
|
18
|
+
agent_load: Annotated[int, typer.Option(..., "--agent-load", "-al", help="Number of tasks per prompt")] = 13,
|
|
19
|
+
prompt: Annotated[Optional[str], typer.Option(..., "--prompt", "-P", help="Prompt prefix as string")] = None,
|
|
20
|
+
prompt_path: Annotated[Optional[Path], typer.Option(..., "--prompt-path", "-pp", help="Path to prompt file")] = None,
|
|
21
|
+
job_name: Annotated[str, typer.Option(..., "--job-name", "-j", help="Job name")] = "AI_Agents",
|
|
22
|
+
separate: Annotated[bool, typer.Option(..., "--separate", "-S", help="Keep prompt material in separate file to the context.")] = True,
|
|
23
|
+
output_path: Annotated[Optional[Path], typer.Option(..., "--output-path", "-o", help="Path to write the layout.json file")] = None,
|
|
24
|
+
agents_dir: Annotated[Optional[Path], typer.Option(..., "--agents-dir", "-ad", help="Directory to store agent files. If not provided, will be constructed automatically.")] = None,
|
|
25
25
|
):
|
|
26
26
|
|
|
27
27
|
from machineconfig.scripts.python.helpers_fire.fire_agents_help_launch import prep_agent_launch, get_agents_launch_layout
|
|
@@ -94,9 +94,9 @@ agents create "{context_path_resolved}" \\
|
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
def collect(
|
|
97
|
-
agent_dir: str
|
|
98
|
-
output_path: str
|
|
99
|
-
separator: str
|
|
97
|
+
agent_dir: Annotated[str, typer.Argument(..., help="Path to the agent directory containing the prompts folder")],
|
|
98
|
+
output_path: Annotated[str, typer.Argument(..., help="Path to write the concatenated material files")],
|
|
99
|
+
separator: Annotated[str, typer.Option(..., help="Separator to use when concatenating material files")] = "\n",
|
|
100
100
|
) -> None:
|
|
101
101
|
"""Collect all material files from an agent directory and concatenate them."""
|
|
102
102
|
if not Path(agent_dir).exists() or not Path(agent_dir).is_dir():
|
|
@@ -149,7 +149,7 @@ from pathlib import Path
|
|
|
149
149
|
else:
|
|
150
150
|
console.print(Panel("❌ Could not determine the local machineconfig repo root. Please ensure the `REPO_ROOT` in `source_of_truth.py` is correctly set to the local path of the machineconfig repo, or do not use the `--local` flag.", title="Error", border_style="red"))
|
|
151
151
|
return
|
|
152
|
-
else: ve_line = """--with "machineconfig[plot]>=5.
|
|
152
|
+
else: ve_line = """--with "machineconfig[plot]>=5.87" """
|
|
153
153
|
fire_line = f"uv run --python 3.14 {ve_line} {interpreter} {interactivity} {profile} {str(pyfile)}"
|
|
154
154
|
|
|
155
155
|
from machineconfig.utils.code import run_shell_script
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""devops with emojis"""
|
|
2
2
|
|
|
3
3
|
import typer
|
|
4
|
-
from typing import Optional
|
|
4
|
+
from typing import Optional, Annotated
|
|
5
5
|
|
|
6
6
|
import machineconfig.scripts.python.devops_helpers.cli_repos as cli_repos
|
|
7
7
|
import machineconfig.scripts.python.devops_helpers.cli_config as cli_config
|
|
@@ -10,15 +10,17 @@ import machineconfig.scripts.python.devops_helpers.cli_data as cli_data
|
|
|
10
10
|
import machineconfig.scripts.python.devops_helpers.cli_nw as cli_network
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
group: bool = typer.Option(False, "--group", "-g", help="Treat 'which' as a group name. A group is bundle of apps."),
|
|
17
|
-
interactive: bool = typer.Option(False, "--interactive", "-ia", help="Interactive selection of programs to install."),
|
|
13
|
+
def install(which: Annotated[Optional[str], typer.Argument(..., help="Comma-separated list of program names to install, or group name if --group flag is set.")],
|
|
14
|
+
group: Annotated[bool, typer.Option(..., "--group", "-g", help="Treat 'which' as a group name. A group is bundle of apps.")] = False,
|
|
15
|
+
interactive: Annotated[bool, typer.Option(..., "--interactive", "-ia", help="Interactive selection of programs to install.")] = False,
|
|
18
16
|
) -> None:
|
|
19
17
|
"""📦 Install essential packages"""
|
|
20
18
|
import machineconfig.utils.installer_utils.installer as installer_entry_point
|
|
21
19
|
installer_entry_point.main(which=which, group=group, interactive=interactive)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_app():
|
|
23
|
+
app = typer.Typer(help="🛠️ DevOps operations", no_args_is_help=True, add_completion=True)
|
|
22
24
|
_ = install
|
|
23
25
|
app.command("install", no_args_is_help=True, help="🛠️ [i] Install essential packages")(install)
|
|
24
26
|
app.command("i", no_args_is_help=True, help="Install essential packages", hidden=True)(install)
|
|
@@ -6,18 +6,18 @@ import typer
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def private(method: Literal["symlink", "copy"]
|
|
10
|
-
on_conflict: Literal["throwError", "overwriteSelfManaged", "backupSelfManaged", "overwriteDefaultPath", "backupDefaultPath"]
|
|
11
|
-
which: Optional[str]
|
|
12
|
-
interactive: bool
|
|
9
|
+
def private(method: Annotated[Literal["symlink", "copy"], typer.Option(..., "--method", "-m", help="Method to use for linking files")],
|
|
10
|
+
on_conflict: Annotated[Literal["throwError", "overwriteSelfManaged", "backupSelfManaged", "overwriteDefaultPath", "backupDefaultPath"], typer.Option(..., "--on-conflict", "-o", help="Action to take on conflict")] = "throwError",
|
|
11
|
+
which: Annotated[Optional[str], typer.Option(..., "--which", "-w", help="Specific items to process")] = None,
|
|
12
|
+
interactive: Annotated[bool, typer.Option(..., "--interactive", "-ia", help="Run in interactive mode")] = False):
|
|
13
13
|
"""🔗 Manage private configuration files."""
|
|
14
14
|
import machineconfig.profile.create_links_export as create_links_export
|
|
15
15
|
create_links_export.main_private_from_parser(method=method, on_conflict=on_conflict, which=which, interactive=interactive)
|
|
16
16
|
|
|
17
|
-
def public(method: Literal["symlink", "copy"]
|
|
18
|
-
on_conflict: Literal["throwError", "overwriteDefaultPath", "backupDefaultPath"]
|
|
19
|
-
which: Optional[str]
|
|
20
|
-
interactive: bool
|
|
17
|
+
def public(method: Annotated[Literal["symlink", "copy"], typer.Option(..., "--method", "-m", help="Method to use for setting up the config file.")],
|
|
18
|
+
on_conflict: Annotated[Literal["throwError", "overwriteDefaultPath", "backupDefaultPath"], typer.Option(..., "--on-conflict", "-o", help="Action to take on conflict")] = "throwError",
|
|
19
|
+
which: Annotated[Optional[str], typer.Option(..., "--which", "-w", help="Specific items to process")] = None,
|
|
20
|
+
interactive: Annotated[bool, typer.Option(..., "--interactive", "-ia", help="Run in interactive mode")] = False):
|
|
21
21
|
"""🔗 Manage public configuration files."""
|
|
22
22
|
import machineconfig.profile.create_links_export as create_links_export
|
|
23
23
|
create_links_export.main_public_from_parser(method=method, on_conflict=on_conflict, which=which, interactive=interactive)
|
|
@@ -42,7 +42,7 @@ def path():
|
|
|
42
42
|
from pathlib import Path
|
|
43
43
|
path = Path(navigator.__file__).resolve().parent.joinpath("path_manager_tui.py")
|
|
44
44
|
from machineconfig.utils.code import run_shell_script
|
|
45
|
-
run_shell_script(f"""uv run --with "machineconfig>=5.
|
|
45
|
+
run_shell_script(f"""uv run --with "machineconfig>=5.87,textual" {path}""")
|
|
46
46
|
|
|
47
47
|
def pwsh_theme():
|
|
48
48
|
"""🔗 Select powershell prompt theme."""
|
|
@@ -51,7 +51,7 @@ def pwsh_theme():
|
|
|
51
51
|
import subprocess
|
|
52
52
|
subprocess.run(["pwsh", "-File", str(file)])
|
|
53
53
|
|
|
54
|
-
def copy_assets(which: Literal["scripts", "settings", "both"]
|
|
54
|
+
def copy_assets(which: Annotated[Literal["scripts", "settings", "both"], typer.Argument(..., help="Which assets to copy")]):
|
|
55
55
|
"""🔗 Copy asset files from library to machine."""
|
|
56
56
|
import machineconfig.profile.create_helper as create_helper
|
|
57
57
|
match which:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import machineconfig.scripts.python.devops_helpers.cli_terminal as cli_terminal
|
|
3
3
|
import machineconfig.scripts.python.devops_helpers.cli_share_server as cli_share_server
|
|
4
4
|
import typer
|
|
5
|
-
from typing import Optional
|
|
5
|
+
from typing import Optional, Annotated
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
@@ -19,10 +19,10 @@ def install_ssh_server():
|
|
|
19
19
|
run_shell_script(script=SSH_SERVER.read_text(encoding="utf-8"))
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def add_ssh_key(path: Optional[str]
|
|
23
|
-
choose: bool
|
|
24
|
-
value: bool
|
|
25
|
-
github: Optional[str]
|
|
22
|
+
def add_ssh_key(path: Annotated[Optional[str], typer.Option(..., help="Path to the public key file")] = None,
|
|
23
|
+
choose: Annotated[bool, typer.Option(..., "--choose", "-c", help="Choose from available public keys in ~/.ssh/*.pub")] = False,
|
|
24
|
+
value: Annotated[bool, typer.Option(..., "--value", "-v", help="Paste the public key content manually")] = False,
|
|
25
|
+
github: Annotated[Optional[str], typer.Option(..., "--github", "-g", help="Fetch public keys from a GitHub username")] = None
|
|
26
26
|
):
|
|
27
27
|
"""🔑 SSH add pub key to this machine so its accessible by owner of corresponding private key."""
|
|
28
28
|
import machineconfig.scripts.python.nw.devops_add_ssh_key as helper
|
|
@@ -49,7 +49,8 @@ def debug_ssh():
|
|
|
49
49
|
import machineconfig.scripts.python.nw.ssh_debug_linux as helper
|
|
50
50
|
helper.ssh_debug_linux()
|
|
51
51
|
elif system() == "Windows":
|
|
52
|
-
|
|
52
|
+
import machineconfig.scripts.python.nw.ssh_debug_windows as helper
|
|
53
|
+
helper.ssh_debug_windows()
|
|
53
54
|
else:
|
|
54
55
|
raise NotImplementedError(f"Platform {system()} is not supported.")
|
|
55
56
|
|
|
@@ -87,26 +87,26 @@ def analyze(directory: DirectoryArgument = None) -> None:
|
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
def viz(
|
|
90
|
-
repo: str
|
|
91
|
-
output_file: Optional[Path]
|
|
92
|
-
resolution: str
|
|
93
|
-
seconds_per_day: float
|
|
94
|
-
auto_skip_seconds: float
|
|
95
|
-
title: Optional[str]
|
|
96
|
-
hide_items: list[str]
|
|
97
|
-
key_items: bool
|
|
98
|
-
fullscreen: bool
|
|
99
|
-
viewport: Optional[str]
|
|
100
|
-
start_date: Optional[str]
|
|
101
|
-
stop_date: Optional[str]
|
|
102
|
-
user_image_dir: Optional[Path]
|
|
103
|
-
max_files: int
|
|
104
|
-
max_file_lag: float
|
|
105
|
-
file_idle_time: int
|
|
106
|
-
framerate: int
|
|
107
|
-
background_color: str
|
|
108
|
-
font_size: int
|
|
109
|
-
camera_mode: str
|
|
90
|
+
repo: Annotated[str, typer.Option(..., "--repo", "-r", help="Path to git repository to visualize")] = Path.cwd().__str__(),
|
|
91
|
+
output_file: Annotated[Optional[Path], typer.Option(..., "--output", "-o", help="Output video file (e.g., output.mp4). If specified, gource will render to video.")] = None,
|
|
92
|
+
resolution: Annotated[str, typer.Option(..., "--resolution", "-res", help="Video resolution (e.g., 1920x1080, 1280x720)")] = "1920x1080",
|
|
93
|
+
seconds_per_day: Annotated[float, typer.Option(..., "--seconds-per-day", "-spd", help="Speed of simulation (lower = faster)")] = 0.1,
|
|
94
|
+
auto_skip_seconds: Annotated[float, typer.Option(..., "--auto-skip-seconds", "-as", help="Skip to next entry if nothing happens for X seconds")] = 1.0,
|
|
95
|
+
title: Annotated[Optional[str], typer.Option(..., "--title", "-t", help="Title for the visualization")] = None,
|
|
96
|
+
hide_items: Annotated[list[str], typer.Option(..., "--hide", "-h", help="Items to hide: bloom, date, dirnames, files, filenames, mouse, progress, root, tree, users, usernames")] = [],
|
|
97
|
+
key_items: Annotated[bool, typer.Option(..., "--key", "-k", help="Show file extension key")] = False,
|
|
98
|
+
fullscreen: Annotated[bool, typer.Option(..., "--fullscreen", "-f", help="Run in fullscreen mode")] = False,
|
|
99
|
+
viewport: Annotated[Optional[str], typer.Option(..., "--viewport", "-v", help="Camera viewport (e.g., '1000x1000')")] = None,
|
|
100
|
+
start_date: Annotated[Optional[str], typer.Option(..., "--start-date", help="Start date (YYYY-MM-DD)")] = None,
|
|
101
|
+
stop_date: Annotated[Optional[str], typer.Option(..., "--stop-date", help="Stop date (YYYY-MM-DD)")] = None,
|
|
102
|
+
user_image_dir: Annotated[Optional[Path], typer.Option(..., "--user-image-dir", help="Directory with user avatar images")] = None,
|
|
103
|
+
max_files: Annotated[int, typer.Option(..., "--max-files", help="Maximum number of files to show (0 = no limit)")] = 0,
|
|
104
|
+
max_file_lag: Annotated[float, typer.Option(..., "--max-file-lag", help="Max time files remain on screen after last change")] = 5.0,
|
|
105
|
+
file_idle_time: Annotated[int, typer.Option(..., "--file-idle-time", help="Time in seconds files remain idle before being removed")] = 0,
|
|
106
|
+
framerate: Annotated[int, typer.Option(..., "--framerate", help="Frames per second for video output")] = 60,
|
|
107
|
+
background_color: Annotated[str, typer.Option(..., "--background-color", help="Background color in hex (e.g., 000000 for black)")] = "000000",
|
|
108
|
+
font_size: Annotated[int, typer.Option(..., "--font-size", help="Font size")] = 22,
|
|
109
|
+
camera_mode: Annotated[str, typer.Option(..., "--camera-mode", help="Camera mode: overview or track")] = "overview",
|
|
110
110
|
) -> None:
|
|
111
111
|
"""🎬 Visualize repository activity using Gource."""
|
|
112
112
|
from machineconfig.scripts.python.helpers_repos.grource import visualize
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import typer
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Optional, Annotated
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def update():
|
|
@@ -41,9 +41,9 @@ def install():
|
|
|
41
41
|
# main_public_from_parser()
|
|
42
42
|
import platform
|
|
43
43
|
if platform.system() == "Windows":
|
|
44
|
-
run_shell_script(r"""$HOME\.local\bin\uv.exe tool install machineconfig>=5.
|
|
44
|
+
run_shell_script(r"""$HOME\.local\bin\uv.exe tool install machineconfig>=5.87""")
|
|
45
45
|
else:
|
|
46
|
-
run_shell_script("""$HOME/.local/bin/uv tool install machineconfig>=5.
|
|
46
|
+
run_shell_script("""$HOME/.local/bin/uv tool install machineconfig>=5.87""")
|
|
47
47
|
|
|
48
48
|
def navigate():
|
|
49
49
|
"""📚 NAVIGATE command structure with TUI"""
|
|
@@ -51,11 +51,11 @@ def navigate():
|
|
|
51
51
|
from pathlib import Path
|
|
52
52
|
path = Path(navigator.__file__).resolve().parent.joinpath("devops_navigator.py")
|
|
53
53
|
from machineconfig.utils.code import run_shell_script
|
|
54
|
-
run_shell_script(f"""uv run --with "machineconfig>=5.
|
|
54
|
+
run_shell_script(f"""uv run --with "machineconfig>=5.87,textual" {path}""")
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
def run_python(ip: str
|
|
58
|
-
command: Optional[bool]
|
|
57
|
+
def run_python(ip: Annotated[str, typer.Argument(..., help="Python command to run in the machineconfig environment")],
|
|
58
|
+
command: Annotated[Optional[bool], typer.Option(..., "--command", "-c", help="Run as command")] = False):
|
|
59
59
|
"""🐍 RUN python command/file in the machineconfig environment"""
|
|
60
60
|
if command:
|
|
61
61
|
exec(ip)
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
from typing import Optional, Annotated
|
|
3
3
|
import typer
|
|
4
|
-
# import typer
|
|
5
|
-
|
|
6
4
|
|
|
7
5
|
|
|
8
6
|
def display_share_url(local_ip_v4: str, port: int, protocol: str = "http") -> None:
|
|
9
7
|
"""Display a flashy, unmissable share URL announcement."""
|
|
10
|
-
|
|
11
8
|
from rich.console import Console
|
|
12
9
|
from rich.panel import Panel
|
|
13
10
|
from rich.text import Text
|
|
14
11
|
from rich.align import Align
|
|
15
12
|
console = Console()
|
|
16
|
-
|
|
17
13
|
# Create the main message with styling
|
|
18
14
|
url_text = Text(f"{protocol}://{local_ip_v4}:{port}", style="bold bright_cyan underline")
|
|
19
15
|
message = Text.assemble(
|
|
@@ -22,7 +18,6 @@ def display_share_url(local_ip_v4: str, port: int, protocol: str = "http") -> No
|
|
|
22
18
|
url_text,
|
|
23
19
|
(" 🚀", "bright_red")
|
|
24
20
|
)
|
|
25
|
-
|
|
26
21
|
# Create a fancy panel with borders and styling
|
|
27
22
|
panel = Panel(
|
|
28
23
|
Align.center(message),
|
|
@@ -32,7 +27,6 @@ def display_share_url(local_ip_v4: str, port: int, protocol: str = "http") -> No
|
|
|
32
27
|
padding=(1, 2),
|
|
33
28
|
expand=False
|
|
34
29
|
)
|
|
35
|
-
|
|
36
30
|
# Print with extra spacing and attention-grabbing elements
|
|
37
31
|
console.print(panel)
|
|
38
32
|
|
|
@@ -45,9 +39,8 @@ def main(
|
|
|
45
39
|
over_internet: Annotated[bool, typer.Option("--over-internet", "-i", help="Expose the share server over the internet using ngrok")] = False
|
|
46
40
|
) -> None:
|
|
47
41
|
from machineconfig.utils.installer_utils.installer import install_if_missing
|
|
48
|
-
install_if_missing("ezshare")
|
|
49
|
-
if over_internet: install_if_missing("ngrok")
|
|
50
|
-
|
|
42
|
+
install_if_missing(which="ezshare")
|
|
43
|
+
if over_internet: install_if_missing(which="ngrok", )
|
|
51
44
|
if username is None:
|
|
52
45
|
import getpass
|
|
53
46
|
username = getpass.getuser()
|
|
@@ -10,18 +10,18 @@ from machineconfig.utils.code import get_shell_file_executing_python_script, wri
|
|
|
10
10
|
|
|
11
11
|
import platform
|
|
12
12
|
import subprocess
|
|
13
|
-
from typing import Optional, Literal
|
|
13
|
+
from typing import Optional, Literal, Annotated
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
console = Console()
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def main(
|
|
20
|
-
cloud: Optional[str]
|
|
21
|
-
repo: Optional[str]
|
|
22
|
-
message: Optional[str]
|
|
23
|
-
on_conflict: Literal["ask", "push-local-merge", "overwrite-local", "stop-on-conflict", "remove-rclone-conflict"]
|
|
24
|
-
pwd: Optional[str]
|
|
20
|
+
cloud: Annotated[Optional[str], typer.Option(..., "--cloud", "-c", help="Cloud storage profile name. If not provided, uses default from config.")] = None,
|
|
21
|
+
repo: Annotated[Optional[str], typer.Option(..., "--repo", "-r", help="Path to the local repository. Defaults to current working directory.")] = None,
|
|
22
|
+
message: Annotated[Optional[str], typer.Option(..., "--message", "-m", help="Commit message for local changes.")] = None,
|
|
23
|
+
on_conflict: Annotated[Literal["ask", "push-local-merge", "overwrite-local", "stop-on-conflict", "remove-rclone-conflict"], typer.Option(..., "--on-conflict", "-oc", help="Action to take on merge conflict. Default is 'ask'.")] = "ask",
|
|
24
|
+
pwd: Annotated[Optional[str], typer.Option(..., "--password", help="Password for encryption/decryption of the remote repository.")] = None,
|
|
25
25
|
):
|
|
26
26
|
if cloud is None:
|
|
27
27
|
try:
|
|
@@ -101,7 +101,7 @@ git pull originEnc master
|
|
|
101
101
|
return "done"
|
|
102
102
|
from machineconfig.utils.meta import function_to_script
|
|
103
103
|
program_1_py = function_to_script(func=func2, call_with_args=None, call_with_kwargs={"remote_repo": str(repo_remote_root), "local_repo": str(repo_local_root), "cloud": cloud_resolved})
|
|
104
|
-
shell_file_1 = get_shell_file_executing_python_script(python_script=program_1_py, ve_path=None, executable="""uv run --with "machineconfig>=5.
|
|
104
|
+
shell_file_1 = get_shell_file_executing_python_script(python_script=program_1_py, ve_path=None, executable="""uv run --with "machineconfig>=5.87" """)
|
|
105
105
|
# ================================================================================
|
|
106
106
|
option2 = "Delete local repo and replace it with remote copy:"
|
|
107
107
|
program_2 = f"""
|
|
@@ -122,7 +122,7 @@ sudo chmod +x $HOME/dotfiles/scripts/linux -R
|
|
|
122
122
|
inspect_repos(repo_local_root=repo_local_root, repo_remote_root=repo_remote_root)
|
|
123
123
|
return "done"
|
|
124
124
|
program_3_py = function_to_script(func=func, call_with_args=None, call_with_kwargs={"repo_local_root": str(repo_local_root), "repo_remote_root": str(repo_remote_root)})
|
|
125
|
-
shell_file_3 = get_shell_file_executing_python_script(python_script=program_3_py, ve_path=None, executable="""uv run --with "machineconfig>=5.
|
|
125
|
+
shell_file_3 = get_shell_file_executing_python_script(python_script=program_3_py, ve_path=None, executable="""uv run --with "machineconfig>=5.87" """)
|
|
126
126
|
# ================================================================================
|
|
127
127
|
|
|
128
128
|
option4 = "Remove problematic rclone file from repo and replace with remote:"
|
|
@@ -319,7 +319,7 @@ def visualize(
|
|
|
319
319
|
|
|
320
320
|
|
|
321
321
|
def install(
|
|
322
|
-
version: Optional[str]
|
|
322
|
+
version: Annotated[Optional[str], typer.Option(..., "--version", "-v", help="Gource version to install")] = "0.53",
|
|
323
323
|
) -> None:
|
|
324
324
|
"""Install portable Gource on Windows (no admin privileges required)."""
|
|
325
325
|
if platform.system() == "Windows":
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
|
|
2
2
|
import typer
|
|
3
|
-
from typing import Optional, Literal
|
|
3
|
+
from typing import Optional, Literal, Annotated
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def main(
|
|
8
|
-
cloud: Optional[str]
|
|
9
|
-
repo: Optional[str]
|
|
10
|
-
message: Optional[str]
|
|
11
|
-
on_conflict: Literal["ask", "push-local-merge", "overwrite-local", "stop-on-conflict", "remove-rclone-conflict"]
|
|
12
|
-
pwd: Optional[str]
|
|
8
|
+
cloud: Annotated[Optional[str], typer.Option(..., "--cloud", "-c", help="Cloud storage profile name. If not provided, uses default from config.")] = None,
|
|
9
|
+
repo: Annotated[Optional[str], typer.Option(..., "--repo", "-r", help="Path to the local repository. Defaults to cwd.")] = Path.cwd().as_posix(),
|
|
10
|
+
message: Annotated[Optional[str], typer.Option(..., "--message", "-m", help="Commit message for local changes.")] = None,
|
|
11
|
+
on_conflict: Annotated[Literal["ask", "push-local-merge", "overwrite-local", "stop-on-conflict", "remove-rclone-conflict"], typer.Option(..., "--on-conflict", "-oc", help="Action to take on merge conflict. Default is 'ask'.")] = "ask",
|
|
12
|
+
pwd: Annotated[Optional[str], typer.Option(..., "--password", help="Password for encryption/decryption of the remote repository.")] = None,
|
|
13
13
|
):
|
|
14
14
|
from machineconfig.scripts.python.helpers_repos.cloud_repo_sync import main as program_content
|
|
15
15
|
program_content(cloud=cloud, repo=repo, message=message, on_conflict=on_conflict, pwd=pwd)
|
|
@@ -130,9 +130,9 @@ def execute_installations(selected_options: list[str]) -> None:
|
|
|
130
130
|
console.print(Panel("🐍 [bold green]PYTHON ENVIRONMENT[/bold green]\n[italic]Virtual environment setup[/italic]", border_style="green"))
|
|
131
131
|
import platform
|
|
132
132
|
if platform.system() == "Windows":
|
|
133
|
-
run_shell_script(r"""$HOME\.local\bin\uv.exe tool install machineconfig>=5.
|
|
133
|
+
run_shell_script(r"""$HOME\.local\bin\uv.exe tool install machineconfig>=5.87""")
|
|
134
134
|
else:
|
|
135
|
-
run_shell_script("""$HOME/.local/bin/uv tool install machineconfig>=5.
|
|
135
|
+
run_shell_script("""$HOME/.local/bin/uv tool install machineconfig>=5.87""")
|
|
136
136
|
if "install_ssh_server" in selected_options:
|
|
137
137
|
console.print(Panel("🔒 [bold red]SSH SERVER[/bold red]\n[italic]Remote access setup[/italic]", border_style="red"))
|
|
138
138
|
import platform
|
|
@@ -6,7 +6,7 @@ from machineconfig.utils.path_extended import PathExtended
|
|
|
6
6
|
from rich.console import Console
|
|
7
7
|
from rich.panel import Panel
|
|
8
8
|
from rich import box # Import box
|
|
9
|
-
from typing import Optional
|
|
9
|
+
from typing import Optional, Annotated
|
|
10
10
|
import typer
|
|
11
11
|
|
|
12
12
|
|
|
@@ -77,10 +77,10 @@ sudo service ssh --full-restart
|
|
|
77
77
|
"""
|
|
78
78
|
|
|
79
79
|
|
|
80
|
-
def main(pub_path: Optional[str]
|
|
81
|
-
pub_choose: bool
|
|
82
|
-
pub_val: bool
|
|
83
|
-
from_github: Optional[str]
|
|
80
|
+
def main(pub_path: Annotated[Optional[str], typer.Argument(..., help="Path to the public key file")] = None,
|
|
81
|
+
pub_choose: Annotated[bool, typer.Option(..., "--choose", "-c", help="Choose from available public keys in ~/.ssh")] = False,
|
|
82
|
+
pub_val: Annotated[bool, typer.Option(..., "--paste", "-p", help="Paste the public key content manually")] = False,
|
|
83
|
+
from_github: Annotated[Optional[str], typer.Option(..., "--from-github", "-g", help="Fetch public keys from a GitHub username")] = None
|
|
84
84
|
) -> None:
|
|
85
85
|
if pub_path:
|
|
86
86
|
key_path = PathExtended(pub_path).expanduser().absolute()
|
|
@@ -6,7 +6,7 @@ from machineconfig.utils.path_extended import PathExtended
|
|
|
6
6
|
from rich.console import Console
|
|
7
7
|
from rich.panel import Panel
|
|
8
8
|
from rich import box
|
|
9
|
-
from typing import Optional
|
|
9
|
+
from typing import Optional, Annotated
|
|
10
10
|
import typer
|
|
11
11
|
|
|
12
12
|
|
|
@@ -66,10 +66,10 @@ sudo service ssh --full-restart
|
|
|
66
66
|
return program
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
def main(pub_path: Optional[str]
|
|
70
|
-
pub_choose: bool
|
|
71
|
-
pub_val: bool
|
|
72
|
-
from_github: Optional[str]
|
|
69
|
+
def main(pub_path: Annotated[Optional[str], typer.Argument(..., help="Path to the public key file")] = None,
|
|
70
|
+
pub_choose: Annotated[bool, typer.Option(..., "--choose", "-c", help="Choose from available public keys in ~/.ssh")] = False,
|
|
71
|
+
pub_val: Annotated[bool, typer.Option(..., "--paste", "-p", help="Paste the public key content manually")] = False,
|
|
72
|
+
from_github: Annotated[Optional[str], typer.Option(..., "--from-github", "-g", help="Fetch public keys from a GitHub username")] = None
|
|
73
73
|
) -> None:
|
|
74
74
|
|
|
75
75
|
if pub_path:
|
|
@@ -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.14 --with "machineconfig>=5.
|
|
8
|
+
uv run --python 3.14 --with "machineconfig>=5.87" 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."
|