machineconfig 1.7__py3-none-any.whl → 1.8__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.

Files changed (63) hide show
  1. machineconfig/__init__.py +2 -2
  2. machineconfig/jobs/python/check_installations.py +37 -31
  3. machineconfig/jobs/python/create_bootable_media.py +4 -4
  4. machineconfig/jobs/python/create_zellij_template.py +3 -2
  5. machineconfig/jobs/python/python_cargo_build_share.py +14 -9
  6. machineconfig/jobs/python/python_ve_symlink.py +6 -6
  7. machineconfig/jobs/{python_linux_installers/dev → script_installer}/azure_data_studio.py +6 -5
  8. machineconfig/jobs/{python_windows_installers/dev → script_installer}/bypass_paywall.py +5 -4
  9. machineconfig/jobs/script_installer/code.py +34 -0
  10. machineconfig/jobs/{python_linux_installers/dev → script_installer}/docker_desktop.py +2 -2
  11. machineconfig/jobs/script_installer/ngrok.py +29 -0
  12. machineconfig/jobs/script_installer/skim.py +21 -0
  13. machineconfig/jobs/script_installer/wezterm.py +34 -0
  14. machineconfig/profile/create.py +8 -6
  15. machineconfig/profile/shell.py +15 -13
  16. machineconfig/scripts/python/cloud_copy.py +14 -13
  17. machineconfig/scripts/python/cloud_mount.py +27 -11
  18. machineconfig/scripts/python/cloud_repo_sync.py +32 -14
  19. machineconfig/scripts/python/cloud_sync.py +9 -9
  20. machineconfig/scripts/python/croshell.py +3 -3
  21. machineconfig/scripts/python/devops.py +22 -6
  22. machineconfig/scripts/python/devops_add_identity.py +7 -6
  23. machineconfig/scripts/python/devops_add_ssh_key.py +10 -9
  24. machineconfig/scripts/python/devops_backup_retrieve.py +5 -5
  25. machineconfig/scripts/python/devops_devapps_install.py +13 -14
  26. machineconfig/scripts/python/devops_update_repos.py +5 -4
  27. machineconfig/scripts/python/dotfile.py +8 -4
  28. machineconfig/scripts/python/fire_jobs.py +95 -24
  29. machineconfig/scripts/python/ftpx.py +1 -1
  30. machineconfig/scripts/python/mount_nfs.py +13 -10
  31. machineconfig/scripts/python/mount_nw_drive.py +4 -3
  32. machineconfig/scripts/python/mount_ssh.py +8 -5
  33. machineconfig/scripts/python/repos.py +21 -20
  34. machineconfig/scripts/python/snapshot.py +2 -2
  35. machineconfig/scripts/python/start_slidev.py +104 -0
  36. machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +20 -34
  37. machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +11 -12
  38. machineconfig/utils/installer.py +96 -204
  39. machineconfig/utils/scheduling.py +1 -1
  40. machineconfig/utils/utils.py +102 -51
  41. machineconfig/utils/ve.py +96 -13
  42. {machineconfig-1.7.dist-info → machineconfig-1.8.dist-info}/METADATA +8 -8
  43. machineconfig-1.8.dist-info/RECORD +70 -0
  44. machineconfig/jobs/python_generic_installers/archive/gopass.py +0 -18
  45. machineconfig/jobs/python_generic_installers/archive/nvim.py +0 -20
  46. machineconfig/jobs/python_generic_installers/archive/opencommit.py +0 -25
  47. machineconfig/jobs/python_generic_installers/archive/strongbox.py +0 -33
  48. machineconfig/jobs/python_generic_installers/dev/__init__.py +0 -0
  49. machineconfig/jobs/python_linux_installers/archive/__init__.py +0 -0
  50. machineconfig/jobs/python_linux_installers/archive/bandwhich.py +0 -14
  51. machineconfig/jobs/python_linux_installers/archive/ranger.py +0 -19
  52. machineconfig/jobs/python_linux_installers/dev/bytehound.py +0 -20
  53. machineconfig/jobs/python_linux_installers/dev/nnn.py +0 -22
  54. machineconfig/jobs/python_windows_installers/archive/ntop.py +0 -21
  55. machineconfig/jobs/python_windows_installers/dev/obs_background_removal_plugin.py +0 -22
  56. machineconfig/scripts/python/choose_ohmybash_theme.py +0 -31
  57. machineconfig/scripts/python/choose_ohmyposh_theme.py +0 -57
  58. machineconfig/utils/pandas_type.py +0 -37
  59. machineconfig/utils/to_exe.py +0 -7
  60. machineconfig-1.7.dist-info/RECORD +0 -81
  61. /machineconfig/jobs/{python_generic_installers/archive → script_installer}/__init__.py +0 -0
  62. {machineconfig-1.7.dist-info → machineconfig-1.8.dist-info}/WHEEL +0 -0
  63. {machineconfig-1.7.dist-info → machineconfig-1.8.dist-info}/top_level.txt +0 -0
@@ -13,7 +13,8 @@ from rich.panel import Panel
13
13
  from rich.console import Console
14
14
  from rich.syntax import Syntax
15
15
  import platform
16
- from typing import Optional, Union, TypeVar
16
+ import subprocess
17
+ from typing import Optional, Union, TypeVar, Iterable
17
18
 
18
19
 
19
20
  LIBRARY_ROOT = P(machineconfig.__file__).resolve().parent # .replace(P.home().str.lower(), P.home().str)
@@ -35,17 +36,16 @@ def choose_cloud_interactively() -> str:
35
36
  tmp = Terminal().run("rclone listremotes").op_if_successfull_or_default(strict_returcode=False)
36
37
  # consider this: remotes = Read.ini(P.home().joinpath(".config/rclone/rclone.conf")).sections()
37
38
  if isinstance(tmp, str):
