machineconfig 1.7__py3-none-any.whl → 1.9__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 +38 -32
- machineconfig/jobs/python/create_bootable_media.py +4 -4
- machineconfig/jobs/python/create_zellij_template.py +3 -2
- machineconfig/jobs/python/python_cargo_build_share.py +14 -9
- machineconfig/jobs/python/python_ve_symlink.py +6 -6
- machineconfig/jobs/python_custom_installers/azuredatastudio.py +36 -0
- machineconfig/jobs/python_custom_installers/bypass_paywall.py +30 -0
- machineconfig/jobs/{python_linux_installers/dev → python_custom_installers}/docker_desktop.py +15 -4
- machineconfig/jobs/python_custom_installers/gh.py +53 -0
- machineconfig/jobs/python_custom_installers/goes.py +35 -0
- machineconfig/jobs/python_custom_installers/helix.py +43 -0
- machineconfig/jobs/python_custom_installers/lvim.py +48 -0
- machineconfig/jobs/python_custom_installers/ngrok.py +39 -0
- machineconfig/jobs/python_custom_installers/nvim.py +48 -0
- machineconfig/jobs/python_custom_installers/vscode.py +45 -0
- machineconfig/jobs/python_custom_installers/wezterm.py +41 -0
- machineconfig/profile/create.py +12 -7
- machineconfig/profile/shell.py +15 -13
- machineconfig/scripts/python/choose_wezterm_theme.py +96 -0
- machineconfig/scripts/python/cloud_copy.py +18 -13
- machineconfig/scripts/python/cloud_mount.py +41 -15
- machineconfig/scripts/python/cloud_repo_sync.py +57 -31
- machineconfig/scripts/python/cloud_sync.py +13 -15
- machineconfig/scripts/python/croshell.py +19 -10
- machineconfig/scripts/python/devops.py +22 -6
- machineconfig/scripts/python/devops_add_identity.py +7 -6
- machineconfig/scripts/python/devops_add_ssh_key.py +10 -9
- machineconfig/scripts/python/devops_backup_retrieve.py +5 -5
- machineconfig/scripts/python/devops_devapps_install.py +24 -19
- machineconfig/scripts/python/devops_update_repos.py +5 -4
- machineconfig/scripts/python/dotfile.py +8 -4
- machineconfig/scripts/python/fire_jobs.py +165 -55
- machineconfig/scripts/python/ftpx.py +18 -8
- machineconfig/scripts/python/mount_nfs.py +13 -10
- machineconfig/scripts/python/mount_nw_drive.py +4 -3
- machineconfig/scripts/python/mount_ssh.py +8 -5
- machineconfig/scripts/python/repos.py +26 -21
- machineconfig/scripts/python/snapshot.py +2 -2
- machineconfig/scripts/python/start_slidev.py +104 -0
- machineconfig/scripts/python/start_terminals.py +1 -1
- machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +20 -34
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +11 -12
- machineconfig/utils/installer.py +177 -217
- machineconfig/utils/scheduling.py +1 -1
- machineconfig/utils/utils.py +107 -54
- machineconfig/utils/ve.py +120 -16
- machineconfig-1.9.dist-info/LICENSE +201 -0
- {machineconfig-1.7.dist-info → machineconfig-1.9.dist-info}/METADATA +155 -140
- machineconfig-1.9.dist-info/RECORD +76 -0
- {machineconfig-1.7.dist-info → machineconfig-1.9.dist-info}/WHEEL +1 -1
- machineconfig/jobs/python_generic_installers/archive/gopass.py +0 -18
- machineconfig/jobs/python_generic_installers/archive/nvim.py +0 -20
- machineconfig/jobs/python_generic_installers/archive/opencommit.py +0 -25
- machineconfig/jobs/python_generic_installers/archive/strongbox.py +0 -33
- machineconfig/jobs/python_generic_installers/dev/__init__.py +0 -0
- machineconfig/jobs/python_linux_installers/archive/__init__.py +0 -0
- machineconfig/jobs/python_linux_installers/archive/bandwhich.py +0 -14
- machineconfig/jobs/python_linux_installers/archive/ranger.py +0 -19
- machineconfig/jobs/python_linux_installers/dev/azure_data_studio.py +0 -21
- machineconfig/jobs/python_linux_installers/dev/bytehound.py +0 -20
- machineconfig/jobs/python_linux_installers/dev/nnn.py +0 -22
- machineconfig/jobs/python_windows_installers/archive/ntop.py +0 -21
- machineconfig/jobs/python_windows_installers/dev/bypass_paywall.py +0 -22
- machineconfig/jobs/python_windows_installers/dev/obs_background_removal_plugin.py +0 -22
- machineconfig/scripts/python/choose_ohmybash_theme.py +0 -31
- machineconfig/scripts/python/choose_ohmyposh_theme.py +0 -57
- machineconfig/utils/pandas_type.py +0 -37
- machineconfig/utils/to_exe.py +0 -7
- machineconfig-1.7.dist-info/RECORD +0 -81
- /machineconfig/jobs/{python_generic_installers/archive → python_custom_installers}/__init__.py +0 -0
- {machineconfig-1.7.dist-info → machineconfig-1.9.dist-info}/top_level.txt +0 -0
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
|
|
2
2
|
"""utils"""
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
from machineconfig.utils.utils import CONFIG_PATH, DEFAULTS_PATH, write_shell_script, get_shell_file_executing_python_script
|
|
6
|
+
from crocodile.file_management import P, Read, install_n_import
|
|
7
|
+
from crocodile.core import randstr
|
|
8
|
+
from crocodile.meta import Terminal
|
|
6
9
|
import argparse
|
|
7
10
|
import platform
|
|
8
11
|
from typing import Optional
|
|
@@ -10,10 +13,24 @@ from typing import Optional
|
|
|
10
13
|
# import subprocess
|
|
11
14
|
|
|
12
15
|
|
|
13
|
-
def get_wt_cmd(wd1:
|
|
16
|
+
def get_wt_cmd(wd1: P, wd2: P) -> str:
|
|
17
|
+
lines = [
|
|
18
|
+
f"""wt --window 0 new-tab --profile pwsh --title "gitdiff" --tabColor `#3b04d1 --startingDirectory {wd1} ` --colorScheme "Solarized Dark" """,
|
|
19
|
+
f"""split-pane --horizontal --profile pwsh --startingDirectory {wd2} --size 0.5 --colorScheme "Tango Dark" -- pwsh -Interactive """
|
|
20
|
+
]
|
|
21
|
+
return " `; ".join(lines)
|
|
14
22
|
|
|
15
23
|
|
|
16
|
-
def get_zellij_cmd(wd1:
|
|
24
|
+
def get_zellij_cmd(wd1: P, wd2: P) -> str:
|
|
25
|
+
lines = [f""" zellij action new-tab --name gitdiff""",
|
|
26
|
+
f"""zellij action new-pane --direction down --name local --cwd ./data """,
|
|
27
|
+
f"""zellij action write-chars "cd '{wd1}'; git status" """,
|
|
28
|
+
f"""zellij action move-focus up; zellij action close-pane """,
|
|
29
|
+
f"""zellij action new-pane --direction down --name remote --cwd code """,
|
|
30
|
+
f"""zellij action write-chars "cd '{wd2}' """,
|
|
31
|
+
f"""git status" """
|
|
32
|
+
]
|
|
33
|
+
return "; ".join(lines)
|
|
17
34
|
|
|
18
35
|
|
|
19
36
|
def args_parser():
|
|
@@ -25,7 +42,7 @@ def args_parser():
|
|
|
25
42
|
# parser.add_argument("--share", help="Repository path, defaults to cwd.", action="store_true", default=False)
|
|
26
43
|
|
|
27
44
|
parser.add_argument("--cloud", "-c", help="rclone cloud profile name.", default=None)
|
|
28
|
-
parser.add_argument("--message", "-m", help="Commit Message", default=f"new message {
|
|
45
|
+
parser.add_argument("--message", "-m", help="Commit Message", default=f"new message {randstr()}")
|
|
29
46
|
parser.add_argument("--skip_confirmation", "-s", help="Skip confirmation.", action="store_true", default=False)
|
|
30
47
|
# parser.add_argument("--key", "-k", help="Key for encryption", default=None)
|
|
31
48
|
parser.add_argument("--pwd", "-p", help="Password for encryption", default=None)
|
|
@@ -41,89 +58,98 @@ def args_parser():
|
|
|
41
58
|
|
|
42
59
|
def main(cloud: Optional[str] = None, path: Optional[str] = None, message: Optional[str] = None, skip_confirmation: bool = False, pwd: Optional[str] = None, push: bool = True):
|
|
43
60
|
if cloud is None:
|
|
44
|
-
try:
|
|
61
|
+
try:
|
|
62
|
+
cloud_resolved = Read.ini(DEFAULTS_PATH)['general']['rclone_config_name']
|
|
63
|
+
print(f"⚠️ Using default cloud: `{cloud_resolved}` from {DEFAULTS_PATH} ⚠️")
|
|
45
64
|
except FileNotFoundError:
|
|
46
65
|
print(f"No cloud profile found @ {DEFAULTS_PATH}, please set one up or provide one via the --cloud flag.")
|
|
47
66
|
return ""
|
|
48
67
|
else: cloud_resolved = cloud
|
|
49
|
-
# repo_root =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
68
|
+
# repo_root = P(args.repo).expanduser().absolute()
|
|
69
|
+
repo_local_root = P.cwd() if path is None else P(path).expanduser().absolute()
|
|
70
|
+
repo_local_obj = install_n_import("git", "gitpython").Repo(repo_local_root, search_parent_directories=True)
|
|
71
|
+
repo_local_root = P(repo_local_obj.working_dir) # cwd might have been in a sub directory of repo_root, so its better to redefine it.
|
|
53
72
|
CONFIG_PATH.joinpath("remote").create()
|
|
54
|
-
|
|
73
|
+
repo_remote_root = CONFIG_PATH.joinpath("remote", repo_local_root.rel2home()) # .delete(sure=True)
|
|
55
74
|
try:
|
|
56
75
|
print("\n", "=============================== Downloading Remote Repo ====================================")
|
|
57
|
-
remote_path =
|
|
58
|
-
|
|
76
|
+
remote_path = repo_local_root.get_remote_path(rel2home=True, os_specific=False, root="myhome") + ".zip.enc"
|
|
77
|
+
repo_remote_root.from_cloud(remotepath=remote_path, cloud=cloud_resolved, unzip=True, decrypt=True, rel2home=True, os_specific=False, pwd=pwd)
|
|
59
78
|
except AssertionError:
|
|
60
79
|
print("Remote does not exist, creating it and exiting ... ")
|
|
61
|
-
|
|
80
|
+
repo_local_root.to_cloud(cloud=cloud_resolved, zip=True, encrypt=True, rel2home=True, pwd=pwd, os_specific=False)
|
|
62
81
|
return ""
|
|
63
|
-
|
|
64
|
-
if
|
|
65
|
-
print("=" * 50, '\n', f"WRANING: the remote `{
|
|
82
|
+
repo_remote_obj = install_n_import("git", "gitpython").Repo(repo_remote_root)
|
|
83
|
+
if repo_remote_obj.is_dirty():
|
|
84
|
+
print("=" * 50, '\n', f"WRANING: the remote `{repo_remote_root}` is dirty, please commit or stash changes before proceeding.", '\n', "=" * 50)
|
|
66
85
|
|
|
67
86
|
script = f"""
|
|
68
87
|
echo ""
|
|
69
88
|
echo "=============================== Committing Local Changes ==================================="
|
|
70
|
-
cd {
|
|
89
|
+
cd {repo_local_root}
|
|
71
90
|
git status
|
|
72
91
|
git add .
|
|
73
92
|
git commit -am "{message}"
|
|
74
93
|
echo ""
|
|
75
94
|
echo ""
|
|
76
95
|
echo "=============================== Pulling Latest From Remote ================================"
|
|
77
|
-
cd {
|
|
96
|
+
cd {repo_local_root}
|
|
78
97
|
echo '-> Trying to removing originEnc remote from local repo if it exists.'
|
|
79
98
|
git remote remove originEnc
|
|
80
99
|
echo '-> Adding originEnc remote to local repo'
|
|
81
|
-
git remote add originEnc {
|
|
100
|
+
git remote add originEnc {repo_remote_root}
|
|
82
101
|
echo '-> Fetching originEnc remote.'
|
|
83
102
|
git pull originEnc master
|
|
84
103
|
|
|
85
104
|
"""
|
|
86
105
|
suffix = '.ps1' if platform.system() == 'Windows' else '.sh'
|
|
87
|
-
res =
|
|
106
|
+
res = Terminal().run(f". {P.tmpfile(suffix=suffix).write_text(script)}", shell="powershell").capture().print()
|
|
88
107
|
|
|
89
108
|
if res.is_successful(strict_err=True, strict_returcode=True):
|
|
90
109
|
print("\n", "Pull succeeded, removing originEnc, the local copy of remote & pushing merged repo_root to remote ... ")
|
|
91
|
-
|
|
110
|
+
repo_remote_root.delete(sure=True)
|
|
92
111
|
from git.remote import Remote
|
|
93
|
-
Remote.remove(
|
|
112
|
+
Remote.remove(repo_local_obj, "originEnc")
|
|
94
113
|
if push:
|
|
95
|
-
|
|
114
|
+
repo_local_root.to_cloud(cloud=cloud_resolved, zip=True, encrypt=True, rel2home=True, pwd=pwd, os_specific=False)
|
|
96
115
|
else:
|
|
97
|
-
print(f"Failed to pull, keeping local copy of remote at {
|
|
116
|
+
print(f"Failed to pull, keeping local copy of remote at {repo_remote_root} ... ")
|
|
98
117
|
|
|
99
118
|
if push:
|
|
100
119
|
if skip_confirmation: resp = "y"
|
|
101
|
-
else: resp = input(f"Would you like to proceed syncing `{
|
|
120
|
+
else: resp = input(f"Would you like to proceed syncing `{repo_local_root}` to `{cloud_resolved}` by pushing local changes to remote and deleting local copy of remote? y/[n] ") or "n"
|
|
102
121
|
else: resp = "n"
|
|
103
122
|
|
|
104
123
|
if resp.lower() == "y":
|
|
105
|
-
delete_remote_repo_copy_and_push_local(remote_repo=
|
|
124
|
+
delete_remote_repo_copy_and_push_local(remote_repo=repo_remote_root.str, local_repo=repo_local_root.str, cloud=cloud_resolved)
|
|
106
125
|
else:
|
|
107
126
|
program = f"""
|
|
108
127
|
from machineconfig.scripts.python.cloud_repo_sync import delete_remote_repo_copy_and_push_local as func
|
|
109
|
-
func(remote_repo=r'{
|
|
128
|
+
func(remote_repo=r'{repo_remote_root.str}', local_repo=r'{repo_local_root.str}', cloud=r'{cloud_resolved}')
|
|
110
129
|
"""
|
|
111
130
|
shell_file = get_shell_file_executing_python_script(python_script=program)
|
|
112
131
|
print(f"When ready, use this snippet: \n. {shell_file}")
|
|
132
|
+
print(f"""
|
|
133
|
+
Or, if you want to delete local repo and replace with remote, run the following bash commands:
|
|
134
|
+
|
|
135
|
+
rm -rfd {repo_local_root}
|
|
136
|
+
mv {repo_remote_root} {repo_local_root}
|
|
137
|
+
|
|
138
|
+
""")
|
|
113
139
|
if platform.system() == "Windows":
|
|
114
|
-
program = get_wt_cmd(wd1=
|
|
140
|
+
program = get_wt_cmd(wd1=repo_local_root, wd2=repo_remote_root)
|
|
115
141
|
write_shell_script(program=program, execute=True)
|
|
116
142
|
return None
|
|
117
143
|
elif platform.system() == "Linux":
|
|
118
|
-
program = get_zellij_cmd(wd1=
|
|
144
|
+
program = get_zellij_cmd(wd1=repo_local_root, wd2=repo_remote_root)
|
|
119
145
|
write_shell_script(program=program, execute=True)
|
|
120
146
|
return None
|
|
121
147
|
else: raise NotImplementedError(f"Platform {platform.system()} not implemented.")
|
|
122
148
|
|
|
123
149
|
|
|
124
150
|
def delete_remote_repo_copy_and_push_local(remote_repo: str, local_repo: str, cloud: str):
|
|
125
|
-
repo_sync_root =
|
|
126
|
-
repo_root_path =
|
|
151
|
+
repo_sync_root = P(remote_repo).expanduser().absolute()
|
|
152
|
+
repo_root_path = P(local_repo).expanduser().absolute()
|
|
127
153
|
repo_sync_root.delete(sure=True)
|
|
128
154
|
from git.remote import Remote
|
|
129
155
|
from git.repo import Repo
|
|
@@ -5,14 +5,17 @@ TODO: use typer to make clis
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from crocodile.file_management import P, Read, Struct
|
|
8
|
-
from crocodile.core import install_n_import
|
|
8
|
+
# from crocodile.core import install_n_import
|
|
9
9
|
from machineconfig.utils.utils import PROGRAM_PATH, DEFAULTS_PATH
|
|
10
10
|
from machineconfig.scripts.python.cloud_mount import get_mprocs_mount_txt
|
|
11
11
|
import argparse
|
|
12
12
|
import os
|
|
13
13
|
from typing import Optional
|
|
14
14
|
# from dataclasses import dataclass
|
|
15
|
+
# install_n_import("pydantic")
|
|
15
16
|
# from tap import Tap
|
|
17
|
+
from pydantic.dataclasses import dataclass
|
|
18
|
+
from pydantic import ConfigDict
|
|
16
19
|
|
|
17
20
|
|
|
18
21
|
ES = "^" # chosen carefully to not mean anything on any shell. `$` was a bad choice.
|
|
@@ -32,15 +35,8 @@ class ArgsDefaults:
|
|
|
32
35
|
pwd = None
|
|
33
36
|
|
|
34
37
|
|
|
35
|
-
install_n_import("pydantic")
|
|
36
|
-
from pydantic.dataclasses import dataclass # type: ignore # ruffle: ignore
|
|
37
|
-
from pydantic import ConfigDict
|
|
38
|
-
|
|
39
|
-
|
|
40
38
|
@dataclass(config=ConfigDict(extra="forbid", frozen=True))
|
|
41
39
|
class Args():
|
|
42
|
-
# source: str
|
|
43
|
-
# target: str
|
|
44
40
|
cloud: Optional[str] = None
|
|
45
41
|
|
|
46
42
|
zip: bool = ArgsDefaults.zip_
|
|
@@ -81,12 +77,14 @@ def get_secure_share_cloud_config(interactive: bool = True) -> Args:
|
|
|
81
77
|
cloud = default_cloud
|
|
82
78
|
else:
|
|
83
79
|
try:
|
|
84
|
-
|
|
80
|
+
default_cloud__ = Read.ini(DEFAULTS_PATH)['general']['rclone_config_name']
|
|
85
81
|
except Exception:
|
|
86
|
-
|
|
87
|
-
if
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
default_cloud__ = 'No default cloud found.'
|
|
83
|
+
if default_cloud__ == 'No default cloud found.' or interactive:
|
|
84
|
+
# assert default_cloud is not None
|
|
85
|
+
cloud = input(f"Enter cloud name (default {default_cloud__}): ") or default_cloud__
|
|
86
|
+
else:
|
|
87
|
+
cloud = default_cloud__
|
|
90
88
|
|
|
91
89
|
default_password_path = P.home().joinpath("dotfiles/creds/passwords/quick_password")
|
|
92
90
|
if default_password_path.exists():
|
|
@@ -99,7 +97,7 @@ def get_secure_share_cloud_config(interactive: bool = True) -> Args:
|
|
|
99
97
|
res = Args(cloud=cloud,
|
|
100
98
|
pwd=pwd, encrypt=True,
|
|
101
99
|
zip=True, overwrite=True, share=True,
|
|
102
|
-
rel2home=True, root="
|
|
100
|
+
rel2home=True, root="myshare", os_specific=False,)
|
|
103
101
|
Struct(res.__dict__).print(as_config=True, title=f"⚠️ Using SecureShare cloud config")
|
|
104
102
|
return res
|
|
105
103
|
|
|
@@ -215,7 +213,7 @@ def args_parser():
|
|
|
215
213
|
parser.add_argument("--transfers", "-t", help="Number of threads in syncing.", default=10) # default is False
|
|
216
214
|
parser.add_argument("--root", "-R", help="Remote root.", default="myhome") # default is False
|
|
217
215
|
|
|
218
|
-
|
|
216
|
+
parser.add_argument("--key", "-k", help="Key for encryption", default=None)
|
|
219
217
|
parser.add_argument("--pwd", "-P", help="Password for encryption", default=None)
|
|
220
218
|
parser.add_argument("--encrypt", "-e", help="Decrypt after receiving.", action="store_true") # default is False
|
|
221
219
|
parser.add_argument("--zip", "-z", help="unzip after receiving.", action="store_true") # default is False
|
|
@@ -8,7 +8,7 @@ import argparse
|
|
|
8
8
|
# import subprocess
|
|
9
9
|
# import platform
|
|
10
10
|
from crocodile.file_management import P, randstr
|
|
11
|
-
from machineconfig.utils.ve import get_ipython_profile, get_ve_profile
|
|
11
|
+
from machineconfig.utils.ve import get_ipython_profile, get_ve_profile, get_ve_name_and_ipython_profile
|
|
12
12
|
from machineconfig.utils.utils import PROGRAM_PATH, display_options
|
|
13
13
|
|
|
14
14
|
|
|
@@ -34,8 +34,8 @@ def get_read_data_pycode(path: str):
|
|
|
34
34
|
p = P(r\'{path}\').absolute()
|
|
35
35
|
try:
|
|
36
36
|
dat = p.readit()
|
|
37
|
-
if
|
|
38
|
-
else: print(f"
|
|
37
|
+
if isinstance(dat, dict): Struct(dat).print(as_config=True, title=p.name)
|
|
38
|
+
else: print(f"Successfully read the file {{p.name}}")
|
|
39
39
|
except Exception as e:
|
|
40
40
|
print(e)
|
|
41
41
|
|
|
@@ -67,7 +67,7 @@ def build_parser():
|
|
|
67
67
|
parser.add_argument("--fzf", "-F", help="search with fuzzy finder for python scripts and run them", action="store_true", default=False)
|
|
68
68
|
|
|
69
69
|
# OPTIONAL KEYWORD
|
|
70
|
-
parser.add_argument("--
|
|
70
|
+
parser.add_argument("--ve", "-v", help="virtual enviroment to use, defaults to activated ve, if existed, else ve.", default=None)
|
|
71
71
|
parser.add_argument("--profile", "-P", help="ipython profile to use, defaults to default profile.", default=None)
|
|
72
72
|
parser.add_argument("--read", "-r", dest="read", help="read a binary file.", default="")
|
|
73
73
|
parser.add_argument("--file", "-f", dest="file", help="python file path to interpret", default="")
|
|
@@ -93,17 +93,23 @@ def build_parser():
|
|
|
93
93
|
options = P.cwd().search("*.py", r=True).apply(str).list
|
|
94
94
|
file = display_options(msg="Choose a python file to run", options=options, fzf=True, multi=False, )
|
|
95
95
|
assert isinstance(file, str)
|
|
96
|
-
if profile is None:
|
|
96
|
+
if profile is None:
|
|
97
|
+
profile = get_ipython_profile(P(file))
|
|
97
98
|
program = P(file).read_text(encoding='utf-8')
|
|
98
99
|
|
|
99
100
|
elif args.file != "":
|
|
100
101
|
file = P(args.file.lstrip()).expanduser().absolute()
|
|
101
|
-
if profile is None:
|
|
102
|
+
if profile is None:
|
|
103
|
+
profile = get_ipython_profile(P(file))
|
|
102
104
|
program = get_read_pyfile_pycode(file, as_module=args.module, cmd=args.cmd)
|
|
103
105
|
|
|
104
106
|
elif args.read != "":
|
|
105
107
|
file = P(str(args.read).lstrip()).expanduser().absolute()
|
|
106
|
-
|
|
108
|
+
ve_name_from_file, ipy_profile_from_file = get_ve_name_and_ipython_profile(init_path=P(file))
|
|
109
|
+
# if profile is None:
|
|
110
|
+
# profile = get_ipython_profile(P(file))
|
|
111
|
+
if profile is None: profile = ipy_profile_from_file
|
|
112
|
+
if args.ve is None: args.ve = ve_name_from_file
|
|
107
113
|
program = get_read_data_pycode(str(file))
|
|
108
114
|
|
|
109
115
|
else: # just run croshell.py interactively
|
|
@@ -129,9 +135,11 @@ print_logo(logo="crocodile")
|
|
|
129
135
|
total_program = preprogram + add_print_header_pycode(str(pyfile), title=title) + program
|
|
130
136
|
|
|
131
137
|
pyfile.write_text(total_program, encoding='utf-8')
|
|
132
|
-
if profile is None:
|
|
138
|
+
if profile is None:
|
|
139
|
+
profile = get_ipython_profile(P.cwd())
|
|
140
|
+
# profile = "default"
|
|
133
141
|
|
|
134
|
-
ve = get_ve_profile(P(file)) if args.
|
|
142
|
+
ve = get_ve_profile(P(file)) if args.ve is None else str(args.ve)
|
|
135
143
|
|
|
136
144
|
final_program = f"""
|
|
137
145
|
# deactivate
|
|
@@ -140,7 +148,8 @@ print_logo(logo="crocodile")
|
|
|
140
148
|
if interpreter == "ipython": final_program += f"{interactivity} --profile {profile} --no-banner"
|
|
141
149
|
final_program += f" {str(pyfile)}"
|
|
142
150
|
print(f"🔥 sourcing ... {pyfile}")
|
|
143
|
-
|
|
151
|
+
# print(f"Running ... {final_program}")
|
|
152
|
+
PROGRAM_PATH.write_text(data=final_program)
|
|
144
153
|
|
|
145
154
|
# if platform.system() == "Windows":
|
|
146
155
|
# return subprocess.run([f"powershell", "-Command", res], shell=True, capture_output=False, text=True, check=True)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
|
|
2
|
+
|
|
3
|
+
|
|
2
4
|
"""devops
|
|
3
5
|
"""
|
|
4
|
-
|
|
5
|
-
from platform import system
|
|
6
|
-
# import subprocess
|
|
7
|
-
# import crocodile.toolbox as tb
|
|
6
|
+
from crocodile.file_management import P
|
|
8
7
|
from machineconfig.utils.utils import display_options, PROGRAM_PATH, write_shell_script
|
|
8
|
+
from platform import system
|
|
9
9
|
from enum import Enum
|
|
10
10
|
from typing import Optional
|
|
11
11
|
|
|
@@ -48,8 +48,24 @@ def main(which: Optional[str] = None):
|
|
|
48
48
|
program = helper.main()
|
|
49
49
|
|
|
50
50
|
elif choice_key == Options.ve.value:
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
program = ""
|
|
52
|
+
reply: bool = False
|
|
53
|
+
if P.cwd().joinpath(".ve.ini").exists():
|
|
54
|
+
reply = input("Detected .ve.ini file. Do you want to use it to build ve? (y/[n]): ") == "y"
|
|
55
|
+
if reply:
|
|
56
|
+
from machineconfig.utils.ve import get_ve_install_script_from_specs
|
|
57
|
+
program_win = get_ve_install_script_from_specs(repo_root=P.cwd().str, system="Windows")
|
|
58
|
+
program_lin = get_ve_install_script_from_specs(repo_root=P.cwd().str, system="Linux")
|
|
59
|
+
install_reply = input("Proceed with installation? (y/[n]): ") == "y"
|
|
60
|
+
if not install_reply: program = ""
|
|
61
|
+
else:
|
|
62
|
+
if system() == "Windows": program = program_win
|
|
63
|
+
elif system() == "Linux": program = program_lin
|
|
64
|
+
else: raise ValueError(f"Unknown system: {system()}")
|
|
65
|
+
|
|
66
|
+
if not reply:
|
|
67
|
+
from machineconfig.utils.ve import get_ve_install_script
|
|
68
|
+
program = get_ve_install_script()
|
|
53
69
|
|
|
54
70
|
elif choice_key == Options.cli_install.value:
|
|
55
71
|
import machineconfig.scripts.python.devops_devapps_install as helper
|
|
@@ -2,20 +2,21 @@
|
|
|
2
2
|
"""ID
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
# from platform import system
|
|
7
|
+
from crocodile.file_management import P
|
|
7
8
|
from machineconfig.utils.utils import display_options
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
def main():
|
|
11
|
-
private_keys =
|
|
12
|
+
private_keys = P.home().joinpath(".ssh").search("*.pub").apply(lambda x: x.with_name(x.stem)).filter(lambda x: x.exists())
|
|
12
13
|
choice = display_options(msg="Path to private key to be used when ssh'ing: ", options=private_keys.apply(str).list + ["I have the path to the key file", "I want to paste the key itself"])
|
|
13
|
-
if choice == "I have the path to the key file": path_to_key =
|
|
14
|
-
elif choice == "I want to paste the key itself": path_to_key =
|
|
15
|
-
elif isinstance(choice, str): path_to_key =
|
|
14
|
+
if choice == "I have the path to the key file": path_to_key = P(input("Input path here: ")).expanduser().absolute()
|
|
15
|
+
elif choice == "I want to paste the key itself": path_to_key = P.home().joinpath(f".ssh/{input('file name (default: my_pasted_key): ') or 'my_pasted_key'}").write_text(input("Paste the private key here: "))
|
|
16
|
+
elif isinstance(choice, str): path_to_key = P(choice)
|
|
16
17
|
else: raise NotImplementedError(f"Choice {choice} not supported")
|
|
17
18
|
txt = f"IdentityFile {path_to_key.collapseuser().as_posix()}" # adds this id for all connections, no host specified.
|
|
18
|
-
config_path =
|
|
19
|
+
config_path = P.home().joinpath(".ssh/config")
|
|
19
20
|
if config_path.exists(): config_path.modify_text(txt_search=txt, txt_alt=txt, replace_line=True, notfound_append=True, prepend=True) # note that Identity line must come on top of config file otherwise it won't work, hence `prepend=True`
|
|
20
21
|
else: config_path.write_text(txt)
|
|
21
22
|
program = f"echo 'Finished adding identity to ssh config file. {'*'*50} Consider reloading config file.'"
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
"""SSH
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
from platform import system
|
|
7
7
|
from machineconfig.utils.utils import LIBRARY_ROOT, display_options
|
|
8
|
+
from crocodile.file_management import P
|
|
8
9
|
|
|
9
10
|
|
|
10
|
-
def get_add_ssh_key_script(path_to_key:
|
|
11
|
-
if system() == "Linux": authorized_keys =
|
|
12
|
-
elif system() == "Windows": authorized_keys =
|
|
11
|
+
def get_add_ssh_key_script(path_to_key: P):
|
|
12
|
+
if system() == "Linux": authorized_keys = P.home().joinpath(".ssh/authorized_keys")
|
|
13
|
+
elif system() == "Windows": authorized_keys = P("C:/ProgramData/ssh/administrators_authorized_keys")
|
|
13
14
|
else: raise NotImplementedError
|
|
14
15
|
|
|
15
16
|
if authorized_keys.exists():
|
|
@@ -35,7 +36,7 @@ def get_add_ssh_key_script(path_to_key: tb.P):
|
|
|
35
36
|
program = f"cat {path_to_key} > ~/.ssh/authorized_keys"
|
|
36
37
|
else:
|
|
37
38
|
program = LIBRARY_ROOT.joinpath("setup_windows/openssh-server_add-sshkey.ps1")
|
|
38
|
-
program =
|
|
39
|
+
program = P(program).expanduser().read_text().replace('$sshfile=""', f'$sshfile="{path_to_key}"')
|
|
39
40
|
|
|
40
41
|
if system() == "Linux": program += f"""
|
|
41
42
|
|
|
@@ -50,17 +51,17 @@ sudo service ssh --full-restart
|
|
|
50
51
|
|
|
51
52
|
|
|
52
53
|
def main():
|
|
53
|
-
pub_keys =
|
|
54
|
+
pub_keys = P.home().joinpath(".ssh").search("*.pub")
|
|
54
55
|
all_keys_option = f"all pub keys available ({len(pub_keys)})"
|
|
55
56
|
i_have_path_option = "I have the path to the key file"
|
|
56
57
|
i_paste_option = "I want to paste the key itself"
|
|
57
58
|
res = display_options("Which public key to add? ", options=pub_keys.apply(str).list + [all_keys_option, i_have_path_option, i_paste_option])
|
|
58
59
|
assert isinstance(res, str), f"Got {res} of type {type(res)} instead of str."
|
|
59
60
|
if res == all_keys_option: program = "\n\n\n".join(pub_keys.apply(get_add_ssh_key_script))
|
|
60
|
-
elif res == i_have_path_option: program = get_add_ssh_key_script(
|
|
61
|
-
elif res == i_paste_option: program = get_add_ssh_key_script(
|
|
61
|
+
elif res == i_have_path_option: program = get_add_ssh_key_script(P(input("Path: ")).expanduser().absolute())
|
|
62
|
+
elif res == i_paste_option: program = get_add_ssh_key_script(P.home().joinpath(f".ssh/{input('file name (default: my_pasted_key.pub): ') or 'my_pasted_key.pub'}").write_text(input("Paste the pub key here: ")))
|
|
62
63
|
else:
|
|
63
|
-
program = get_add_ssh_key_script(
|
|
64
|
+
program = get_add_ssh_key_script(P(res))
|
|
64
65
|
print(program)
|
|
65
66
|
return program
|
|
66
67
|
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"""BR: Backup and Retrieve
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from platform import system
|
|
6
5
|
# import subprocess
|
|
7
|
-
|
|
6
|
+
from crocodile.file_management import Read, P
|
|
8
7
|
from machineconfig.utils.utils import LIBRARY_ROOT, DEFAULTS_PATH, print_code, choose_cloud_interactively, display_options
|
|
9
8
|
from machineconfig.scripts.python.cloud_sync import ES
|
|
9
|
+
from platform import system
|
|
10
10
|
from typing import Any, Literal, Optional
|
|
11
11
|
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ OPTIONS = Literal["BACKUP", "RETRIEVE"]
|
|
|
15
15
|
|
|
16
16
|
def main(direction: OPTIONS, which: Optional[str] = None):
|
|
17
17
|
try:
|
|
18
|
-
cloud: str =
|
|
18
|
+
cloud: str = Read.ini(DEFAULTS_PATH)['general']['rclone_config_name']
|
|
19
19
|
print(f"\n{'--' * 50}\n ⚠️ Using default cloud: `{cloud}` ⚠️\n{'--' * 50}\n")
|
|
20
20
|
except (FileNotFoundError, KeyError, IndexError): cloud = choose_cloud_interactively()
|
|
21
21
|
|
|
@@ -40,8 +40,8 @@ def main(direction: OPTIONS, which: Optional[str] = None):
|
|
|
40
40
|
flags += 'r' if item['rel2home'] == 'True' else ''
|
|
41
41
|
flags += 'o' if system().lower() in item_name else ''
|
|
42
42
|
if flags: flags = "-" + flags
|
|
43
|
-
if direction == "BACKUP": program += f"""\ncloud_copy "{
|
|
44
|
-
elif direction == "RETRIEVE": program += f"""\ncloud_copy $cloud "{
|
|
43
|
+
if direction == "BACKUP": program += f"""\ncloud_copy "{P(item['path']).as_posix()}" $cloud {flags}\n"""
|
|
44
|
+
elif direction == "RETRIEVE": program += f"""\ncloud_copy $cloud "{P(item['path']).as_posix()}" {flags}\n"""
|
|
45
45
|
else: raise RuntimeError(f"Unknown direction: {direction}")
|
|
46
46
|
if item_name == "dotfiles" and system() == "Linux": program += f"""\nchmod 700 ~/.ssh/*\n"""
|
|
47
47
|
print_code(program, lexer="shell", desc=f"{direction} script")
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
"""Devops Devapps Install
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from platform import system
|
|
6
5
|
# import subprocess
|
|
7
|
-
|
|
6
|
+
from tqdm import tqdm
|
|
7
|
+
from crocodile.core import List as L
|
|
8
8
|
from machineconfig.utils.utils import LIBRARY_ROOT, choose_multiple_options
|
|
9
|
-
from machineconfig.utils.installer import
|
|
9
|
+
from machineconfig.utils.installer import get_installers, Installer, install_all
|
|
10
|
+
from platform import system
|
|
10
11
|
from typing import Any, Optional, Literal, TypeAlias
|
|
11
12
|
|
|
12
13
|
|
|
@@ -15,11 +16,10 @@ WHICH: TypeAlias = Literal["AllEssentials", "EssentialsAndOthers", "SystemInstal
|
|
|
15
16
|
|
|
16
17
|
def main(which: Optional[str] = None):
|
|
17
18
|
sys = system()
|
|
18
|
-
installers =
|
|
19
|
+
installers = get_installers(dev=False, system=sys) # + get_installers(dev=True, system=sys)
|
|
19
20
|
default = "AllEssentials"
|
|
20
|
-
options = ["SystemInstallers", "OtherDevApps", "EssentialsAndOthers", "PrecheckedCloudInstaller"]
|
|
21
|
-
options = [
|
|
22
|
-
options = [x.get_description() for x in installers] + options
|
|
21
|
+
options = ["SystemInstallers", "OtherDevApps", "EssentialsAndOthers", "PrecheckedCloudInstaller", default]
|
|
22
|
+
options = [x.get_description() for x in tqdm(installers, desc="Checking installed programs")] + options
|
|
23
23
|
|
|
24
24
|
if which is not None:
|
|
25
25
|
return get_program(program_name=which, options=options, installers=list(installers))
|
|
@@ -34,14 +34,17 @@ def main(which: Optional[str] = None):
|
|
|
34
34
|
|
|
35
35
|
def get_program(program_name: str, options: list[str], installers: list[Installer]):
|
|
36
36
|
if program_name == "AllEssentials" or program_name == "EssentialsAndOthers":
|
|
37
|
-
installers_ =
|
|
37
|
+
installers_ = get_installers(dev=False, system=system())
|
|
38
38
|
if program_name == "EssentialsAndOthers":
|
|
39
|
-
installers_ +=
|
|
40
|
-
|
|
39
|
+
installers_ += get_installers(dev=True, system=system())
|
|
40
|
+
install_all(installers=L(installers))
|
|
41
41
|
program = ""
|
|
42
42
|
elif program_name == "SystemInstallers":
|
|
43
43
|
if system() == "Windows": options_system = parse_apps_installer_windows(LIBRARY_ROOT.joinpath("setup_windows/apps.ps1").read_text())
|
|
44
|
-
elif system() == "Linux":
|
|
44
|
+
elif system() == "Linux":
|
|
45
|
+
options_system_1 = parse_apps_installer_linux(LIBRARY_ROOT.joinpath("setup_linux/apps_dev.sh").read_text())
|
|
46
|
+
options_system_2 = parse_apps_installer_linux(LIBRARY_ROOT.joinpath("setup_linux/apps.sh").read_text())
|
|
47
|
+
options_system = {**options_system_1, **options_system_2}
|
|
45
48
|
else: raise NotImplementedError(f"System {system()} not supported")
|
|
46
49
|
program_names = choose_multiple_options(msg="", options=sorted(list(options_system.keys())), header="CHOOSE DEV APP")
|
|
47
50
|
program = ""
|
|
@@ -50,10 +53,13 @@ def get_program(program_name: str, options: list[str], installers: list[Installe
|
|
|
50
53
|
if sub_program.startswith("#winget"): sub_program = sub_program[1:]
|
|
51
54
|
program += "\n" + sub_program
|
|
52
55
|
elif program_name == "OtherDevApps":
|
|
53
|
-
installers =
|
|
54
|
-
options__: list[str] = [x.get_description() for x in installers]
|
|
55
|
-
program_names = choose_multiple_options(msg="", options=sorted(options__), header="CHOOSE DEV APP")
|
|
56
|
+
installers = get_installers(dev=True, system=system())
|
|
57
|
+
options__: list[str] = [x.get_description() for x in tqdm(installers, desc="Checking installed programs")]
|
|
58
|
+
program_names = choose_multiple_options(msg="", options=sorted(options__) + ["all"], header="CHOOSE DEV APP")
|
|
59
|
+
if "all" in program_names: program_names = options__
|
|
56
60
|
program = ""
|
|
61
|
+
print(f"Installing:")
|
|
62
|
+
L(program_names).print()
|
|
57
63
|
for name in program_names:
|
|
58
64
|
try:
|
|
59
65
|
idx = options__.index(name)
|
|
@@ -61,9 +67,8 @@ def get_program(program_name: str, options: list[str], installers: list[Installe
|
|
|
61
67
|
print(f"{name=}")
|
|
62
68
|
print(f"{options__=}")
|
|
63
69
|
raise ve
|
|
70
|
+
print(f"Installing {name}")
|
|
64
71
|
sub_program = installers[idx].install_robust(version=None) # finish the task
|
|
65
|
-
# sub_program = "echo 'Finished Installation'" # write an empty program
|
|
66
|
-
# program += "\n" + ""sub_program
|
|
67
72
|
elif program_name == "PrecheckedCloudInstaller":
|
|
68
73
|
from machineconfig.jobs.python.check_installations import PrecheckedCloudInstaller
|
|
69
74
|
ci = PrecheckedCloudInstaller()
|
|
@@ -97,7 +102,7 @@ def parse_apps_installer_windows(txt: str) -> dict[str, Any]:
|
|
|
97
102
|
if idx == 0: continue
|
|
98
103
|
if idx == 1: chunks.append(item)
|
|
99
104
|
else: chunks.append("winget install" + item)
|
|
100
|
-
# progs =
|
|
105
|
+
# progs = L(txt.splitlines()).filter(lambda x: x.startswith("winget ") or x.startswith("#winget"))
|
|
101
106
|
res: dict[str, str] = {}
|
|
102
107
|
for a_chunk in chunks:
|
|
103
108
|
try:
|
|
@@ -110,8 +115,8 @@ def parse_apps_installer_windows(txt: str) -> dict[str, Any]:
|
|
|
110
115
|
except IndexError as e:
|
|
111
116
|
print(a_chunk)
|
|
112
117
|
raise e
|
|
113
|
-
#
|
|
114
|
-
#
|
|
118
|
+
# Struct(res).print(as_config=True)
|
|
119
|
+
# L(chunks).print(sep="-----------------------------------------------------------------------\n\n")
|
|
115
120
|
# import time
|
|
116
121
|
# time.sleep(10)
|
|
117
122
|
return res
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
"""Update
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
|
|
5
|
+
from crocodile.file_management import P, Read
|
|
6
|
+
from crocodile.core import install_n_import
|
|
7
7
|
from machineconfig.utils.utils import DEFAULTS_PATH
|
|
8
|
+
from platform import system
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
sep = "\n"
|
|
@@ -14,7 +15,7 @@ def main(verbose: bool = True) -> str:
|
|
|
14
15
|
_ = verbose
|
|
15
16
|
repos: list[str] = ["~/code/crocodile", "~/code/machineconfig", ]
|
|
16
17
|
try:
|
|
17
|
-
tmp =
|
|
18
|
+
tmp = Read.ini(DEFAULTS_PATH)['general']['repos'].split(",")
|
|
18
19
|
if tmp[-1] == "": tmp = tmp[:-1]
|
|
19
20
|
repos += tmp
|
|
20
21
|
except (FileNotFoundError, KeyError, IndexError):
|
|
@@ -30,7 +31,7 @@ to_email = myemail@email.com
|
|
|
30
31
|
repos_objs = []
|
|
31
32
|
for a_package_path in repos:
|
|
32
33
|
try:
|
|
33
|
-
repo =
|
|
34
|
+
repo = install_n_import("git", "gitpython").Repo(str(P(a_package_path).expanduser()), search_parent_directories=True)
|
|
34
35
|
repos_objs.append(repo)
|
|
35
36
|
except Exception as ex:
|
|
36
37
|
print(ex)
|