machineconfig 6.51__py3-none-any.whl → 6.53__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 +3 -3
- machineconfig/jobs/installer/check_installations.py +0 -1
- machineconfig/jobs/installer/installer_data.json +17 -0
- machineconfig/scripts/python/croshell.py +4 -4
- machineconfig/scripts/python/env_manager/path_manager_tui.py +1 -1
- machineconfig/scripts/python/fire_jobs.py +9 -7
- machineconfig/scripts/python/helpers_devops/cli_config.py +3 -2
- machineconfig/scripts/python/helpers_devops/cli_self.py +3 -3
- machineconfig/scripts/python/helpers_devops/cli_utils.py +43 -0
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +24 -20
- machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +1 -1
- machineconfig/scripts/python/helpers_repos/sync.py +5 -5
- machineconfig/scripts/python/nw/mount_nfs +1 -1
- machineconfig/scripts/windows/mounts/mount_ssh.ps1 +1 -1
- machineconfig/setup_linux/web_shortcuts/interactive.sh +1 -1
- machineconfig/setup_mac/__init__.py +17 -0
- machineconfig/setup_mac/apps.sh +73 -0
- machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
- machineconfig/setup_mac/uv.sh +36 -0
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +1 -1
- machineconfig/utils/code.py +46 -84
- machineconfig/utils/installer.py +8 -3
- machineconfig/utils/meta.py +5 -251
- machineconfig/utils/scheduling.py +0 -1
- machineconfig/utils/ssh.py +46 -45
- {machineconfig-6.51.dist-info → machineconfig-6.53.dist-info}/METADATA +1 -1
- {machineconfig-6.51.dist-info → machineconfig-6.53.dist-info}/RECORD +30 -26
- {machineconfig-6.51.dist-info → machineconfig-6.53.dist-info}/WHEEL +0 -0
- {machineconfig-6.51.dist-info → machineconfig-6.53.dist-info}/entry_points.txt +0 -0
- {machineconfig-6.51.dist-info → machineconfig-6.53.dist-info}/top_level.txt +0 -0
|
@@ -5,13 +5,13 @@ from machineconfig.utils.schemas.layouts.layout_types import TabConfig, LayoutCo
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
7
|
def get_fire_command_and_artifact_files(func: FunctionType):
|
|
8
|
-
from machineconfig.utils.meta import
|
|
9
|
-
py_script =
|
|
8
|
+
from machineconfig.utils.meta import lambda_to_defstring
|
|
9
|
+
py_script = lambda_to_defstring(lmb=lambda: func, in_global=True)
|
|
10
10
|
from machineconfig.utils.accessories import randstr
|
|
11
11
|
py_script_path = Path.home().joinpath("tmp_results", "tmp_py_scripts", f"tmp_{randstr(10)}.py")
|
|
12
12
|
py_script_path.parent.mkdir(parents=True, exist_ok=True)
|
|
13
13
|
py_script_path.write_text(py_script, encoding="utf-8")
|
|
14
|
-
command_to_run = f"uv run
|
|
14
|
+
command_to_run = f"uv run {py_script_path}"
|
|
15
15
|
tab_config: TabConfig = {
|
|
16
16
|
"command": command_to_run,
|
|
17
17
|
"startDir": "$HOME",
|
|
@@ -221,7 +221,6 @@ APP_SUMMARY_PATH = CONFIG_ROOT.joinpath(f"profile/records/{platform.system().low
|
|
|
221
221
|
# # cli_installers = get_cli_py_installers()
|
|
222
222
|
# # else: raise NotImplementedError(f"Platform {platform.system().lower()} is not supported yet.")
|
|
223
223
|
|
|
224
|
-
# if name == "essentials":
|
|
225
224
|
# print(f"""
|
|
226
225
|
# {'=' * 150}
|
|
227
226
|
# 📥 DOWNLOAD | Downloading {len(self.data)} apps...
|
|
@@ -2144,6 +2144,23 @@
|
|
|
2144
2144
|
}
|
|
2145
2145
|
}
|
|
2146
2146
|
},
|
|
2147
|
+
{
|
|
2148
|
+
"appName": "cline",
|
|
2149
|
+
"repoURL": "CMD",
|
|
2150
|
+
"doc": "Cline agent extension in the terminal",
|
|
2151
|
+
"fileNamePattern": {
|
|
2152
|
+
"amd64": {
|
|
2153
|
+
"linux": "npm install -g cline",
|
|
2154
|
+
"windows": "npm install -g cline",
|
|
2155
|
+
"macos": "npm install -g cline"
|
|
2156
|
+
},
|
|
2157
|
+
"arm64": {
|
|
2158
|
+
"linux": "npm install -g cline",
|
|
2159
|
+
"windows": "npm install -g cline",
|
|
2160
|
+
"macos": "npm install -g cline"
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
},
|
|
2147
2164
|
{
|
|
2148
2165
|
"appName": "copilot",
|
|
2149
2166
|
"repoURL": "CMD",
|
|
@@ -127,7 +127,7 @@ def croshell(
|
|
|
127
127
|
fire_line = f"uv run --with visidata,pyarrow vd {str(file_obj)}"
|
|
128
128
|
elif marimo:
|
|
129
129
|
if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--with marimo --project "{str(Path.home().joinpath("code/machineconfig"))}" """
|
|
130
|
-
else: requirements = """--with "marimo,machineconfig[plot]>=6.
|
|
130
|
+
else: requirements = """--with "marimo,machineconfig[plot]>=6.52" """
|
|
131
131
|
fire_line = f"""
|
|
132
132
|
cd {str(pyfile.parent)}
|
|
133
133
|
uv run --with "marimo" marimo convert {pyfile.name} -o marimo_nb.py
|
|
@@ -135,14 +135,14 @@ uv run {requirements} marimo edit --host 0.0.0.0 marimo_nb.py
|
|
|
135
135
|
"""
|
|
136
136
|
elif jupyter:
|
|
137
137
|
if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" --with jupyterlab """
|
|
138
|
-
else: requirements = """--with "machineconfig[plot]>=6.
|
|
138
|
+
else: requirements = """--with "machineconfig[plot]>=6.52" """
|
|
139
139
|
fire_line = f"uv run {requirements} jupyter-lab {str(nb_target)}"
|
|
140
140
|
elif vscode:
|
|
141
141
|
fire_line = f"""
|
|
142
142
|
cd {str(pyfile.parent)}
|
|
143
143
|
uv init --python 3.14
|
|
144
144
|
uv venv
|
|
145
|
-
uv add "machineconfig[plot]>=6.
|
|
145
|
+
uv add "machineconfig[plot]>=6.52"
|
|
146
146
|
# code serve-web
|
|
147
147
|
code --new-window {str(pyfile)}
|
|
148
148
|
"""
|
|
@@ -150,7 +150,7 @@ code --new-window {str(pyfile)}
|
|
|
150
150
|
if interpreter == "ipython": profile = f" --profile {ipython_profile} --no-banner"
|
|
151
151
|
else: profile = ""
|
|
152
152
|
if Path.home().joinpath("code/machineconfig").exists(): ve_line = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" """
|
|
153
|
-
else: ve_line = """--with "machineconfig[plot]>=6.
|
|
153
|
+
else: ve_line = """--with "machineconfig[plot]>=6.52" """
|
|
154
154
|
# ve_path_maybe, ipython_profile_maybe = get_ve_path_and_ipython_profile(Path.cwd())
|
|
155
155
|
# --python 3.14
|
|
156
156
|
fire_line = f"uv run {ve_line} {interpreter} {interactivity} {profile} {str(pyfile)}"
|
|
@@ -204,19 +204,22 @@ def fire(
|
|
|
204
204
|
cmd: Annotated[bool, typer.Option("--cmd", "-B", help="Create a cmd fire command to launch the job asynchronously")] = False,
|
|
205
205
|
interactive: Annotated[bool, typer.Option("--interactive", "-i", help="Whether to run the job interactively using IPython")] = False,
|
|
206
206
|
debug: Annotated[bool, typer.Option("--debug", "-d", help="Enable debug mode")] = False,
|
|
207
|
-
choose_function: Annotated[bool, typer.Option("--
|
|
207
|
+
choose_function: Annotated[bool, typer.Option("--choose-function", "-c", help="Choose function interactively")] = False,
|
|
208
208
|
loop: Annotated[bool, typer.Option("--loop", "-l", help="Infinite recursion (runs again after completion/interruption)")] = False,
|
|
209
209
|
jupyter: Annotated[bool, typer.Option("--jupyter", "-j", help="Open in a jupyter notebook")] = False,
|
|
210
|
-
submit_to_cloud: Annotated[bool, typer.Option("--submit_to_cloud", "-C", help="Submit to cloud compute")] = False,
|
|
211
|
-
remote: Annotated[bool, typer.Option("--remote", "-r", help="Launch on a remote machine")] = False,
|
|
212
210
|
module: Annotated[bool, typer.Option("--module", "-m", help="Launch the main file")] = False,
|
|
211
|
+
optimized: Annotated[bool, typer.Option("--optimized", "-O", help="Run the optimized version of the function")] = False,
|
|
212
|
+
zellij_tab: Annotated[Optional[str], typer.Option("--zellij-tab", "-z", help="Open in a new zellij tab")] = None,
|
|
213
|
+
|
|
214
|
+
submit_to_cloud: Annotated[bool, typer.Option("--submit-to-cloud", "-C", help="Submit to cloud compute")] = False,
|
|
215
|
+
remote: Annotated[bool, typer.Option("--remote", "-r", help="Launch on a remote machine")] = False,
|
|
216
|
+
|
|
213
217
|
streamlit: Annotated[bool, typer.Option("--streamlit", "-S", help="Run as streamlit app")] = False,
|
|
214
218
|
environment: Annotated[str, typer.Option("--environment", "-E", help="Choose ip, localhost, hostname or arbitrary url")] = "",
|
|
215
219
|
holdDirectory: Annotated[bool, typer.Option("--holdDirectory", "-D", help="Hold current directory and avoid cd'ing to the script directory")] = False,
|
|
216
220
|
PathExport: Annotated[bool, typer.Option("--PathExport", "-P", help="Augment the PYTHONPATH with repo root")] = False,
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
zellij_tab: Annotated[Optional[str], typer.Option("--zellij_tab", "-z", help="Open in a new zellij tab")] = None,
|
|
221
|
+
|
|
222
|
+
git_pull: Annotated[bool, typer.Option("--git-pull", "-g", help="Start by pulling the git repo")] = False,
|
|
220
223
|
watch: Annotated[bool, typer.Option("--watch", "-w", help="Watch the file for changes")] = False,
|
|
221
224
|
) -> None:
|
|
222
225
|
"""Main function to process fire jobs arguments."""
|
|
@@ -254,7 +257,6 @@ def fire(
|
|
|
254
257
|
except Exception as e:
|
|
255
258
|
# For other exceptions, print clean error message and exit
|
|
256
259
|
import sys
|
|
257
|
-
|
|
258
260
|
print(f"❌ Error: {e}", file=sys.stderr)
|
|
259
261
|
sys.exit(1)
|
|
260
262
|
|
|
@@ -36,13 +36,14 @@ def shell():
|
|
|
36
36
|
from machineconfig.profile.create_shell_profile import create_default_shell_profile
|
|
37
37
|
create_default_shell_profile()
|
|
38
38
|
|
|
39
|
+
|
|
39
40
|
def path():
|
|
40
41
|
"""📚 NAVIGATE PATH variable with TUI"""
|
|
41
42
|
from machineconfig.scripts.python import env_manager as navigator
|
|
42
43
|
from pathlib import Path
|
|
43
44
|
path = Path(navigator.__file__).resolve().parent.joinpath("path_manager_tui.py")
|
|
44
45
|
from machineconfig.utils.code import run_shell_script
|
|
45
|
-
if not Path.home().joinpath("code/machineconfig").exists(): executable = """--with "machineconfig>=6.
|
|
46
|
+
if not Path.home().joinpath("code/machineconfig").exists(): executable = """--with "machineconfig>=6.52,textual" """
|
|
46
47
|
else: executable = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" --with textual"""
|
|
47
48
|
run_shell_script(f"""uv run {executable} {path}""")
|
|
48
49
|
|
|
@@ -78,7 +79,7 @@ def get_app():
|
|
|
78
79
|
config_apps.command("path", no_args_is_help=False, help="📚 [p] NAVIGATE PATH variable with TUI")(path)
|
|
79
80
|
config_apps.command("p", no_args_is_help=False, help="NAVIGATE PATH variable with TUI", hidden=True)(path)
|
|
80
81
|
config_apps.command("pwsh-theme", no_args_is_help=False, help="🔗 [t] Select powershell prompt theme.")(pwsh_theme)
|
|
81
|
-
config_apps.command("t", no_args_is_help=
|
|
82
|
+
config_apps.command("t", no_args_is_help=False, help="Select powershell prompt theme.", hidden=True)(pwsh_theme)
|
|
82
83
|
config_apps.command("copy-assets", no_args_is_help=True, help="🔗 [c] Copy asset files from library to machine.", hidden=False)(copy_assets)
|
|
83
84
|
config_apps.command("c", no_args_is_help=True, help="Copy asset files from library to machine.", hidden=True)(copy_assets)
|
|
84
85
|
return config_apps
|
|
@@ -40,9 +40,9 @@ def install(no_copy_assets: Annotated[bool, typer.Option("--no-assets-copy", "-n
|
|
|
40
40
|
else:
|
|
41
41
|
import platform
|
|
42
42
|
if platform.system() == "Windows":
|
|
43
|
-
run_shell_script(r"""$HOME\.local\bin\uv.exe tool install --upgrade "machineconfig>=6.
|
|
43
|
+
run_shell_script(r"""& "$HOME\.local\bin\uv.exe" tool install --upgrade "machineconfig>=6.52" """)
|
|
44
44
|
else:
|
|
45
|
-
run_shell_script("""$HOME/.local/bin/uv tool install --upgrade "machineconfig>=6.
|
|
45
|
+
run_shell_script("""$HOME/.local/bin/uv tool install --upgrade "machineconfig>=6.52" """)
|
|
46
46
|
from machineconfig.profile.create_shell_profile import create_default_shell_profile
|
|
47
47
|
if not no_copy_assets:
|
|
48
48
|
create_default_shell_profile() # involves copying assets too
|
|
@@ -67,7 +67,7 @@ def navigate():
|
|
|
67
67
|
path = Path(navigator.__file__).resolve().parent.joinpath("devops_navigator.py")
|
|
68
68
|
from machineconfig.utils.code import run_shell_script
|
|
69
69
|
if Path.home().joinpath("code/machineconfig").exists(): executable = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" --with textual"""
|
|
70
|
-
else: executable = """--with "machineconfig>=6.
|
|
70
|
+
else: executable = """--with "machineconfig>=6.52,textual" """
|
|
71
71
|
run_shell_script(f"""uv run {executable} {path}""")
|
|
72
72
|
|
|
73
73
|
|
|
@@ -78,8 +78,51 @@ def download(
|
|
|
78
78
|
raise typer.Exit(code=1)
|
|
79
79
|
|
|
80
80
|
|
|
81
|
+
def merge_pdfs(
|
|
82
|
+
pdf1: Annotated[str, typer.Argument(..., help="Path to the first PDF file.")],
|
|
83
|
+
pdf2: Annotated[str, typer.Argument(..., help="Path to the second PDF file.")],
|
|
84
|
+
output: Annotated[Optional[str], typer.Option("--output", "-o", help="Output merged PDF file path.")] = None,
|
|
85
|
+
compress: Annotated[bool, typer.Option("--compress", "-c", help="Compress the output PDF.")] = False,
|
|
86
|
+
) -> None:
|
|
87
|
+
def merge_pdfs_internal(pdf1: str, pdf2: str, output: Optional[str], compress: bool) -> None:
|
|
88
|
+
from pypdf import PdfReader, PdfWriter
|
|
89
|
+
writer = PdfWriter()
|
|
90
|
+
for pdf_path in [pdf1, pdf2]:
|
|
91
|
+
reader = PdfReader(pdf_path)
|
|
92
|
+
for page in reader.pages:
|
|
93
|
+
writer.add_page(page)
|
|
94
|
+
output_path = output if output else "merged.pdf"
|
|
95
|
+
if compress:
|
|
96
|
+
try:
|
|
97
|
+
for p in writer.pages:
|
|
98
|
+
try:
|
|
99
|
+
# PageObject.compress_content_streams exists in pypdf
|
|
100
|
+
p.compress_content_streams()
|
|
101
|
+
except Exception:
|
|
102
|
+
# best-effort: ignore per-page compression failures
|
|
103
|
+
continue
|
|
104
|
+
except Exception:
|
|
105
|
+
pass
|
|
106
|
+
try:
|
|
107
|
+
writer.compress_identical_objects()
|
|
108
|
+
except Exception:
|
|
109
|
+
# non-fatal if this fails
|
|
110
|
+
pass
|
|
111
|
+
writer.write(output_path)
|
|
112
|
+
print(f"✅ Merged PDF saved to: {output_path}")
|
|
113
|
+
from machineconfig.utils.meta import lambda_to_defstring
|
|
114
|
+
code = lambda_to_defstring(lambda : merge_pdfs_internal(pdf1=pdf1, pdf2=pdf2, output=output, compress=compress), in_global=True)
|
|
115
|
+
import tempfile
|
|
116
|
+
tmp_py_file = Path(tempfile.mkstemp(suffix=".py")[1])
|
|
117
|
+
tmp_py_file.write_text(code, encoding="utf-8")
|
|
118
|
+
from machineconfig.utils.code import run_shell_script
|
|
119
|
+
run_shell_script(f"""uv run --with pypdf {tmp_py_file} """)
|
|
120
|
+
|
|
121
|
+
|
|
81
122
|
def get_app() -> typer.Typer:
|
|
82
123
|
app = typer.Typer(help="🛠️ [u] utilities operations", no_args_is_help=True, add_help_option=False, add_completion=False)
|
|
83
124
|
app.command(name="download", no_args_is_help=True, help="[d] Download a file from a URL and optionally decompress it.")(download)
|
|
84
125
|
app.command(name="d", no_args_is_help=True, hidden=True)(download)
|
|
126
|
+
app.command(name="merge-pdfs", no_args_is_help=True, help="[m] Merge two PDF files into one.")(merge_pdfs)
|
|
127
|
+
app.command(name="m", no_args_is_help=True, hidden=True)(merge_pdfs)
|
|
85
128
|
return app
|
|
@@ -6,7 +6,7 @@ import typer
|
|
|
6
6
|
from machineconfig.utils.path_extended import PathExtended
|
|
7
7
|
from machineconfig.utils.terminal import Response
|
|
8
8
|
from machineconfig.utils.source_of_truth import CONFIG_ROOT, DEFAULTS_PATH
|
|
9
|
-
from machineconfig.utils.code import get_shell_file_executing_python_script
|
|
9
|
+
from machineconfig.utils.code import get_shell_file_executing_python_script
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
import platform
|
|
12
12
|
import subprocess
|
|
@@ -76,10 +76,17 @@ git pull originEnc master
|
|
|
76
76
|
|
|
77
77
|
"""
|
|
78
78
|
|
|
79
|
-
if Path.home().joinpath("code/machineconfig").exists():
|
|
80
|
-
|
|
79
|
+
if Path.home().joinpath("code/machineconfig").exists():
|
|
80
|
+
uv_project_dir = f"""{str(Path.home().joinpath("code/machineconfig"))}"""
|
|
81
|
+
uv_with = None
|
|
82
|
+
else:
|
|
83
|
+
uv_with = ["machineconfig>=6.52"]
|
|
84
|
+
uv_project_dir = None
|
|
85
|
+
|
|
86
|
+
import tempfile
|
|
87
|
+
shell_path = Path(tempfile.mkstemp(suffix=".ps1" if platform.system() == "Windows" else ".sh")[1])
|
|
88
|
+
shell_path.write_text(script, encoding="utf-8")
|
|
81
89
|
|
|
82
|
-
shell_path = write_shell_script_to_file(shell_script=script)
|
|
83
90
|
command = f". {shell_path}"
|
|
84
91
|
if platform.system() == "Windows":
|
|
85
92
|
completed = subprocess.run(["powershell", "-Command", command], capture_output=True, check=False, text=True)
|
|
@@ -100,20 +107,12 @@ git pull originEnc master
|
|
|
100
107
|
|
|
101
108
|
# ================================================================================
|
|
102
109
|
option1 = "Delete remote copy and push local:"
|
|
103
|
-
from machineconfig.utils.meta import
|
|
110
|
+
from machineconfig.utils.meta import lambda_to_defstring
|
|
104
111
|
def func2(remote_repo: str, local_repo: str, cloud: str):
|
|
105
112
|
from machineconfig.scripts.python.helpers_repos.sync import delete_remote_repo_copy_and_push_local
|
|
106
113
|
delete_remote_repo_copy_and_push_local(remote_repo=remote_repo, local_repo=local_repo, cloud=cloud)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
# from machineconfig.scripts.python.helpers_repos.sync import delete_remote_repo_copy_and_push_local
|
|
110
|
-
# delete_remote_repo_copy_and_push_local(remote_repo=remote_repo, local_repo=local_repo, cloud=cloud)
|
|
111
|
-
# return "done"
|
|
112
|
-
# program_1_py = function_to_script(func=func2, call_with_kwargs=None)
|
|
113
|
-
program_1_py = function_to_script(func=func2, call_with_kwargs={"remote_repo": str(repo_remote_root), "local_repo": str(repo_local_root), "cloud": cloud_resolved})
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
shell_file_1 = get_shell_file_executing_python_script(python_script=program_1_py, ve_path=None, executable=executable)
|
|
114
|
+
program_1_py = lambda_to_defstring(lambda: func2(remote_repo=str(repo_remote_root), local_repo=str(repo_local_root), cloud=str(cloud_resolved)), in_global=True)
|
|
115
|
+
shell_file_1 = get_shell_file_executing_python_script(python_script=program_1_py, uv_with=uv_with, uv_project_dir=uv_project_dir)
|
|
117
116
|
# ================================================================================
|
|
118
117
|
option2 = "Delete local repo and replace it with remote copy:"
|
|
119
118
|
program_2 = f"""
|
|
@@ -126,15 +125,19 @@ sudo chmod 600 $HOME/.ssh/*
|
|
|
126
125
|
sudo chmod 700 $HOME/.ssh
|
|
127
126
|
sudo chmod +x $HOME/dotfiles/scripts/linux -R
|
|
128
127
|
"""
|
|
129
|
-
|
|
128
|
+
import tempfile
|
|
129
|
+
shell_file_2 = Path(tempfile.mkstemp(suffix=".ps1" if platform.system() == "Windows" else ".sh")[1])
|
|
130
|
+
shell_file_2.write_text(program_2, encoding="utf-8")
|
|
131
|
+
|
|
130
132
|
# ================================================================================
|
|
131
133
|
option3 = "Inspect repos:"
|
|
132
134
|
def func(repo_local_root: str, repo_remote_root: str):
|
|
133
135
|
from machineconfig.scripts.python.helpers_repos.sync import inspect_repos
|
|
134
136
|
inspect_repos(repo_local_root=repo_local_root, repo_remote_root=repo_remote_root)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
137
|
+
# program_3_py = function_to_script(func=func, call_with_kwargs={"repo_local_root": str(repo_local_root), "repo_remote_root": str(repo_remote_root)})
|
|
138
|
+
# shell_file_3 = get_shell_file_executing_python_script(python_script=program_3_py, ve_path=None, executable=executable)
|
|
139
|
+
program_3_py = lambda_to_defstring(lambda: func(repo_local_root=str(repo_local_root), repo_remote_root=str(repo_remote_root)), in_global=True)
|
|
140
|
+
shell_file_3 = get_shell_file_executing_python_script(python_script=program_3_py, uv_with=uv_with, uv_project_dir=uv_project_dir)
|
|
138
141
|
# ================================================================================
|
|
139
142
|
|
|
140
143
|
option4 = "Remove problematic rclone file from repo and replace with remote:"
|
|
@@ -145,7 +148,8 @@ cd $HOME/dotfiles
|
|
|
145
148
|
git commit -am "finished merging"
|
|
146
149
|
. {shell_file_1}
|
|
147
150
|
"""
|
|
148
|
-
shell_file_4 =
|
|
151
|
+
shell_file_4 = Path(tempfile.mkstemp(suffix=".ps1" if platform.system() == "Windows" else ".sh")[1])
|
|
152
|
+
shell_file_4.write_text(program_4, encoding="utf-8")
|
|
149
153
|
# ================================================================================
|
|
150
154
|
|
|
151
155
|
console.print(Panel("🔄 RESOLVE MERGE CONFLICT\nChoose an option to resolve the conflict:", title_align="left", border_style="blue"))
|
|
@@ -8,7 +8,7 @@ def analyze_repo_development(repo_path: Annotated[str, typer.Argument(..., help=
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
count_lines_path = Path(count_lines.__file__)
|
|
10
10
|
# --project $HOME/code/ machineconfig --group plot
|
|
11
|
-
cmd = f"""uv run --python 3.14 --with "machineconfig[plot]>=6.
|
|
11
|
+
cmd = f"""uv run --python 3.14 --with "machineconfig[plot]>=6.52" {count_lines_path} analyze-over-time {repo_path}"""
|
|
12
12
|
from machineconfig.utils.code import run_shell_script
|
|
13
13
|
run_shell_script(cmd)
|
|
14
14
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from machineconfig.utils.path_extended import PathExtended
|
|
2
|
-
from machineconfig.utils.code import write_shell_script_to_file
|
|
3
2
|
import platform
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
from rich.console import Console
|
|
@@ -56,11 +55,12 @@ def inspect_repos(repo_local_root: str, repo_remote_root: str):
|
|
|
56
55
|
|
|
57
56
|
if platform.system() == "Windows":
|
|
58
57
|
program = get_wt_cmd(wd1=PathExtended(repo_local_root), wd2=PathExtended(repo_local_root))
|
|
59
|
-
write_shell_script_to_file(shell_script=program)
|
|
60
|
-
return None
|
|
61
58
|
elif platform.system() in ["Linux", "Darwin"]:
|
|
62
59
|
program = get_zellij_cmd(wd1=PathExtended(repo_local_root), wd2=PathExtended(repo_remote_root))
|
|
63
|
-
write_shell_script_to_file(shell_script=program)
|
|
64
|
-
return None
|
|
65
60
|
else:
|
|
66
61
|
raise NotImplementedError(f"Platform {platform.system()} not implemented.")
|
|
62
|
+
import tempfile
|
|
63
|
+
with tempfile.NamedTemporaryFile(mode='w', suffix=".sh" if platform.system() != "Windows" else ".ps1", delete=False, encoding='utf-8') as temp_file:
|
|
64
|
+
temp_file.write(program)
|
|
65
|
+
temp_script_path = PathExtended(temp_file.name)
|
|
66
|
+
console.print(Panel(f"🚀 Launching repo inspection tool...\n\n[blue]{temp_script_path}[/blue]", border_style="blue"))
|
|
@@ -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>=6.
|
|
8
|
+
uv run --python 3.14 --with "machineconfig>=6.52" 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."
|
|
@@ -7,7 +7,7 @@ $user = ''
|
|
|
7
7
|
$sharePath = ''
|
|
8
8
|
$driveLetter = ''
|
|
9
9
|
|
|
10
|
-
uv run --python 3.14 --with "machineconfig>=6.
|
|
10
|
+
uv run --python 3.14 --with "machineconfig>=6.52" python -m machineconfig.scripts.python.mount_ssh
|
|
11
11
|
|
|
12
12
|
net use T: \\sshfs.kr\$user@$host.local
|
|
13
13
|
# this worked: net use T: \\sshfs\alex@alex-p51s-5.local
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
. <( curl -sSL "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/uv.sh")
|
|
3
3
|
mcfg() {
|
|
4
|
-
"$HOME/.local/bin/uv" run --python 3.14 --with "machineconfig>=6.
|
|
4
|
+
"$HOME/.local/bin/uv" run --python 3.14 --with "machineconfig>=6.52" mcfg "$@"
|
|
5
5
|
}
|
|
6
6
|
alias d="mcfg devops"
|
|
7
7
|
alias c="mcfg cloud"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Mac setup module for machineconfig.
|
|
2
|
+
|
|
3
|
+
This module provides setup script locations and configurations for macOS systems.
|
|
4
|
+
It mirrors the layout used by the Linux setup module and exposes Path objects
|
|
5
|
+
pointing at common scripts (so other code can import these paths).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
# Path to main installer script for macOS
|
|
11
|
+
APPS = Path(__file__).parent.joinpath("apps.sh")
|
|
12
|
+
# Optional helper scripts (may or may not exist)
|
|
13
|
+
UV = Path(__file__).parent.joinpath("uv.sh")
|
|
14
|
+
# Path to macOS SSH helper
|
|
15
|
+
SSH_SETUP = Path(__file__).parent.joinpath("ssh/openssh_setup.sh")
|
|
16
|
+
|
|
17
|
+
__all__ = ["APPS", "UV", "SSH_SETUP"]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
4
|
+
echo "🔄 Updating Homebrew..."
|
|
5
|
+
brew update || true
|
|
6
|
+
|
|
7
|
+
# --GROUP:ESSENTIAL_SYSTEM:git,nano,curl,nvm,nodejs,brave-browser,visual-studio-code
|
|
8
|
+
echo "📥 Installing essential tools..."
|
|
9
|
+
echo "📥 Installing Git version control..."
|
|
10
|
+
echo "📥 Installing Nano text editor..."
|
|
11
|
+
echo "📥 Installing Node Version Manager (NVM)..."
|
|
12
|
+
# Note: git and nano are pre-installed on macOS, but we install via Homebrew to ensure latest versions
|
|
13
|
+
brew install git || true
|
|
14
|
+
brew install nano || true
|
|
15
|
+
brew install curl || true
|
|
16
|
+
# Install NVM
|
|
17
|
+
if [ ! -s "$HOME/.nvm/nvm.sh" ]; then
|
|
18
|
+
echo "📥 Installing NVM (Node Version Manager)..."
|
|
19
|
+
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
|
|
20
|
+
fi
|
|
21
|
+
echo "🔧 Configuring NVM environment..."
|
|
22
|
+
export NVM_DIR="$HOME/.nvm"
|
|
23
|
+
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
|
24
|
+
echo "📥 Installing latest Node.js..."
|
|
25
|
+
nvm install node || true
|
|
26
|
+
brew install --cask brave-browser || true
|
|
27
|
+
brew install --cask visual-studio-code || true
|
|
28
|
+
|
|
29
|
+
# Database tools
|
|
30
|
+
# echo "📥 Installing SQLite - lightweight SQL database..."
|
|
31
|
+
# echo "📥 Installing PostgreSQL client..."
|
|
32
|
+
# echo "📥 Installing Redis command-line tools..."
|
|
33
|
+
# brew install sqlite3 || true
|
|
34
|
+
# brew install postgresql || true
|
|
35
|
+
# brew install redis || true
|
|
36
|
+
|
|
37
|
+
# --GROUP:TerminalEyeCandy:fortune,toilet,sl,cmatrix,chafa
|
|
38
|
+
echo "📥 Installing fortune - random wisdom generator..."
|
|
39
|
+
echo "📥 Installing figlet - ASCII art text generator..."
|
|
40
|
+
echo "📥 Installing cowsay - ASCII cow speech generator..."
|
|
41
|
+
echo "📥 Installing lolcat - colorized text output..."
|
|
42
|
+
echo "📥 Installing chafa - terminal image viewer..."
|
|
43
|
+
brew install fortune || true
|
|
44
|
+
brew install figlet || true
|
|
45
|
+
brew install cowsay || true
|
|
46
|
+
brew install lolcat || true
|
|
47
|
+
brew install chafa || true
|
|
48
|
+
|
|
49
|
+
# --GROUP:NetworkTools: sshfs,nfs-utils
|
|
50
|
+
echo "📥 Installing SSHFS - mount remote filesystems over SSH..."
|
|
51
|
+
echo "📥 Installing NFS utilities..."
|
|
52
|
+
brew install sshfs || true
|
|
53
|
+
brew install nfs-utils || true
|
|
54
|
+
|
|
55
|
+
# --GROUP:DEV_SYSTEM: graphviz,make,rust,sqlite3,postgresql-client,redis-tools,ffmpeg
|
|
56
|
+
echo "📥 Installing Graphviz - graph visualization software..."
|
|
57
|
+
echo "📥 Installing make - build automation tool..."
|
|
58
|
+
echo "📥 Installing FFmpeg - multimedia framework..."
|
|
59
|
+
echo "📥 Installing SSL/TLS development libraries..."
|
|
60
|
+
echo "📥 Installing Rust programming language and toolchain..."
|
|
61
|
+
brew install graphviz || true
|
|
62
|
+
brew install make || true
|
|
63
|
+
brew install ffmpeg || true
|
|
64
|
+
brew install openssl || true
|
|
65
|
+
|
|
66
|
+
# Install Rust if not already installed
|
|
67
|
+
if ! command -v rustc &> /dev/null; then
|
|
68
|
+
echo "📥 Installing Rust..."
|
|
69
|
+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y || true
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# 🔐 OpenSSH Setup for macOS
|
|
4
|
+
# This script sets up SSH configuration and permissions on macOS
|
|
5
|
+
|
|
6
|
+
echo "🔐 Starting OpenSSH setup for macOS..."
|
|
7
|
+
|
|
8
|
+
# ✅ SSH is built-in on macOS (OpenSSH comes pre-installed)
|
|
9
|
+
echo "✅ OpenSSH is pre-installed on macOS"
|
|
10
|
+
|
|
11
|
+
# 📁 Create SSH directory with correct permissions
|
|
12
|
+
echo "📁 Setting up SSH directory..."
|
|
13
|
+
mkdir -p ~/.ssh
|
|
14
|
+
chmod 700 ~/.ssh
|
|
15
|
+
echo "✅ SSH directory created with correct permissions (700)"
|
|
16
|
+
|
|
17
|
+
# 📝 Create authorized_keys file if it doesn't exist
|
|
18
|
+
if [ ! -f ~/.ssh/authorized_keys ]; then
|
|
19
|
+
touch ~/.ssh/authorized_keys
|
|
20
|
+
chmod 600 ~/.ssh/authorized_keys
|
|
21
|
+
echo "✅ Created authorized_keys file"
|
|
22
|
+
else
|
|
23
|
+
echo "✅ authorized_keys file already exists"
|
|
24
|
+
chmod 600 ~/.ssh/authorized_keys
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# 🔑 Create SSH keys if they don't exist
|
|
28
|
+
if [ ! -f ~/.ssh/id_rsa ]; then
|
|
29
|
+
echo "🔑 Generating SSH keys (RSA)..."
|
|
30
|
+
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N "" -C "$(whoami)@$(hostname)"
|
|
31
|
+
echo "✅ SSH RSA keys generated: ~/.ssh/id_rsa"
|
|
32
|
+
else
|
|
33
|
+
echo "✅ SSH keys already exist"
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# 🔐 Create Ed25519 keys (modern alternative)
|
|
37
|
+
if [ ! -f ~/.ssh/id_ed25519 ]; then
|
|
38
|
+
echo "🔑 Generating SSH keys (Ed25519)..."
|
|
39
|
+
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" -C "$(whoami)@$(hostname)"
|
|
40
|
+
echo "✅ SSH Ed25519 keys generated: ~/.ssh/id_ed25519"
|
|
41
|
+
else
|
|
42
|
+
echo "✅ SSH Ed25519 keys already exist"
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# 🔧 Configure SSH config file for convenience
|
|
46
|
+
SSH_CONFIG="$HOME/.ssh/config"
|
|
47
|
+
if [ ! -f "$SSH_CONFIG" ]; then
|
|
48
|
+
echo "📝 Creating SSH config file..."
|
|
49
|
+
cat > "$SSH_CONFIG" << 'EOF'
|
|
50
|
+
# SSH Config File for macOS
|
|
51
|
+
# Add your remote hosts below
|
|
52
|
+
|
|
53
|
+
# Example host configuration:
|
|
54
|
+
# Host myserver
|
|
55
|
+
# HostName example.com
|
|
56
|
+
# User username
|
|
57
|
+
# Port 22
|
|
58
|
+
# IdentityFile ~/.ssh/id_ed25519
|
|
59
|
+
# IdentityFile ~/.ssh/id_rsa
|
|
60
|
+
|
|
61
|
+
# Global settings
|
|
62
|
+
Host *
|
|
63
|
+
AddKeysToAgent yes
|
|
64
|
+
UseKeychain yes
|
|
65
|
+
IdentityFile ~/.ssh/id_ed25519
|
|
66
|
+
IdentityFile ~/.ssh/id_rsa
|
|
67
|
+
ServerAliveInterval 60
|
|
68
|
+
EOF
|
|
69
|
+
chmod 600 "$SSH_CONFIG"
|
|
70
|
+
echo "✅ SSH config file created: $SSH_CONFIG"
|
|
71
|
+
else
|
|
72
|
+
echo "✅ SSH config file already exists"
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# 🔒 Ensure correct file permissions
|
|
76
|
+
echo "🔒 Setting correct SSH file permissions..."
|
|
77
|
+
chmod 700 ~/.ssh
|
|
78
|
+
chmod 600 ~/.ssh/authorized_keys 2>/dev/null || true
|
|
79
|
+
chmod 600 ~/.ssh/id_rsa 2>/dev/null || true
|
|
80
|
+
chmod 644 ~/.ssh/id_rsa.pub 2>/dev/null || true
|
|
81
|
+
chmod 600 ~/.ssh/id_ed25519 2>/dev/null || true
|
|
82
|
+
chmod 644 ~/.ssh/id_ed25519.pub 2>/dev/null || true
|
|
83
|
+
chmod 600 ~/.ssh/config 2>/dev/null || true
|
|
84
|
+
echo "✅ SSH file permissions configured correctly"
|
|
85
|
+
|
|
86
|
+
# ℹ️ Display SSH key information
|
|
87
|
+
echo ""
|
|
88
|
+
echo "📋 SSH Setup Summary:"
|
|
89
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
90
|
+
echo "SSH Directory: ~/.ssh"
|
|
91
|
+
echo "SSH Config: ~/.ssh/config"
|
|
92
|
+
echo ""
|
|
93
|
+
echo "Available SSH Keys:"
|
|
94
|
+
if [ -f ~/.ssh/id_rsa.pub ]; then
|
|
95
|
+
echo " • RSA Key: ~/.ssh/id_rsa"
|
|
96
|
+
fi
|
|
97
|
+
if [ -f ~/.ssh/id_ed25519.pub ]; then
|
|
98
|
+
echo " • Ed25519 Key: ~/.ssh/id_ed25519"
|
|
99
|
+
fi
|
|
100
|
+
echo ""
|
|
101
|
+
echo "💡 Next Steps:"
|
|
102
|
+
echo " 1. View your public key:"
|
|
103
|
+
echo " cat ~/.ssh/id_ed25519.pub (or id_rsa.pub)"
|
|
104
|
+
echo " 2. Add it to your GitHub/GitLab/server authorized_keys"
|
|
105
|
+
echo " 3. Test connection:"
|
|
106
|
+
echo " ssh -v your_server"
|
|
107
|
+
echo " 4. Configure hosts in ~/.ssh/config for easy access"
|
|
108
|
+
echo ""
|
|
109
|
+
echo "📚 Learn more about SSH:"
|
|
110
|
+
echo " • man ssh"
|
|
111
|
+
echo " • man ssh-keygen"
|
|
112
|
+
echo " • man ssh_config"
|
|
113
|
+
echo ""
|
|
114
|
+
echo "✅ OpenSSH setup complete!"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Install or update uv (universal version manager) on macOS
|
|
4
|
+
# Mirrors Linux uv installer but adapts PATH and locations for mac
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
UV_BIN="$HOME/.local/bin/uv"
|
|
9
|
+
|
|
10
|
+
if [ ! -f "$UV_BIN" ]; then
|
|
11
|
+
echo "📦 uv binary not found — installing uv to $HOME/.local/bin..."
|
|
12
|
+
mkdir -p "$HOME/.local/bin"
|
|
13
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
14
|
+
echo "✅ uv installed to $UV_BIN"
|
|
15
|
+
else
|
|
16
|
+
echo "🔄 uv binary found — attempting self-update..."
|
|
17
|
+
"$UV_BIN" self update || true
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Ensure local bin is in PATH for this run
|
|
21
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
22
|
+
|
|
23
|
+
if ! command -v uv &> /dev/null; then
|
|
24
|
+
echo "⚠️ uv not found in PATH even after install; add \"$HOME/.local/bin\" to your shell profile"
|
|
25
|
+
else
|
|
26
|
+
echo "🔧 uv available: $(command -v uv)"
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Example uv usage: ensure Python 3.14 is available (adjust as needed)
|
|
30
|
+
if command -v uv &> /dev/null; then
|
|
31
|
+
echo "📥 Ensuring Python 3.14 via uv (if supported)"
|
|
32
|
+
# uv may manage various runtimes; this is an example command and will be skipped gracefully if unsupported
|
|
33
|
+
uv python install 3.14 || true
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
echo "✅ uv setup complete"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
iex (iwr "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_windows/uv.ps1").Content
|
|
4
4
|
function mcfg {
|
|
5
|
-
& "$HOME\.local\bin\uv.exe" run --python 3.14 --with "machineconfig>=6.
|
|
5
|
+
& "$HOME\.local\bin\uv.exe" run --python 3.14 --with "machineconfig>=6.52" mcfg $args
|
|
6
6
|
}
|
|
7
7
|
function d { mcfg devops @args }
|
|
8
8
|
function c { mcfg cloud @args }
|