38
- remotes = L(tmp.splitlines()).apply(lambda x: x.replace(":", ""))
39
+ remotes: list[str] = L(tmp.splitlines()).apply(lambda x: x.replace(":", "")).list
39
40
 
40
41
  else: raise ValueError(f"Got {tmp} from rclone listremotes")
41
42
  if len(remotes) == 0:
42
43
  raise RuntimeError(f"You don't have remotes. Configure your rclone first to get cloud services access.")
43
- cloud = display_options(msg="WHICH CLOUD?", options=list(remotes), default=remotes[0], fzf=True)
44
- assert isinstance(cloud, str)
44
+ cloud: str = choose_one_option(msg="WHICH CLOUD?", options=list(remotes), default=remotes[0], fzf=True)
45
45
  return cloud
46
46
 
47
47
 
48
- def sanitize_path(a_path: P):
48
+ def sanitize_path(a_path: P) -> P:
49
49
  path = P(a_path)
50
50
  if path.as_posix().startswith("/home"):
51
51
  if platform.system() == "Windows": # path copied from Linux to Windows
@@ -69,24 +69,56 @@ def sanitize_path(a_path: P):
69
69
  return path.expanduser().absolute()
70
70
 
71
71
 
72
- def match_file_name(sub_string: str):
72
+ def match_file_name(sub_string: str, search_root: Optional[P] = None) -> P:
73
73
  """Look up current directory for file name that matches the passed substring."""
74
- print(f"Searching for {sub_string} in {P.cwd()}")
75
- search_results = P.cwd().absolute().search(f"*{sub_string}*.py", r=True)
74
+ root = search_root if search_root is not None else P.cwd()
75
+ print(f"Searching for {sub_string} in {root}")
76
+ search_results = root.absolute().search(f"*{sub_string}*.py", r=True)
76
77
  if len(search_results) == 1:
77
78
  path_obj = search_results.list[0]
78
79
  elif len(search_results) > 1:
79
- choice = display_options(msg=f"Search results are ambiguous or non-existent", options=search_results.list, fzf=True, multi=False)
80
- assert not isinstance(choice, list)
80
+ choice = choose_one_option(msg=f"Search results are ambiguous or non-existent", options=search_results.list, fzf=True)
81
81
  path_obj = P(choice)
82
82
  else:
83
+ # let's do a final retry with sub_string.small()
84
+ sub_string_small = sub_string.lower()
85
+ if sub_string_small != sub_string:
86
+ return match_file_name(sub_string=sub_string_small)
87
+ from git.repo import Repo
88
+ from git.exc import InvalidGitRepositoryError
89
+ try:
90
+ repo = Repo(root, search_parent_directories=True)
91
+ repo_root_dir = P(repo.working_dir)
92
+ if repo_root_dir != root: # may be user is in a subdirectory of the repo root, try with root dir.
93
+ return match_file_name(sub_string=sub_string, search_root=repo_root_dir)
94
+ else:
95
+ root = repo_root_dir
96
+ except InvalidGitRepositoryError:
97
+ pass
98
+
99
+ if check_tool_exists("fzf"):
100
+ try:
101
+ search_res = subprocess.run(f"cd '{root}'; fzf --filter={sub_string}", stdout=subprocess.PIPE, text=True, check=True, shell=True).stdout.split("\n")[:-1]
102
+ except subprocess.CalledProcessError as cpe:
103
+ print(f"Failed at fzf search with {sub_string} in {root}.\n{cpe}")
104
+ msg = f"\n{'--' * 50}\n💥 Path {sub_string} does not exist. No search results\n{'--' * 50}\n"
105
+ raise FileNotFoundError(msg) from cpe
106
+ if len(search_res) == 1: return root.joinpath(search_res[0])
107
+ else:
108
+ try:
109
+ res = subprocess.run(f"cd '{root}'; fzf --query={sub_string}", check=True, stdout=subprocess.PIPE, text=True, shell=True).stdout.strip()
110
+ except subprocess.CalledProcessError as cpe:
111
+ print(f"Failed at fzf search with {sub_string} in {root}. {cpe}")
112
+ msg = f"\n{'--' * 50}\n💥 Path {sub_string} does not exist. No search results\n{'--' * 50}\n"
113
+ raise FileNotFoundError(msg) from cpe
114
+ return root.joinpath(res)
83
115
  msg = f"\n{'--' * 50}\n💥 Path {sub_string} does not exist. No search results\n{'--' * 50}\n"
84
116
  raise FileNotFoundError(msg)
85
117
  print(f"\n{'--' * 50}\n🔗 Matched `{sub_string}` ➡️ `{path_obj}`\n{'--' * 50}\n")
86
118
  return path_obj
87
119
 
88
120
 
