machineconfig 1.8__py3-none-any.whl → 1.91__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/__init__.py +4 -2
- machineconfig/jobs/python/check_installations.py +8 -6
- machineconfig/jobs/python/checkout_version.py +27 -32
- machineconfig/jobs/python/create_bootable_media.py +1 -1
- machineconfig/jobs/python/python_cargo_build_share.py +2 -2
- machineconfig/jobs/python/tasks.py +2 -2
- machineconfig/jobs/python_custom_installers/gh.py +53 -0
- machineconfig/jobs/python_custom_installers/hx.py +55 -0
- machineconfig/profile/create.py +26 -21
- machineconfig/profile/create_hardlinks.py +101 -0
- machineconfig/profile/shell.py +5 -5
- machineconfig/scripts/python/choose_wezterm_theme.py +96 -0
- machineconfig/scripts/python/cloud_copy.py +24 -17
- machineconfig/scripts/python/cloud_mount.py +20 -10
- machineconfig/scripts/python/cloud_repo_sync.py +109 -56
- machineconfig/scripts/python/cloud_sync.py +73 -68
- machineconfig/scripts/python/croshell.py +23 -14
- machineconfig/scripts/python/devops.py +19 -20
- machineconfig/scripts/python/devops_backup_retrieve.py +19 -10
- machineconfig/scripts/python/devops_devapps_install.py +81 -57
- machineconfig/scripts/python/devops_update_repos.py +5 -5
- machineconfig/scripts/python/dotfile.py +4 -4
- machineconfig/scripts/python/fire_jobs.py +139 -66
- machineconfig/scripts/python/ftpx.py +17 -7
- machineconfig/scripts/python/gh_models.py +53 -0
- machineconfig/scripts/python/mount_nfs.py +1 -1
- machineconfig/scripts/python/mount_nw_drive.py +3 -3
- machineconfig/scripts/python/mount_ssh.py +2 -3
- machineconfig/scripts/python/pomodoro.py +1 -1
- machineconfig/scripts/python/repos.py +26 -23
- machineconfig/scripts/python/scheduler.py +1 -1
- machineconfig/scripts/python/start_slidev.py +10 -4
- machineconfig/scripts/python/start_terminals.py +6 -5
- machineconfig/scripts/python/wifi_conn.py +34 -42
- machineconfig/scripts/python/wsl_windows_transfer.py +1 -1
- machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +1 -1
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +3 -2
- machineconfig/utils/installer.py +167 -60
- machineconfig/utils/procs.py +2 -2
- machineconfig/utils/scheduling.py +3 -3
- machineconfig/utils/utils.py +137 -56
- machineconfig/utils/ve.py +171 -100
- machineconfig-1.91.dist-info/LICENSE +201 -0
- {machineconfig-1.8.dist-info → machineconfig-1.91.dist-info}/METADATA +31 -11
- machineconfig-1.91.dist-info/RECORD +69 -0
- {machineconfig-1.8.dist-info → machineconfig-1.91.dist-info}/WHEEL +1 -1
- machineconfig/jobs/script_installer/azure_data_studio.py +0 -22
- machineconfig/jobs/script_installer/bypass_paywall.py +0 -23
- machineconfig/jobs/script_installer/code.py +0 -34
- machineconfig/jobs/script_installer/docker_desktop.py +0 -41
- machineconfig/jobs/script_installer/ngrok.py +0 -29
- machineconfig/jobs/script_installer/skim.py +0 -21
- machineconfig/jobs/script_installer/wezterm.py +0 -34
- machineconfig-1.8.dist-info/RECORD +0 -70
- /machineconfig/jobs/{script_installer → python_custom_installers}/__init__.py +0 -0
- {machineconfig-1.8.dist-info → machineconfig-1.91.dist-info}/top_level.txt +0 -0
machineconfig/utils/installer.py
CHANGED
|
@@ -3,17 +3,23 @@
|
|
|
3
3
|
"""
|
|
4
4
|
from rich.console import Console
|
|
5
5
|
|
|
6
|
-
from crocodile.file_management import P, List as L, Read
|
|
6
|
+
from crocodile.file_management import P, List as L, Read
|
|
7
|
+
from crocodile.core import Struct
|
|
7
8
|
from crocodile.meta import Terminal
|
|
8
9
|
from machineconfig.utils.utils import INSTALL_VERSION_ROOT, INSTALL_TMP_DIR, LIBRARY_ROOT, check_tool_exists
|
|
9
10
|
|
|
10
11
|
# from dataclasses import dataclass
|
|
11
|
-
from typing import Optional, Any
|
|
12
|
+
from typing import Optional, Any, TypeAlias, Literal
|
|
12
13
|
import platform
|
|
13
14
|
# import os
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
LINUX_INSTALL_PATH = '/usr/local/bin'
|
|
18
|
+
WINDOWS_INSTALL_PATH = P.home().joinpath("AppData/Local/Microsoft/WindowsApps").__str__()
|
|
19
|
+
CATEGORY: TypeAlias = Literal["OS_SPECIFIC", "OS_GENERIC", "CUSTOM", "OS_SPECIFIC_DEV", "OS_GENERIC_DEV", "CUSTOM_DEV"]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def find_move_delete_windows(downloaded_file_path: P, exe_name: Optional[str] = None, delete: bool=True, rename_to: Optional[str] = None):
|
|
17
23
|
if exe_name is not None and ".exe" in exe_name: exe_name = exe_name.replace(".exe", "")
|
|
18
24
|
if downloaded_file_path.is_file():
|
|
19
25
|
exe = downloaded_file_path
|
|
@@ -22,10 +28,14 @@ def find_move_delete_windows(downloaded_file_path: P, exe_name: Optional[str] =
|
|
|
22
28
|
else:
|
|
23
29
|
tmp = downloaded_file_path.search(f"{exe_name}.exe", r=True)
|
|
24
30
|
if len(tmp) == 1: exe = tmp.list[0]
|
|
25
|
-
else:
|
|
31
|
+
else:
|
|
32
|
+
search_res = downloaded_file_path.search("*.exe", r=True)
|
|
33
|
+
if len(search_res) == 0: raise IndexError(f"No executable found in {downloaded_file_path}")
|
|
34
|
+
elif len(search_res) == 1: exe = search_res.list[0]
|
|
35
|
+
else: exe = search_res.sort(lambda x: x.size("kb")).list[-1]
|
|
26
36
|
if rename_to and exe.name != rename_to:
|
|
27
37
|
exe = exe.with_name(name=rename_to, inplace=True)
|
|
28
|
-
exe_new_location = exe.move(folder=
|
|
38
|
+
exe_new_location = exe.move(folder=WINDOWS_INSTALL_PATH, overwrite=True) # latest version overwrites older installation.
|
|
29
39
|
if delete: downloaded_file_path.delete(sure=True)
|
|
30
40
|
return exe_new_location
|
|
31
41
|
|
|
@@ -41,33 +51,36 @@ def find_move_delete_linux(downloaded: P, tool_name: str, delete: Optional[bool]
|
|
|
41
51
|
if len(exe_search_res) == 0:
|
|
42
52
|
print(f"No search results for `{tool_name}` in `{downloaded}`")
|
|
43
53
|
raise IndexError(f"No executable found in {downloaded}")
|
|
44
|
-
|
|
54
|
+
elif len(exe_search_res) == 1:
|
|
45
55
|
exe = exe_search_res.list[0]
|
|
56
|
+
else:
|
|
57
|
+
exe = exe_search_res.sort(lambda x: x.size("kb")).list[-1]
|
|
46
58
|
if rename_to and exe.name != rename_to:
|
|
47
59
|
exe = exe.with_name(name=rename_to, inplace=True)
|
|
48
|
-
print(f"MOVING file `{repr(exe)}` to '
|
|
60
|
+
print(f"MOVING file `{repr(exe)}` to '{LINUX_INSTALL_PATH}'")
|
|
49
61
|
exe.chmod(0o777)
|
|
50
|
-
# exe.move(folder=
|
|
51
|
-
Terminal().run(f"sudo mv {exe} /
|
|
62
|
+
# exe.move(folder=LINUX_INSTALL_PATH, overwrite=False)
|
|
63
|
+
Terminal().run(f"sudo mv {exe} {LINUX_INSTALL_PATH}/").print_if_unsuccessful(desc=f"MOVING executable `{exe}` to {LINUX_INSTALL_PATH}", strict_err=True, strict_returncode=True)
|
|
52
64
|
if delete: downloaded.delete(sure=True)
|
|
53
|
-
exe_new_location = P(
|
|
65
|
+
exe_new_location = P(LINUX_INSTALL_PATH).joinpath(exe.name)
|
|
54
66
|
return exe_new_location
|
|
55
67
|
|
|
56
68
|
|
|
57
69
|
class Installer:
|
|
58
|
-
def __init__(self, repo_url: str, name: str, doc: str, filename_template_windows_amd_64: str, filename_template_linux_amd_64: str,
|
|
59
|
-
|
|
60
|
-
self.
|
|
61
|
-
self.
|
|
62
|
-
self.
|
|
63
|
-
self.
|
|
64
|
-
self.
|
|
65
|
-
self.
|
|
70
|
+
def __init__(self, repo_url: str, name: str, doc: str, filename_template_windows_amd_64: str, filename_template_linux_amd_64: str,
|
|
71
|
+
strip_v: bool, exe_name: str):
|
|
72
|
+
self.repo_url: str=repo_url
|
|
73
|
+
self.name: str=name
|
|
74
|
+
self.doc: str=doc
|
|
75
|
+
self.filename_template_windows_amd_64: str=filename_template_windows_amd_64
|
|
76
|
+
self.filename_template_linux_amd_64: str=filename_template_linux_amd_64
|
|
77
|
+
self.strip_v: bool=strip_v
|
|
78
|
+
self.exe_name: str=exe_name
|
|
66
79
|
def __repr__(self) -> str: return f"Installer of {self.repo_url}"
|
|
67
80
|
def get_description(self):
|
|
68
81
|
# old_version_cli = Terminal().run(f"{self.exe_name} --version").op.replace("\n", "")
|
|
69
82
|
# old_version_cli = os.system(f"{self.exe_name} --version").replace("\n", "")
|
|
70
|
-
old_version_cli =
|
|
83
|
+
old_version_cli: bool=check_tool_exists(tool_name=self.exe_name)
|
|
71
84
|
old_version_cli_str = "✅" if old_version_cli else "❌"
|
|
72
85
|
# name_version = f"{self.exe_name} {old_version_cli_str}"
|
|
73
86
|
return f"{self.exe_name:<12} {old_version_cli_str} {self.doc}"
|
|
@@ -83,39 +96,49 @@ class Installer:
|
|
|
83
96
|
from machineconfig.utils.utils import choose_one_option
|
|
84
97
|
path = choose_one_option(options=LIBRARY_ROOT.joinpath("jobs").search("config.json", r=True).list)
|
|
85
98
|
config: dict[str, Any] = Read.json(path) # /python_generic_installers/config.json"))
|
|
86
|
-
|
|
87
|
-
for keys, dict_ in config.items():
|
|
88
|
-
|
|
89
|
-
|
|
99
|
+
app_name = choose_one_option(options=list(config.keys()), fzf=True)
|
|
100
|
+
# for keys, dict_ in config.items():
|
|
101
|
+
installer = Installer.from_dict(d=config[app_name], name=app_name)
|
|
102
|
+
version = input(f"Enter version to install for {installer.exe_name} [latest]: ") or None
|
|
103
|
+
installer.install(version=version)
|
|
90
104
|
|
|
91
105
|
def install_robust(self, version: Optional[str]):
|
|
92
106
|
try:
|
|
107
|
+
|
|
93
108
|
old_version_cli = Terminal().run(f"{self.exe_name} --version").op.replace("\n", "")
|
|
94
109
|
self.install(version=version)
|
|
95
110
|
new_version_cli = Terminal().run(f"{self.exe_name} --version").op.replace("\n", "")
|
|
96
|
-
|
|
97
|
-
|
|
111
|
+
|
|
112
|
+
if old_version_cli == new_version_cli: return f"""echo "📦️ 😑 {self.exe_name}, same version: {old_version_cli}" """
|
|
113
|
+
else: return f"""echo "📦️ 🤩 {self.exe_name} updated from {old_version_cli} === to ===> {new_version_cli}" """
|
|
114
|
+
|
|
98
115
|
except Exception as ex:
|
|
99
116
|
print(ex)
|
|
100
|
-
return f"📦️ Failed at {self.
|
|
117
|
+
return f"""echo "📦️ Failed at `{self.name}` with {ex}" """
|
|
101
118
|
|
|
102
119
|
def install(self, version: Optional[str]):
|
|
103
120
|
if self.repo_url == "CUSTOM":
|
|
104
|
-
|
|
105
|
-
|
|
121
|
+
|
|
122
|
+
import machineconfig.jobs.python_custom_installers as python_custom_installers
|
|
123
|
+
installer_path = P(python_custom_installers.__file__).parent.joinpath(self.exe_name + ".py")
|
|
124
|
+
if not installer_path.exists():
|
|
125
|
+
installer_path = P(python_custom_installers.__file__).parent.joinpath("dev", self.exe_name + ".py")
|
|
126
|
+
|
|
106
127
|
import runpy
|
|
107
|
-
|
|
108
|
-
|
|
128
|
+
print(f"Executing func `main` from `{installer_path}`to get the program to run")
|
|
129
|
+
program: str=runpy.run_path(str(installer_path), run_name=None)['main'](version=version)
|
|
130
|
+
# print(program)
|
|
131
|
+
Terminal(stdin=None, stdout=None, stderr=None).run_script(script=program, shell="default").print(desc="Running custom installer", capture=True)
|
|
132
|
+
# import subprocess
|
|
133
|
+
# subprocess.run(program, shell=True, check=True)
|
|
109
134
|
version_to_be_installed = str(version)
|
|
110
|
-
elif "npm " in self.repo_url:
|
|
111
|
-
|
|
112
|
-
version_to_be_installed = "
|
|
113
|
-
|
|
114
|
-
Terminal().run(self.repo_url, shell="default").print_if_unsuccessful(desc="pip install", strict_err=True, strict_returncode=True)
|
|
115
|
-
version_to_be_installed = "pipLatest"
|
|
135
|
+
elif "npm " in self.repo_url or "pip " in self.repo_url or "winget " in self.repo_url:
|
|
136
|
+
desc = self.repo_url.split(" ", maxsplit=1)[0] + "installation"
|
|
137
|
+
version_to_be_installed = self.repo_url.split(" ", maxsplit=1)[0] + "Latest"
|
|
138
|
+
Terminal().run(self.repo_url, shell="default").print_if_unsuccessful(desc=desc, strict_err=True, strict_returncode=True)
|
|
116
139
|
else:
|
|
117
140
|
downloaded, version_to_be_installed = self.download(version=version)
|
|
118
|
-
if downloaded.
|
|
141
|
+
if downloaded.to_str().endswith(".deb"):
|
|
119
142
|
assert platform.system() == "Linux"
|
|
120
143
|
Terminal().run(f"sudo apt install -y {downloaded}").print_if_unsuccessful(desc="Installing .deb", strict_err=True, strict_returncode=True)
|
|
121
144
|
downloaded.delete(sure=True)
|
|
@@ -147,7 +170,7 @@ class Installer:
|
|
|
147
170
|
else: raise NotImplementedError(f"📦️ System {platform.system()} not implemented")
|
|
148
171
|
version_to_be_installed = "predefined_url"
|
|
149
172
|
else:
|
|
150
|
-
release_url, version_to_be_installed =
|
|
173
|
+
release_url, version_to_be_installed = Installer.get_github_release(repo_url=self.repo_url, version=version)
|
|
151
174
|
print(f"📦️ Version to be installed: {version_to_be_installed}")
|
|
152
175
|
print(f"📦️ Release URL: {release_url}")
|
|
153
176
|
version_to_be_installed_stripped = version_to_be_installed.replace("v", "") if self.strip_v else version_to_be_installed
|
|
@@ -156,9 +179,9 @@ class Installer:
|
|
|
156
179
|
elif platform.system() == "Linux":
|
|
157
180
|
file_name = self.filename_template_linux_amd_64.format(version_to_be_installed_stripped)
|
|
158
181
|
else: raise NotImplementedError(f"📦️ System {platform.system()} not implemented")
|
|
159
|
-
print(
|
|
182
|
+
print("📦️ File name", file_name)
|
|
160
183
|
download_link = release_url.joinpath(file_name)
|
|
161
|
-
print("📦️ Downloading: ", download_link.as_url_str())
|
|
184
|
+
print(f"📦️ Downloading {self.name}: ", download_link.as_url_str())
|
|
162
185
|
downloaded = download_link.download(folder=INSTALL_TMP_DIR).decompress()
|
|
163
186
|
return downloaded, version_to_be_installed
|
|
164
187
|
|
|
@@ -168,6 +191,7 @@ class Installer:
|
|
|
168
191
|
print(f"📦️ Inspecting latest release @ {repo_url} ...")
|
|
169
192
|
# with console.status("Installing..."): # makes troubles on linux when prompt asks for password to move file to /usr/bin
|
|
170
193
|
if version is None:
|
|
194
|
+
# see this: https://api.github.com/repos/cointop-sh/cointop/releases/latest
|
|
171
195
|
import requests # https://docs.github.com/en/repositories/releasing-projects-on-github/linking-to-releases
|
|
172
196
|
_latest_version = requests.get(str(repo_url) + "/releases/latest", timeout=10).url.split("/")[-1] # this is to resolve the redirection that occures: https://stackoverflow.com/questions/36070821/how-to-get-redirect-url-using-python-requests
|
|
173
197
|
version_to_be_installed = _latest_version
|
|
@@ -178,58 +202,137 @@ class Installer:
|
|
|
178
202
|
return release_url, version_to_be_installed
|
|
179
203
|
|
|
180
204
|
@staticmethod
|
|
181
|
-
def check_if_installed_already(exe_name: str, version: str):
|
|
205
|
+
def check_if_installed_already(exe_name: str, version: str, use_cache: bool):
|
|
182
206
|
version_to_be_installed = version
|
|
183
207
|
tmp_path = INSTALL_VERSION_ROOT.joinpath(exe_name).create(parents_only=True)
|
|
184
|
-
|
|
185
|
-
|
|
208
|
+
|
|
209
|
+
if use_cache:
|
|
210
|
+
if tmp_path.exists(): existing_version = tmp_path.read_text().rstrip()
|
|
211
|
+
else: existing_version = None
|
|
212
|
+
else:
|
|
213
|
+
# check_tool_exists(tool_name=exe_name)
|
|
214
|
+
# raise NotImplementedError("Not implemented")
|
|
215
|
+
# import subprocess
|
|
216
|
+
# try:
|
|
217
|
+
# existing_version = subprocess.check_output([exe_name, "--version"], text=True)
|
|
218
|
+
# existing_version = existing_version.strip()
|
|
219
|
+
# except (subprocess.CalledProcessError, FileNotFoundError):
|
|
220
|
+
# print(f"Failed to get version of {exe_name}")
|
|
221
|
+
# existing_version = None
|
|
222
|
+
resp = Terminal().run(exe_name, "--version", check=False).capture()
|
|
223
|
+
if resp.op == '': existing_version = None
|
|
224
|
+
else: existing_version = resp.op.strip()
|
|
186
225
|
|
|
187
226
|
if existing_version is not None:
|
|
188
227
|
if existing_version == version_to_be_installed:
|
|
189
228
|
print(f"📦️ ⚠️ {exe_name} already installed at version {version_to_be_installed}. See {INSTALL_VERSION_ROOT}")
|
|
190
|
-
return
|
|
229
|
+
return ("✅ Uptodate", version.strip(), version_to_be_installed.strip())
|
|
191
230
|
else:
|
|
192
231
|
# print(f"Latest version is {version}, logged at {tmp_path}")
|
|
193
232
|
print(f"📦️ ⬆️ {exe_name} installed at version {existing_version.rstrip()} --> Installing version {version_to_be_installed} ")
|
|
194
233
|
tmp_path.write_text(version_to_be_installed)
|
|
234
|
+
return ("❌ Outdated", existing_version.strip(), version_to_be_installed.strip())
|
|
195
235
|
else:
|
|
196
236
|
print(f"📦️ {exe_name} has no known version. Installing version `{version_to_be_installed}` ")
|
|
197
237
|
tmp_path.write_text(version_to_be_installed)
|
|
198
|
-
return
|
|
238
|
+
return ("⚠️NotInstalled", "None", version_to_be_installed.strip())
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def check_latest():
|
|
242
|
+
installers = get_installers(system=platform.system(), dev=False)
|
|
243
|
+
# installers += get_installers(system=platform.system(), dev=True)
|
|
244
|
+
installers_gitshub = []
|
|
245
|
+
for inst__ in installers:
|
|
246
|
+
if "ntop" in inst__.name: continue
|
|
247
|
+
if "github" not in inst__.repo_url:
|
|
248
|
+
print(f"Skipping {inst__.name} as it is not a github release")
|
|
249
|
+
continue
|
|
250
|
+
installers_gitshub.append(inst__)
|
|
251
|
+
|
|
252
|
+
def func(inst: Installer):
|
|
253
|
+
_release_url, version_to_be_installed = inst.get_github_release(repo_url=inst.repo_url, version=None)
|
|
254
|
+
verdict, current_ver, new_ver = inst.check_if_installed_already(exe_name=inst.exe_name, version=version_to_be_installed, use_cache=False)
|
|
255
|
+
return inst.exe_name, verdict, current_ver, new_ver
|
|
256
|
+
|
|
257
|
+
res = L(installers_gitshub).apply(func=func, jobs=1)
|
|
258
|
+
import pandas as pd
|
|
259
|
+
res_df = pd.DataFrame(res, columns=["Tool", "Status", "Current Version", "New Version"]).groupby("Status").apply(lambda x: x).reset_index(drop=True)
|
|
260
|
+
from crocodile.core import Display
|
|
261
|
+
Display.set_pandas_display()
|
|
262
|
+
print(res_df)
|
|
199
263
|
|
|
200
264
|
|
|
201
265
|
def get_installed_cli_apps():
|
|
202
266
|
if platform.system() == "Windows": apps = P.home().joinpath("AppData/Local/Microsoft/WindowsApps").search("*.exe", not_in=["notepad"])
|
|
203
|
-
elif platform.system() == "Linux": apps = P(
|
|
267
|
+
elif platform.system() == "Linux": apps = P(LINUX_INSTALL_PATH).search("*")
|
|
204
268
|
else: raise NotImplementedError("Not implemented for this OS")
|
|
205
269
|
apps = L([app for app in apps if app.size("kb") > 0.1 and not app.is_symlink()]) # no symlinks like paint and wsl and bash
|
|
206
270
|
return apps
|
|
207
271
|
|
|
208
272
|
|
|
209
273
|
def get_installers(system: str, dev: bool) -> list[Installer]:
|
|
274
|
+
res_all = get_all_dicts(system=system)
|
|
275
|
+
if not dev:
|
|
276
|
+
del res_all["CUSTOM_DEV"]
|
|
277
|
+
del res_all["OS_SPECIFIC_DEV"]
|
|
278
|
+
del res_all["OS_GENERIC_DEV"]
|
|
279
|
+
res_final = {}
|
|
280
|
+
for _k, v in res_all.items():
|
|
281
|
+
res_final.update(v)
|
|
282
|
+
return [Installer.from_dict(d=vd, name=k) for k, vd in res_final.items()]
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def get_all_dicts(system: str) -> dict[CATEGORY, dict[str, dict[str, Any]]]:
|
|
210
286
|
if system == "Windows": import machineconfig.jobs.python_windows_installers as os_specific_installer
|
|
211
287
|
else: import machineconfig.jobs.python_linux_installers as os_specific_installer
|
|
288
|
+
|
|
212
289
|
import machineconfig.jobs.python_generic_installers as generic_installer
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
290
|
+
path_os_specific = P(os_specific_installer.__file__).parent
|
|
291
|
+
path_os_generic = P(generic_installer.__file__).parent
|
|
292
|
+
|
|
293
|
+
path_os_specific_dev = path_os_specific.joinpath("dev")
|
|
294
|
+
path_os_generic_dev = path_os_generic.joinpath("dev")
|
|
295
|
+
|
|
296
|
+
res_final: dict[CATEGORY, dict[str, dict[str, Any]]] = {}
|
|
297
|
+
res_final["OS_SPECIFIC"] = Read.json(path=path_os_specific.joinpath("config.json"))
|
|
298
|
+
res_final["OS_GENERIC"] = Read.json(path=path_os_generic.joinpath("config.json"))
|
|
299
|
+
res_final["OS_SPECIFIC_DEV"] = Read.json(path=path_os_specific_dev.joinpath("config.json"))
|
|
300
|
+
res_final["OS_GENERIC_DEV"] = Read.json(path=path_os_generic_dev.joinpath("config.json"))
|
|
301
|
+
|
|
302
|
+
path_custom_installer = path_os_generic.with_name("python_custom_installers")
|
|
303
|
+
path_custom_installer_dev = path_custom_installer.joinpath("dev")
|
|
304
|
+
|
|
305
|
+
import runpy
|
|
306
|
+
res_custom: dict[str, dict[str, Any]] = {}
|
|
307
|
+
for item in path_custom_installer.search("*.py", r=False, not_in=["__init__"]):
|
|
308
|
+
try:
|
|
309
|
+
config_dict = runpy.run_path(str(item), run_name=None)['config_dict']
|
|
310
|
+
res_custom[item.stem] = config_dict
|
|
311
|
+
except Exception as ex:
|
|
312
|
+
print(f"Failed to load {item}: {ex}")
|
|
313
|
+
|
|
314
|
+
res_custom_dev: dict[str, dict[str, Any]] = {}
|
|
315
|
+
for item in path_custom_installer_dev.search("*.py", r=False, not_in=["__init__"]):
|
|
316
|
+
try:
|
|
317
|
+
config_dict = runpy.run_path(str(item), run_name=None)['config_dict']
|
|
318
|
+
res_custom_dev[item.stem] = config_dict
|
|
319
|
+
except Exception as ex:
|
|
320
|
+
print(f"Failed to load {item}: {ex}")
|
|
321
|
+
|
|
322
|
+
res_final["CUSTOM"] = res_custom
|
|
323
|
+
res_final["CUSTOM_DEV"] = res_custom_dev
|
|
324
|
+
return res_final
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def install_all(installers: L[Installer], safe: bool=False, jobs: int = 10, fresh: bool=False):
|
|
225
328
|
if fresh: INSTALL_VERSION_ROOT.delete(sure=True)
|
|
226
329
|
if safe:
|
|
227
330
|
from machineconfig.jobs.python.check_installations import APP_SUMMARY_PATH
|
|
228
331
|
apps_dir = APP_SUMMARY_PATH.readit()
|
|
229
332
|
if platform.system().lower() == "windows":
|
|
230
|
-
apps_dir.search("*").apply(lambda app: app.move(folder=P.get_env().WindowsApps))
|
|
333
|
+
apps_dir.search("*").apply(lambda app: app.move(folder=P.get_env().WindowsPaths().WindowsApps))
|
|
231
334
|
elif platform.system().lower() == "linux":
|
|
232
|
-
Terminal().run(f"sudo mv {apps_dir.as_posix()}/* /
|
|
335
|
+
Terminal().run(f"sudo mv {apps_dir.as_posix()}/* {LINUX_INSTALL_PATH}/").print_if_unsuccessful(desc=f"MOVING executable to {LINUX_INSTALL_PATH}", strict_err=True, strict_returncode=True)
|
|
233
336
|
else: raise NotImplementedError(f"I don't know this system {platform.system()}")
|
|
234
337
|
apps_dir.delete(sure=True)
|
|
235
338
|
return None
|
|
@@ -249,3 +352,7 @@ def install_all(installers: L[Installer], safe: bool = False, jobs: int = 10, fr
|
|
|
249
352
|
print("\n")
|
|
250
353
|
print("Completed Installation".center(100, "-"))
|
|
251
354
|
print("\n" * 2)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
if __name__ == "__main__":
|
|
358
|
+
pass
|
machineconfig/utils/procs.py
CHANGED
|
@@ -60,7 +60,7 @@ class ProcessManager:
|
|
|
60
60
|
self.kill(pids=sub_df.pid.to_list())
|
|
61
61
|
return
|
|
62
62
|
kill_by_index = input("🔫 Kill by index? 1 4 ... /[n] ")
|
|
63
|
-
if kill_by_index != "":
|
|
63
|
+
if kill_by_index != "" and kill_by_index != "n":
|
|
64
64
|
indices = [int(val) for val in kill_by_index.split(" ")]
|
|
65
65
|
sub_sub_df = sub_df.iloc[indices]
|
|
66
66
|
for idx2, row in sub_sub_df.iterrows():
|
|
@@ -93,7 +93,7 @@ class ProcessManager:
|
|
|
93
93
|
print(f'💀 Killed process with pid {pid} and name {proc.name()}. It lived {get_age(proc.create_time())}. RIP 🪦💐')
|
|
94
94
|
except psutil.NoSuchProcess: print(f'No process with pid {pid} found')
|
|
95
95
|
for command in commands:
|
|
96
|
-
rows = self.df[self.df['command'].
|
|
96
|
+
rows = self.df[self.df['command'].to_str().contains(command)]
|
|
97
97
|
if len(rows) > 0:
|
|
98
98
|
for _idx, a_row in rows.iterrows():
|
|
99
99
|
psutil.Process(a_row.pid).kill()
|
|
@@ -62,7 +62,7 @@ class Report:
|
|
|
62
62
|
status: str
|
|
63
63
|
|
|
64
64
|
@classmethod
|
|
65
|
-
def from_path(cls, path: P, return_default_if_not_found: bool
|
|
65
|
+
def from_path(cls, path: P, return_default_if_not_found: bool=False):
|
|
66
66
|
if not path.exists():
|
|
67
67
|
if return_default_if_not_found:
|
|
68
68
|
return Report(name=path.parent.name, start=datetime(year=2000, month=1, day=1), end=datetime(year=2000, month=1, day=1), status="NA")
|
|
@@ -108,7 +108,7 @@ def read_task_from_dir(path: P):
|
|
|
108
108
|
return task
|
|
109
109
|
|
|
110
110
|
|
|
111
|
-
def main(root: Optional[str] = None, ignore_conditions: bool
|
|
111
|
+
def main(root: Optional[str] = None, ignore_conditions: bool=True):
|
|
112
112
|
if root is None: root_resolved = SCHEDULER_DEFAULT_ROOT
|
|
113
113
|
else: root_resolved = P(root).expanduser().absolute()
|
|
114
114
|
tasks_dirs = root_resolved.search(files=False, folders=True).filter(lambda x: x.joinpath("task.py").exists())
|
|
@@ -168,7 +168,7 @@ def should_task_run(task: Task, tolerance_mins: int = 1440) -> tuple[bool, Optio
|
|
|
168
168
|
def run_task(task: Task) -> Report:
|
|
169
169
|
start_time = datetime.now()
|
|
170
170
|
|
|
171
|
-
shell_script = get_shell_script_executing_python_file(python_file=task.task_root.joinpath("task.py").
|
|
171
|
+
shell_script = get_shell_script_executing_python_file(python_file=task.task_root.joinpath("task.py").to_str(), ve_name=task.venv)
|
|
172
172
|
shell_script_root = P.tmp().joinpath(f"tmp_scripts/scheduler/{task.name}").create()
|
|
173
173
|
try:
|
|
174
174
|
if platform.system() == 'Windows':
|