89
- def choose_one_option(options: list[T], header: str = "", tail: str = "", prompt: str = "", msg: str = "",
121
+ def choose_one_option(options: Iterable[T], header: str = "", tail: str = "", prompt: str = "", msg: str = "",
90
122
  default: Optional[T] = None, fzf: bool = False, custom_input: bool = False) -> T:
91
123
  choice_key = display_options(msg=msg, options=options, header=header, tail=tail, prompt=prompt,
92
124
  default=default, fzf=fzf, multi=False, custom_input=custom_input)
@@ -94,7 +126,7 @@ def choose_one_option(options: list[T], header: str = "", tail: str = "", prompt
94
126
  return choice_key
95
127
 
96
128
 
97
- def choose_multiple_options(options: list[T], header: str = "", tail: str = "", prompt: str = "", msg: str = "",
129
+ def choose_multiple_options(options: Iterable[T], header: str = "", tail: str = "", prompt: str = "", msg: str = "",
98
130
  default: Optional[T] = None, custom_input: bool = False) -> list[T]:
99
131
  choice_key = display_options(msg=msg, options=options, header=header, tail=tail, prompt=prompt,
100
132
  default=default, fzf=True, multi=True,
@@ -103,23 +135,30 @@ def choose_multiple_options(options: list[T], header: str = "", tail: str = "",
103
135
  return [choice_key]
104
136
 
105
137
 
106
- def display_options(msg: str, options: list[T], header: str = "", tail: str = "", prompt: str = "",
138
+ def display_options(msg: str, options: Iterable[T], header: str = "", tail: str = "", prompt: str = "",
107
139
  default: Optional[T] = None, fzf: bool = False, multi: bool = False, custom_input: bool = False) -> Union[T, list[T]]:
108
140
  # TODO: replace with https://github.com/tmbo/questionary # also see https://github.com/charmbracelet/gum
109
141
  tool_name = "fzf"
142
+ options_strings: list[str] = [str(x) for x in options]
143
+ default_string = str(default) if default is not None else None
110
144
  if fzf and check_tool_exists(tool_name):
111
145
  install_n_import("pyfzf")
112
146
  from pyfzf.pyfzf import FzfPrompt
113
147
  fzf_prompt = FzfPrompt()
114
148
  nl = "\n"
115
- choice_key = fzf_prompt.prompt(choices=options, fzf_options=("--multi" if multi else "") + f' --prompt "{prompt.replace(nl, " ")}" ') # --border-label={msg.replace(nl, ' ')}")
149
+ choice_string_multi: list[str] = fzf_prompt.prompt(choices=options_strings, fzf_options=("--multi" if multi else "") + f' --prompt "{prompt.replace(nl, " ")}" ') # --border-label={msg.replace(nl, ' ')}")
116
150
  # --border=rounded doens't work on older versions of fzf installed at Ubuntu 20.04
117
151
  if not multi:
118
- try: choice_key = choice_key[0]
152
+ try:
153
+ choice_one_string = choice_string_multi[0]
154
+ choice_idx = options_strings.index(choice_one_string)
155
+ return list(options)[choice_idx]
119
156
  except IndexError as ie:
120
- print(f"{options=}, {choice_key=}")
121
- print(choice_key)
157
+ print(f"{options=}, {choice_string_multi=}")
158
+ print(choice_string_multi)
122
159
  raise ie
160
+ choice_idx_s = [options_strings.index(x) for x in choice_string_multi]
161
+ return [list(options)[x] for x in choice_idx_s]
123
162
  else:
124
163
  console = Console()
125
164
  if default is not None:
@@ -134,29 +173,33 @@ def display_options(msg: str, options: list[T], header: str = "", tail: str = ""
134
173
  if default is not None:
135
174
  choice_string = input(f"{prompt}\nEnter option number or hit enter for default choice: ")
136
175
  else: choice_string = input(f"{prompt}\nEnter option number: ")
176
+
137
177
  if choice_string == "":
138
- assert default is not None, f"Default option not available!"
139
- choice_idx = options.index(default)
140
- choice_key = default
178
+ if default_string is None:
179
+ print(f"Default option not available!")
180
+ return display_options(msg=msg, options=options, header=header, tail=tail, prompt=prompt, default=default, fzf=fzf, multi=multi, custom_input=custom_input)
181
+ choice_idx = options_strings.index(default_string)
182
+ assert default is not None, f"🧨 Default option not available!"
183
+ choice_one: T = default
141
184
  else:
142
185
  try:
143
- choice_idx = int(choice_string)
144
- choice_key = options[choice_idx]
186
+ choice_idx = int(choice_string, base=10)
187
+ choice_one = list(options)[choice_idx]
145
188
  except IndexError as ie: # i.e. converting to integer was successful but indexing failed.
146
- if choice_string in options: # string input
147
- choice_idx = options.index(choice_key) # type: ignore #TODO: fix this
148
- choice_key = options[choice_idx]
189
+ if choice_string in options_strings: # string input
190
+ choice_idx = options_strings.index(choice_one) # type: ignore #TODO: fix this
191
+ choice_one = list(options)[choice_idx]
149
192
  elif custom_input: return str(choice_string) # type: ignore #TODO: fix this
150
193
  else: raise ValueError(f"Unknown choice. {choice_string}") from ie
151
194
  except TypeError as te: # int(choice_string) failed due to # either the number is invalid, or the input is custom.
152
- if choice_string in options: # string input
153
- choice_idx = options.index(choice_key) # type: ignore #TODO: fix this
154
- choice_key = options[choice_idx]
195
+ if choice_string in options_strings: # string input
196
+ choice_idx = options_strings.index(choice_one) # type: ignore #TODO: fix this
197
+ choice_one = list(options)[choice_idx]
155
198
  elif custom_input: return str(choice_string) # type: ignore #TODO: fix this
156
199
  else: raise ValueError(f"Unknown choice. {choice_string}") from te
157
- print(f"{choice_idx}: {choice_key}", f"<<<<-------- CHOICE MADE")
158
- if multi: choice_key = [choice_key]
159
- return choice_key
200
+ print(f"{choice_idx}: {choice_one}", f"<<<<-------- CHOICE MADE")
201
+ if multi: return [choice_one]
202
+ return choice_one
160
203
 
161
204
 
162
205
  def symlink(this: P, to_this: P, prioritize_to_this: bool = True):
@@ -244,30 +287,39 @@ def print_code(code: str, lexer: str, desc: str = ""):
244
287
  console.print(Panel(Syntax(code=code, lexer=lexer), title=desc), style="bold red")
245
288
 
246
289
 
247
- def get_latest_version(url: str) -> None:
248
- # not yet used, consider, using it.
249
- import requests
250
- import json
251
- url = f"https://api.github.com/repos/{url.split('github.com/')[1]}/releases/latest"
252
- # Replace {owner} and {repo} with the actual owner and repository name
253
- response = requests.get(url, timeout=10)
254
- if response.status_code == 200:
255
- data = json.loads(response.text)
256
- latest_version = data["tag_name"]
257
- print("Latest release version:", latest_version)
258
- else: print("Error:", response.status_code)
290
+ # def get_latest_version(url: str) -> None:
291
+ # # not yet used, consider, using it.
292
+ # import requests
293
+ # import json
294
+ # url = f"https://api.github.com/repos/{url.split('github.com/')[1]}/releases/latest"
295
+ # # Replace {owner} and {repo} with the actual owner and repository name
296
+ # response = requests.get(url, timeout=10)
297
+ # if response.status_code == 200:
298
+ # data = json.loads(response.text)
299
+ # latest_version = data["tag_name"]
300
+ # print("Latest release version:", latest_version)
301
+ # else: print("Error:", response.status_code)
259
302
 
260
303
 
261
- def check_tool_exists(tool_name: str) -> bool:
262
- if platform.system() == "Windows": tool_name = tool_name.replace(".exe", "") + ".exe"
304
+ def check_tool_exists(tool_name: str, install_script: Optional[str] = None) -> bool:
305
+ """This is the CLI equivalent of `install_n_import` function of crocodile. """
306
+ if platform.system() == "Windows":
307
+ tool_name = tool_name.replace(".exe", "") + ".exe"
308
+
263
309
  if platform.system() == "Windows": cmd = "where.exe"
264
310
  elif platform.system() == "Linux": cmd = "which"
265
311
  else: raise NotImplementedError(f"platform {platform.system()} not implemented")
266
- import subprocess
312
+
267
313
  try:
268
- subprocess.check_output([cmd, tool_name])
269
- return True
270
- except (subprocess.CalledProcessError, FileNotFoundError): return False
314
+ _tmp = subprocess.check_output([cmd, tool_name])
315
+ res: bool = True
316
+ except (subprocess.CalledProcessError, FileNotFoundError):
317
+ res = False
318
+ if res is False and install_script is not None:
319
+ print(f"Installing {tool_name} ...")
320
+ Terminal().run(install_script, shell="powershell").print()
321
+ return check_tool_exists(tool_name=tool_name, install_script=None)
322
+ return res
271
323
 
272
324
 
273
325
  def get_ssh_hosts() -> list[str]:
@@ -285,8 +337,7 @@ def check_dotfiles_version_is_beyond(commit_dtm: str, update: bool = False):
285
337
  repo = Repo(path=dotfiles_path)
286
338
  last_commit = repo.head.commit
287
339
  dtm = last_commit.committed_datetime
288
- # make it tz unaware
289
- from datetime import datetime
340
+ from datetime import datetime # make it tz unaware
290
341
  dtm = datetime(dtm.year, dtm.month, dtm.day, dtm.hour, dtm.minute, dtm.second)
291
342
  res = dtm > datetime.fromisoformat(commit_dtm)
292
343
  if res is False and update is True:
machineconfig/utils/ve.py CHANGED
@@ -5,9 +5,23 @@
5
5
  from crocodile.file_management import P, Struct, modify_text, List
6
6
  from machineconfig.utils.utils import LIBRARY_ROOT
7
7
  import platform
8
+ from dataclasses import dataclass
8
9
  from typing import Optional, Literal
9
10
 
10
11
 
12
+ @dataclass
13
+ class VE_Specs:
14
+ ve_name: str
15
+ py_version: str
16
+ ipy_profile: str
17
+ os: str
18
+
19
+
20
+ @dataclass
21
+ class VE_INI:
22
+ specs: VE_Specs
23
+
24
+
11
25
  def get_ipython_profile(init_path: P):
12
26
  a_path = init_path
13
27
  ipy_profile: str = "default"
@@ -48,11 +62,10 @@ def get_installed_interpreters() -> list[P]:
48
62
  system = platform.system()
49
63
  if system == "Windows":
50
64
  tmp: list[P] = P.get_env().PATH.search("python.exe").reduce().list[1:]
51
- List(tmp).print()
52
65
  else:
53
66
  tmp = list(set(List(P.get_env().PATH.search("python3*").reduce()).filter(lambda x: not x.is_symlink() and "-" not in x))) # type: ignore
54
- List(tmp).print()
55
- return [P(x) for x in tmp]
67
+ List(tmp).print()
68
+ return list(set([P(x) for x in tmp]))
56
69
 
57
70
 
58
71
  def get_ve_specs(ve_path: P) -> dict[str, str]:
@@ -67,7 +80,7 @@ def get_ve_specs(ve_path: P) -> dict[str, str]:
67
80
 
68
81
  def get_ve_install_script(ve_name: Optional[str] = None, py_version: Optional[str] = None, install_crocodile_and_machineconfig: Optional[bool] = None,
69
82
  delete_if_exists: bool = True,
70
- system: Optional[Literal["Windows", "Linux"]] = None):
83
+ system: Optional[Literal["Windows", "Linux"]] = None) -> str:
71
84
  from rich.console import Console
72
85
  if system is None:
73
86
  system_: str = platform.system()
@@ -114,26 +127,96 @@ def get_ve_install_script(ve_name: Optional[str] = None, py_version: Optional[st
114
127
  text = LIBRARY_ROOT.joinpath(f"setup_{system_.lower()}/repos.{'ps1' if system_ == 'Windows' else 'sh'}").read_text()
115
128
  text = modify_text(txt_raw=text, txt_search="ve_name=", txt_alt=f"{variable_prefix}ve_name='{ve_name}'", replace_line=True)
116
129
  scripts += text
130
+
131
+ # ve_ini_specs = VE_Specs(ve_name=ve_name, py_version=dotted_py_version, ipy_profile="default", os=system_)
132
+ # ve_ini = VE_INI(specs=ve_ini_specs)
117
133
  return scripts
118
134
 
119
135
 
120
- def get_ps1_install_template(ve_name: str, req_root: str, py_version: str):
136
+ def get_ve_install_script_from_specs(repo_root: str, system: Literal["Windows", "Linux"]):
137
+ from crocodile.file_management import Read, Save
138
+ ini_file = P(repo_root).joinpath(".ve.ini")
139
+ assert ini_file.exists(), f"File {ini_file} does not exist."
140
+ ini = Read.ini(ini_file)
141
+ ve_name = ini["specs"]["ve_name"]
142
+ py_version = ini["specs"]["py_version"]
143
+ ipy_profile = ini["specs"]["ipy_profile"]
144
+
145
+ # repo_root = ini_file.with_name("requirements.txt").parent
146
+
147
+ # for backward compatibility:
148
+ ini_file.with_name(".ve_path").write_text(f"~/venvs/{ve_name}")
149
+ ini_file.with_name(".ipy_profile").write_text(ipy_profile)
150
+
151
+ # vscode:
152
+ if not system == "Windows": # symlinks on windows require admin rights.
153
+ P(repo_root).joinpath(".venv").symlink_to(P.home().joinpath("venvs", ve_name))
154
+
155
+ vscode_settings = P(repo_root).joinpath(".vscode/settings.json")
156
+ if vscode_settings.exists():
157
+ settings = Read.json(vscode_settings)
158
+ else:
159
+ settings = {}
160
+ if system == "Windows":
161
+ settings["python.defaultInterpreterPath"] = f"~/venvs/{ve_name}/Scripts/python.exe"
162
+ elif system == "Linux":
163
+ settings["python.defaultInterpreterPath"] = f"~/venvs/{ve_name}/bin/python"
164
+ pass
165
+ else:
166
+ raise NotImplementedError(f"System {system} not supported.")
167
+ Save.json(obj=settings, path=vscode_settings, indent=4)
168
+
169
+ base_path = P(repo_root).joinpath("versions", "init").create()
170
+ if system == "Windows":
171
+ script = get_ps1_install_template(ve_name=ve_name, py_version=py_version)
172
+ base_path.joinpath("install_ve.ps1").write_text(script)
173
+ elif system == "Linux":
174
+ script = get_bash_install_template(ve_name=ve_name, py_version=py_version)
175
+ base_path.joinpath("install_ve.sh").write_text(script)
176
+ else:
177
+ raise NotImplementedError(f"System {system} not supported.")
178
+
179
+ base_path.joinpath("install_requirements.ps1").write_text(get_install_requirements_template(repo_root=P(repo_root)))
180
+ base_path.joinpath("install_requirements.sh").write_text(get_install_requirements_template(repo_root=P(repo_root)))
181
+
182
+ return script
183
+
184
+
185
+ def get_ps1_install_template(ve_name: str, py_version: str):
121
186
  template = f"""
122
187
  $ve_name = '{ve_name}'
123
188
  $py_version = '{py_version}' # type: ignore
124
- (Invoke-WebRequest bit.ly/cfgvewindows).Content | Invoke-Expression
189
+ (Invoke-WebRequest https://bit.ly/cfgvewindows).Content | Invoke-Expression
125
190
  . $HOME/scripts/activate_ve $ve_name
126
- cd {req_root}
127
- pip install -r requirements_{platform.system().lower()}.txt
128
191
  """
129
192
  return template
130
- def get_bash_install_template(ve_name: str, req_root: str, py_version: str = "3.11"):
193
+ def get_bash_install_template(ve_name: str, py_version: str):
131
194
  template = f"""
132
195
  export ve_name='{ve_name}'
133
196
  export py_version='{py_version}' # type: ignore
134
- curl -L bit.ly/cfgvelinux | bash
135
- . activate_ve $ve_name
136
- cd {req_root}
137
- pip install -r requirements_{platform.system().lower()}.txt
197
+ curl -L https://bit.ly/cfgvelinux | bash
198
+ . $HOME/scripts/activate_ve $ve_name
138
199
  """
139
200
  return template
201
+
202
+
203
+ def get_install_requirements_template(repo_root: P):
204
+ return f"""
205
+ # This is a template that is meant to be modified manually to install requirements.txt and editable packages.
206
+ # one can dispense with this and install libraries manually and on adhoc-basis and then use version_checkout utility.
207
+ cd $HOME/{repo_root.as_posix()}
208
+ . $HOME/scripts/activate_ve
209
+ pip install -r requirements.txt
210
+ pip install -e .
211
+
212
+ # cd ~/code; git clone https://github.com/thisismygitrepo/crocodile.git --origin origin
213
+ # cd ~/code/crocodile; git remote set-url origin https://github.com/thisismygitrepo/crocodile.git
214
+ # cd ~/code/crocodile; git remote add origin https://github.com/thisismygitrepo/crocodile.git
215
+ # cd ~/code/crocodile; pip install -e .
216
+
217
+ # cd ~/code; git clone https://github.com/thisismygitrepo/machineconfig --origin origin
218
+ # cd ~/code/machineconfig; git remote set-url origin https://github.com/thisismygitrepo/machineconfig
219
+ # cd ~/code/machineconfig; git remote add origin https://github.com/thisismygitrepo/machineconfig
220
+ # cd ~/code/machineconfig; pip install -e .
221
+
222
+ """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: machineconfig
3
- Version: 1.7
3
+ Version: 1.8
4
4
  Summary: Dotfiles management package
5
5
  Home-page: https://github.com/thisismygitrepo/machineconfig
6
6
  Author: Alex Al-Saffar
@@ -60,7 +60,7 @@ Invoke-WebRequest https://raw.githubusercontent.com/thisismygitrepo/machineconfi
60
60
  Invoke-WebRequest https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_windows/ve.ps1 | Invoke-Expression
61
61
  # dev repos # short `(iwr bit.ly/cfgreposwindows).Content | iex` OR `curl bit.ly/cfgreposwindows -L | iex`
62
62
  Invoke-WebRequest https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_windows/repos.ps1 | Invoke-Expression
63
- # symlinks: locally, run: `ftpsx username@hostname[:port] ~/dotfiles -z`, then, on the remote:
63
+ # symlinks # short `curl bit.ly/cfgsymlinkswindows -L | iex` OR `(iwr bit.ly/cfgsymlinkswindows).Content | iex`
64
64
  . ~/code/machineconfig/src/machineconfig/setup_windows/symlinks.ps1
65
65
  # devapps:
66
66
  ~/code/machineconfig/src/machineconfig/setup_windows/devapps.ps1
@@ -96,21 +96,21 @@ short: `curl bit.ly/cfgcroshellwindows -L | iex` OR `(iwr bit.ly/cfgcroshellwind
96
96
  # Linux Setup
97
97
  With `sudo` access, run the following: (short `curl bit.ly/cfgalllinux -L | bash`)
98
98
  ```bash
99
- # export package_manager="apt"
100
- # export package_manager="nix"
99
+ export package_manager="apt"
100
+ export package_manager="nix"
101
101
 
102
102
  # apps # short: `curl bit.ly/cfgappslinux -L | bash`
103
103
  curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/apps.sh | bash
104
104
  # Optionally: curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/apps_dev.sh | bash
105
+
105
106
  # virtual enviornment # short `curl bit.ly/cfgvelinux -L | bash`
106
107
  curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/ve.sh | bash
108
+
107
109
  # repos # short `curl bit.ly/cfgreposlinux -L | bash`
108
110
  curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/repos.sh | bash
109
- # symlinks and bash profile.
110
-
111
- # locally, run: `ftpsx username@hostname[:port] ~/dotfiles -z`
112
- # for wsl: wsl_server.ps1; ftpsx $env:USERNAME@localhost:2222 ~/dotfiles -z # OR: ln -s /mnt/c/Users/$(whoami)/dotfiles ~/dotfiles
111
+ # symlinks and bash profile: # short `curl bit.ly/cfgsymlinkslinux -L | bash`
113
112
  source ~/code/machineconfig/src/machineconfig/setup_linux/symlinks.sh # requires sudo since it invloves chmod of dotfiles/.ssh, however sudo doesn't work with source. best to have sudo -s earlier.
113
+
114
114
  # devapps
115
115
  source <(sudo cat ~/code/machineconfig/src/machineconfig/setup_linux/devapps.sh)
116
116
  ```
@@ -0,0 +1,70 @@
1
+ machineconfig/__init__.py,sha256=bsBSmmsUO8rqdzHk2wibjueFpDc0Q97faQnM6vKUNOU,79
2
+ machineconfig/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ machineconfig/jobs/python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ machineconfig/jobs/python/check_installations.py,sha256=CKAfdl7-KafGMSGcSTMs-CpmB4zEP7KKNNnp-nWKI6M,7767
5
+ machineconfig/jobs/python/checkout_version.py,sha256=nrjpz6mK8T7XS1VArFi7slnKKPNlZw0zMr6V2_JeNic,5042
6
+ machineconfig/jobs/python/create_bootable_media.py,sha256=De1_DUXt5oE7PvNY5P9oIdqxD51qZLJjOfB-XMayVKg,585
7
+ machineconfig/jobs/python/create_zellij_template.py,sha256=tIGieeq2n21B_dpgkXiR_Zh2q4xUPG3QhqCwLKCkhog,1301
8
+ machineconfig/jobs/python/python_cargo_build_share.py,sha256=I-xhOKB4Sw0aaPnfk9Ip5Nmu2TOZITsZ_okGrd8deiM,1746
9
+ machineconfig/jobs/python/python_ve_symlink.py,sha256=ZdXuTfEBkO1uYc6F-xg_bWF46ScQ9Xaj3b2dDqO1BL4,837
10
+ machineconfig/jobs/python/tasks.py,sha256=1px4SuPYbcmCTGARxUaKvTx4Hza3yurVWEOqNevbaaM,119
11
+ machineconfig/jobs/python_generic_installers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ machineconfig/jobs/python_linux_installers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ machineconfig/jobs/python_linux_installers/dev/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ machineconfig/jobs/python_windows_installers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ machineconfig/jobs/python_windows_installers/archive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ machineconfig/jobs/python_windows_installers/dev/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ machineconfig/jobs/script_installer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ machineconfig/jobs/script_installer/azure_data_studio.py,sha256=iDPiKbEmkjnV_aPVvrnbSVMPw4USTAV1yoT2KuyUgRU,654
19
+ machineconfig/jobs/script_installer/bypass_paywall.py,sha256=c2_4UD2hIgs2v3gt_tWz7m5861Vsbt99KDk7kbIQdIY,592
20
+ machineconfig/jobs/script_installer/code.py,sha256=F9BPw6ErslGttrJ9M6EDIaF6TXchw8XmHUHAXUIa-mQ,1055
21
+ machineconfig/jobs/script_installer/docker_desktop.py,sha256=oPiUUEI5VXhHvnx8xD0IEtpWGg8g3ZoX0PQcYn8Ssk0,1431
22
+ machineconfig/jobs/script_installer/ngrok.py,sha256=r9w7VcErKOTLxpbxRIpjMkOjmJ1vJE03-Mf8P8kh2-c,726
23
+ machineconfig/jobs/script_installer/skim.py,sha256=O2EE5eT-W7cKiohfOrKj7OM7-3nVVJnjb1ifdWA2H9M,494
24
+ machineconfig/jobs/script_installer/wezterm.py,sha256=OcNYPUc2Dx9QCz-im0ryqPEdEAStgB-J0MSKq9n4c1U,950
25
+ machineconfig/profile/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ machineconfig/profile/create.py,sha256=9QJGkyHDIG6ArA8RMqiZJrD79eZ0HXOy4qAfd269lV8,4962
27
+ machineconfig/profile/shell.py,sha256=oo40fnLvxcS2K6wvjN4ITVefhkvIW_VbP8Tua_9mqm0,6129
28
+ machineconfig/scripts/__init__.py,sha256=8aZPVoch_gcI0Ihcr30zQcPjRQMWiWzDnQXnOm7spzo,73
29
+ machineconfig/scripts/python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ machineconfig/scripts/python/cloud_copy.py,sha256=fWy2D-oJpguj_VPIHRa-A6RNV2YiD10tk51FTvoJIMg,4619
31
+ machineconfig/scripts/python/cloud_manager.py,sha256=qfmO63t1LQxO6QHhz3qxePQnas4RsNOjLV1cGK8xK8I,1639
32
+ machineconfig/scripts/python/cloud_mount.py,sha256=DsOV_Pt6B_9IwCyf2W6qHlxx41W0f_WqDKcUCWQJPmo,4634
33
+ machineconfig/scripts/python/cloud_repo_sync.py,sha256=yZLqOSrCYLNV3mZaLl0wZSu1nE8z5BtAu6OU9Iwtx-8,7805
34
+ machineconfig/scripts/python/cloud_sync.py,sha256=oMaemB0DruVPQyHey-C0KvqJQY9ZPxOgTQAq09-7G9M,11240
35
+ machineconfig/scripts/python/croshell.py,sha256=Gk4jKJCAsZkCUceKdZdnIRsDbJl74z2xfQwB9dY3ODw,6073
36
+ machineconfig/scripts/python/devops.py,sha256=imvtmo1PRcP-SlGgPK_Eeghd-ZtHWwV30vx6zyG8lps,5363
37
+ machineconfig/scripts/python/devops_add_identity.py,sha256=q0DjXowg0dr5nDVrMdyViF_OQdeTN_fDXTVcVPgddfk,1549
38
+ machineconfig/scripts/python/devops_add_ssh_key.py,sha256=RoHO_lP1DuyKrPl_wYfAJuliRP7CVKssygy3cK2eJXo,3308
39
+ machineconfig/scripts/python/devops_backup_retrieve.py,sha256=sH3a5Uvz5SDhiypP_KIJR1-RiZT-IU8IOJjpvC1UeGk,2443
40
+ machineconfig/scripts/python/devops_devapps_install.py,sha256=64XFl6A1UyDFdUSvy-12wH4DxRAtMZ1MLlwnCR3Vaok,5220
41
+ machineconfig/scripts/python/devops_update_repos.py,sha256=ZW_jI1oNlus929Y2ErXhDWDr6A4SSbTxrutn-__AdI4,2809
42
+ machineconfig/scripts/python/dotfile.py,sha256=1zPwDgCjwsAFNBJ6h9qCTqpPPDpZzjdDkq6rFVlhvdo,1564
43
+ machineconfig/scripts/python/fire_jobs.py,sha256=42ynJDoRPaGKLAC2hpbuWAcjHIIRtBQalRe3N7w5TrU,17217
44
+ machineconfig/scripts/python/ftpx.py,sha256=_PDH8QghwTkeNsPXuKXXdRWyEvvSpUW41hMsiui2x_E,4141
45
+ machineconfig/scripts/python/mount_nfs.py,sha256=MLEZ2IjXPLuWqOwzzWhiV8nxcULS32JHzNnrwulmp4I,2485
46
+ machineconfig/scripts/python/mount_nw_drive.py,sha256=2AwmOF1IHI_ET9BBjhgMQ9AGn8uj6zoCC7Rg8Iy0G1A,1005
47
+ machineconfig/scripts/python/mount_ssh.py,sha256=R557UOF3uChH2Mf_eWgSu7GVyzcfNPSaFudn42n51oM,1406
48
+ machineconfig/scripts/python/onetimeshare.py,sha256=tveeuE_PmRuk7hwJy5c53b2eL0lvxR_MACX5X_4syy8,1881
49
+ machineconfig/scripts/python/pomodoro.py,sha256=-ag26tR7dre1Zw4xfKkPERDRvn7xSJkWfBpem8VjJzE,1974
50
+ machineconfig/scripts/python/repos.py,sha256=0dxJcQm8lzxzxn3aArT_UzwEHFtsjDWOP0LGcvaB3oM,10253
51
+ machineconfig/scripts/python/scheduler.py,sha256=PN-_GzkcMCAIdxWj_gQQIFR5OKs8pa3aeXn7Bn4YnEM,2305
52
+ machineconfig/scripts/python/snapshot.py,sha256=XxnGc8bOb7vgx-TpJVBzgkzQf9Fcz6VyQ3LH7sOsLDI,622
53
+ machineconfig/scripts/python/start_slidev.py,sha256=mhcXz6LcogTPU1CEGPRzFj8yC_w6ey1k-FeNEfOEiqk,4359
54
+ machineconfig/scripts/python/start_terminals.py,sha256=VwAbhZ4LxHhuWvmWaRxWh2HvlPK02kHG0-W7QekubVY,5441
55
+ machineconfig/scripts/python/wifi_conn.py,sha256=XABEqc_TNdKa-I3J2DmDgEtT5Xt95fcqjNJ9W9MsEPA,2916
56
+ machineconfig/scripts/python/wsl_windows_transfer.py,sha256=YDmN3bjz-auWktIlhkj4pEFykysXtMnpjZobhXJ69d4,2198
57
+ machineconfig/setup_windows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
+ machineconfig/setup_windows/wt_and_pwsh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
+ machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py,sha256=bwOvQ8Lcmxy8Mds3pPR7itZA_8FUMOD5RzGZgrnzDlM,1611
60
+ machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py,sha256=WgJ9JkrjOZZW8JPw5wdkEIlE7Z4VDkDOXuag1qsqLlo,6242
61
+ machineconfig/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
+ machineconfig/utils/installer.py,sha256=uvXk3w1tjTBBnsoFzWHwv2Z38FLaafEjGB7rOL8pLIs,14393
63
+ machineconfig/utils/procs.py,sha256=GCdvGvowFm-GZe6PLcRe7yaWiBr6QFnSc_lAVWQDKo8,5146
64
+ machineconfig/utils/scheduling.py,sha256=PGSmJPjDN5ZP5pLzzV4aXCRaB71OlMSiEljRkzMWSX8,7341
65
+ machineconfig/utils/utils.py,sha256=izwiIvw_eLtbxvX7zhK7YZkrE6Xd8nw3u1O-r23AZ10,18780
66
+ machineconfig/utils/ve.py,sha256=rtweDN9Xs9xh8a0QNsKIhH6eZmC0H-RBLrIN_f68l6s,9113
67
+ machineconfig-1.8.dist-info/METADATA,sha256=ECcBQ2_UcFmk_ClfRF7vk9tq0uDYV77RAW-x1yCEw_o,6256
68
+ machineconfig-1.8.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
69
+ machineconfig-1.8.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
70
+ machineconfig-1.8.dist-info/RECORD,,
@@ -1,18 +0,0 @@
1
- from machineconfig.utils.installer import get_latest_release
2
- from platform import system
3
- # import crocodile.toolbox as tb
4
- from typing import Optional
5
-
6
-
7
- url = r"https://github.com/gopasspw/gopass"
8
- __doc__ = """cli password manager"""
9
-
10
-
11
- def main(version: Optional[str] = None) -> None:
12
- if system() == "Windows": get_latest_release(url, exe_name="gopass", suffix="windows-amd64", download_n_extract=True, strip_v=True, tool_name="gopass", delete=False, version=version)
13
- elif system() == "Linux": get_latest_release(url, exe_name="gopass", suffix="linux-amd64", download_n_extract=True, compression="tar.gz", strip_v=True, tool_name="gopass", delete=False, version=version)
14
- else: raise NotImplementedError(f"System {system()} is not supported")
15
-
16
-
17
- if __name__ == '__main__':
18
- main()
@@ -1,20 +0,0 @@
1
-
2
- """nvim
3
- """
4
-
5
- from machineconfig.utils.installer import get_latest_release
6
- from platform import system
7
- import crocodile.toolbox as tb
8
-
9
- repo_url = tb.P(r"https://github.com/neovim/neovim")
10
- release = get_latest_release(repo_url.as_url_str(), exe_name="nvim", download_n_extract=False)
11
-
12
- if isinstance(release, tb.P):
13
- if system() == 'Windows':
14
- release.joinpath("nvim-win64.msi").download()()
15
- else:
16
- release.joinpath("nvim-linux64.tar.gz").download().ungz_untar(inplace=True)
17
-
18
-
19
- if __name__ == '__main__':
20
- pass
@@ -1,25 +0,0 @@
1
-
2
- # from machineconfig.utils.utils import write_shell_script
3
- # import crocodile.toolbox as tb
4
- from typing import Optional
5
-
6
- __doc__ = """OpenCommit is a tool for writing better commit messages using GPT-3"""
7
- repo_url = "https://github.com/di-sukharev/opencommit"
8
-
9
-
10
- def main(version: Optional[str] = None):
11
- _ = version
12
- # token = input("Enter your OpenAI API key: ")
13
- token = 1
14
- program = f"""
15
- # as per: {repo_url}
16
- npm install -g opencommit
17
- cd ~
18
- # echo "OPENAI_API_KEY={token}" > .opencommit
19
- """
20
- # tb.Terminal().run(program, shell="powershell").print()
21
- return program
22
-
23
-
24
- if __name__ == '__main__':
25
- pass
@@ -1,33 +0,0 @@
1
-
2
- """
3
- The executable of this program is suspicious according to virustotal.
4
- """
5
-
6
- from machineconfig.utils.installer import find_move_delete_linux, get_latest_release
7
- import crocodile.toolbox as tb
8
- from platform import system
9
-
10
-
11
- url = r'https://github.com/uw-labs/strongbox'
12
-
13
-
14
- def main():
15
- d_url = get_latest_release(url, exe_name="strongbox")
16
- if isinstance(d_url, tb.P):
17
- v = d_url.name.replace("v", "")
18
- if system() == 'Linux':
19
- f = d_url.joinpath(f"strongbox_{v}_linux_amd64").download().with_name("strongbox", inplace=True)
20
- find_move_delete_linux(f, 'tldr', delete=True)
21
- tb.Terminal().run("tldr --update")
22
-
23
- elif system() == 'Windows':
24
- f = d_url.joinpath(f"strongbox_{v}_windows_amd64.exe").download().with_name("strongbox.exe", inplace=True)
25
- f.move(folder=f.get_env().WindowsApps, overwrite=True)
26
-
27
- else:
28
- raise NotImplementedError(f"System {system()} not supported")
29
- tb.Terminal().run("strongbox -git-config", shell="powershell").print()
30
-
31
-
32
- if __name__ == '__main__':
33
- main()
@@ -1,14 +0,0 @@
1
-
2
- # import crocodile.toolbox as tb
3
- from typing import Optional
4
-
5
-
6
- __doc__ = """CLI displaying current network utilization by process"""
7
-
8
- def main(version: Optional[str] = None):
9
- _ = version
10
- pass
11
-
12
-
13
- if __name__ == '__main__':
14
- main()