machineconfig 7.51__py3-none-any.whl → 7.52__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 (54) hide show
  1. machineconfig/jobs/installer/custom_dev/brave.py +1 -1
  2. machineconfig/jobs/installer/custom_dev/code.py +4 -1
  3. machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +0 -9
  4. machineconfig/jobs/installer/custom_dev/sysabc.py +140 -0
  5. machineconfig/jobs/installer/custom_dev/wezterm.py +2 -15
  6. machineconfig/jobs/installer/installer_data.json +689 -9
  7. machineconfig/jobs/installer/linux_scripts/redis.sh +1 -0
  8. machineconfig/jobs/installer/package_groups.py +23 -72
  9. machineconfig/logger.py +0 -1
  10. machineconfig/profile/create_links_export.py +2 -2
  11. machineconfig/profile/mapper.toml +1 -4
  12. machineconfig/scripts/python/croshell.py +20 -43
  13. machineconfig/scripts/python/devops.py +1 -1
  14. machineconfig/scripts/python/env_manager/path_manager_tui.py +1 -1
  15. machineconfig/scripts/python/fire_jobs.py +52 -39
  16. machineconfig/scripts/python/helpers_croshell/crosh.py +1 -1
  17. machineconfig/scripts/python/helpers_devops/cli_config.py +3 -19
  18. machineconfig/scripts/python/helpers_devops/cli_self.py +12 -6
  19. machineconfig/scripts/python/helpers_devops/cli_utils.py +1 -80
  20. machineconfig/scripts/python/helpers_fire_command/file_wrangler.py +0 -17
  21. machineconfig/scripts/python/helpers_msearch/scripts_linux/fzfg +1 -1
  22. machineconfig/scripts/python/helpers_repos/clone.py +0 -1
  23. machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +1 -1
  24. machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +1 -1
  25. machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +2 -2
  26. machineconfig/scripts/python/helpers_utils/path.py +106 -0
  27. machineconfig/scripts/python/interactive.py +9 -15
  28. machineconfig/scripts/python/sessions.py +2 -2
  29. machineconfig/scripts/python/utils.py +7 -3
  30. machineconfig/scripts/windows/mounts/mount_ssh.ps1 +1 -1
  31. machineconfig/setup_linux/__init__.py +0 -1
  32. machineconfig/setup_linux/web_shortcuts/interactive.sh +11 -10
  33. machineconfig/setup_mac/__init__.py +2 -3
  34. machineconfig/setup_windows/__init__.py +0 -3
  35. machineconfig/setup_windows/web_shortcuts/interactive.ps1 +11 -10
  36. machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +15 -0
  37. machineconfig/utils/installer.py +11 -27
  38. machineconfig/utils/installer_utils/installer.py +9 -50
  39. machineconfig/utils/installer_utils/installer_abc.py +0 -68
  40. machineconfig/utils/io.py +0 -1
  41. machineconfig/utils/path_helper.py +57 -6
  42. machineconfig/utils/ssh.py +3 -3
  43. {machineconfig-7.51.dist-info → machineconfig-7.52.dist-info}/METADATA +5 -3
  44. {machineconfig-7.51.dist-info → machineconfig-7.52.dist-info}/RECORD +49 -51
  45. machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -71
  46. machineconfig/jobs/installer/powershell_scripts/archive_pygraphviz.ps1 +0 -12
  47. machineconfig/setup_linux/apps.sh +0 -66
  48. machineconfig/setup_mac/apps.sh +0 -73
  49. machineconfig/setup_windows/apps.ps1 +0 -62
  50. /machineconfig/{jobs/installer/powershell_scripts → setup_windows/ssh}/openssh-server_add_key.ps1 +0 -0
  51. /machineconfig/{jobs/installer/powershell_scripts → setup_windows/ssh}/openssh-server_copy-ssh-id.ps1 +0 -0
  52. {machineconfig-7.51.dist-info → machineconfig-7.52.dist-info}/WHEEL +0 -0
  53. {machineconfig-7.51.dist-info → machineconfig-7.52.dist-info}/entry_points.txt +0 -0
  54. {machineconfig-7.51.dist-info → machineconfig-7.52.dist-info}/top_level.txt +0 -0
@@ -45,6 +45,7 @@ sudo nala update
45
45
  # Install Redis
46
46
  echo "📥 Installing Redis..."
47
47
  sudo nala install redis -y
48
+ sudo nala install redis-tools -y
48
49
 
49
50
  echo """✅ INSTALLATION COMPLETE | Redis has been installed successfully
50
51
 
@@ -1,4 +1,3 @@
1
- from typing import Literal, TypeAlias, Union
2
1
 
3
2
  # AI/LLM Tools - AI-powered coding and chat assistants
4
3
  AGENTS = [
@@ -55,9 +54,12 @@ PACKAGES_CODE_EDITORS = [
55
54
  # Database Tools - Database clients and visualizers
56
55
  PACKAGES_DATABASE = [
57
56
  "SqliteBrowser",
57
+ "sqlite3",
58
+ "redis-cli",
59
+ "postgresql-client",
60
+ "duckdb",
58
61
  "DBeaver",
59
62
  "rainfrog",
60
- "duckdb",
61
63
  ]
62
64
 
63
65
 
@@ -151,7 +153,6 @@ PACKAGES_MISC_DEV = [
151
153
  "obsidian",
152
154
  "istio",
153
155
  "cointop",
154
- "nnn",
155
156
  ]
156
157
 
157
158
 
@@ -190,6 +191,7 @@ PACKAGES_FILE = [
190
191
  # "xplr",
191
192
  # "joshuto",
192
193
  # "lf",
194
+ # "nnn",
193
195
  "yazi",
194
196
  "tere",
195
197
  # "exa",
@@ -216,74 +218,23 @@ PACKAGES_TERMINAL_SHELL = [
216
218
 
217
219
 
218
220
 
219
-
220
-
221
- PACKAGE_GROUPS: TypeAlias = Literal[
222
- "ESSENTIAL",
223
- "DEV",
224
- "AGENTS",
225
- "TUNNELING",
226
- "TERMINAL_EMULATORS",
227
- "BROWSERS",
228
- "CODE_EDITORS",
229
- "PRESENTATION",
230
- "DATABASE",
231
- "DOC_CONVERSION",
232
- "MEDIA",
233
- "FILE_SHARING",
234
- "GIT_DOCKER_TOOLS",
235
- "DEV_UTILS",
236
- "CODE_ANALYSIS",
237
- "PRODUCTIVITY",
238
- "MISC_DEV",
239
- "SYSTEM_MONITORS",
240
- "FILE_TOOLS",
241
- "FILE_VIEWERS",
242
- "SEARCH",
243
- "TERMINAL_SHELL",
244
- "CLOUD_UTILS",
245
- "WEB_TERMINAL",
246
- ]
247
-
248
-
249
-
250
- # Main ESSENTIAL package list - combines all subgroups
251
- ESSENTIAL = [
252
- *PACKAGES_CODE_ANALYSIS,
253
- *PACKAGES_SYSTEM_MONITORS,
254
- *PACKAGES_TERMINAL_SHELL,
255
- *PACKAGES_FILE,
256
- ]
257
- DEV = [
258
- *PACKAGES_TERMINAL_EMULATORS,
259
- *PACKAGES_BROWSERS,
260
- *PACKAGES_CODE_EDITORS,
261
- *PACKAGES_DATABASE,
262
- *PACKAGES_MEDIA,
263
- *PACKAGES_FILE_SHARING,
264
- *PACKAGES_DEV_UTILS,
265
- *PACKAGES_CODE_ANALYSIS,
266
- *PACKAGES_PRODUCTIVITY,
267
- *PACKAGES_MISC_DEV,
268
- ]
269
-
270
- PACKAGE_GROUP2NAMES: dict[PACKAGE_GROUPS, list[str]] = {
271
- "ESSENTIAL": ESSENTIAL,
272
- "DEV": DEV,
273
- "AGENTS": AGENTS,
274
- "TERMINAL_EMULATORS": PACKAGES_TERMINAL_EMULATORS,
275
- "BROWSERS": PACKAGES_BROWSERS,
276
- "CODE_EDITORS": PACKAGES_CODE_EDITORS,
277
- "DATABASE": PACKAGES_DATABASE,
278
- "MEDIA": PACKAGES_MEDIA,
279
- "FILE_SHARING": PACKAGES_FILE_SHARING,
280
- "DEV_UTILS": PACKAGES_DEV_UTILS,
281
- "CODE_ANALYSIS": PACKAGES_CODE_ANALYSIS,
282
- "PRODUCTIVITY": PACKAGES_PRODUCTIVITY,
283
- "MISC_DEV": PACKAGES_MISC_DEV,
284
- "SYSTEM_MONITORS": PACKAGES_SYSTEM_MONITORS,
285
- "SEARCH": PACKAGES_FILE,
286
- "TERMINAL_SHELL": PACKAGES_TERMINAL_SHELL,
221
+ PACKAGE_GROUP2NAMES: dict[str, list[str]] = {
222
+ "sysabc": ["sysabc"],
223
+ "termabc": [*PACKAGES_CODE_ANALYSIS, *PACKAGES_SYSTEM_MONITORS, *PACKAGES_TERMINAL_SHELL, *PACKAGES_FILE,],
224
+ "dev": [*PACKAGES_TERMINAL_EMULATORS, *PACKAGES_BROWSERS, *PACKAGES_CODE_EDITORS, *PACKAGES_DATABASE, *PACKAGES_MEDIA, *PACKAGES_FILE_SHARING, *PACKAGES_DEV_UTILS, *PACKAGES_CODE_ANALYSIS, *PACKAGES_PRODUCTIVITY, *PACKAGES_MISC_DEV,],
225
+ "dev-utils": PACKAGES_DEV_UTILS,
226
+ "dev-msc": PACKAGES_MISC_DEV,
227
+ "agents": AGENTS,
228
+ "terminal-emulator": PACKAGES_TERMINAL_EMULATORS,
229
+ "shell": PACKAGES_TERMINAL_SHELL,
230
+ "browsers": PACKAGES_BROWSERS,
231
+ "code-editors": PACKAGES_CODE_EDITORS,
232
+ "code-analysis": PACKAGES_CODE_ANALYSIS,
233
+ "db": PACKAGES_DATABASE,
234
+ "media": PACKAGES_MEDIA,
235
+ "file-sharing": PACKAGES_FILE_SHARING,
236
+ "productivity": PACKAGES_PRODUCTIVITY,
237
+ "sys-monitor": PACKAGES_SYSTEM_MONITORS,
238
+ "search": PACKAGES_FILE,
287
239
  }
288
240
 
289
- _ = Union, Literal
machineconfig/logger.py CHANGED
@@ -1,4 +1,3 @@
1
- from __future__ import annotations
2
1
 
3
2
  import logging
4
3
  import os
@@ -21,7 +21,7 @@ ON_CONFLICT_MAPPER: dict[str, ON_CONFLICT_STRICT] = {
21
21
 
22
22
  def main_public_from_parser(method: Annotated[Literal["symlink", "s", "copy", "c"], typer.Option(..., "--method", "-m", help="Method to use for setting up the config file.")],
23
23
  on_conflict: Annotated[ON_CONFLICT_LOOSE, typer.Option(..., "--on-conflict", "-o", help="Action to take on conflict")] = "throw-error",
24
- which: Annotated[Optional[str], typer.Option(..., "--which", "-w", help="Specific items to process (default: all)")] = None,
24
+ which: Annotated[Optional[str], typer.Option(..., "--which", "-w", help="Specific items to process")] = "all",
25
25
  interactive: Annotated[bool, typer.Option(..., "--interactive", "-i", help="Run in interactive mode")] = False):
26
26
  """Terminology:
27
27
  SOURCE = Self-Managed-Config-File-Path
@@ -59,7 +59,7 @@ def main_public_from_parser(method: Annotated[Literal["symlink", "s", "copy", "c
59
59
 
60
60
  def main_private_from_parser(method: Annotated[Literal["symlink", "s", "copy", "c"], typer.Option(..., help="Method to use for linking files")],
61
61
  on_conflict: Annotated[ON_CONFLICT_LOOSE, typer.Option(..., help="Action to take on conflict")] = "throw-error",
62
- which: Annotated[Optional[str], typer.Option(..., "--which", "-w", help="Specific items to process")] = None,
62
+ which: Annotated[Optional[str], typer.Option(..., "--which", "-w", help="Specific items to process")] = "all",
63
63
  interactive: Annotated[bool, typer.Option(..., "--interactive", "-i", help="Run in interactive mode")] = False):
64
64
  from machineconfig.profile.create_links import ConfigMapper, read_mapper
65
65
  mapper_full = read_mapper()["private"]
@@ -33,9 +33,6 @@ config2 = {this = '~/.cli-m365-all-connections.json', to_this = '~/dotfiles/cred
33
33
  config3 = {this = '~/.cli-m365-connection.json', to_this = '~/dotfiles/creds/tokens/.cli-m365-connection.json'}
34
34
  # config2 = {this = '~/.cli-m365-tokens.json', to_this = '~/dotfiles/creds/tokens/.cli-m365-tokens.json'}
35
35
 
36
- # [bash_linux]
37
- # bashrc = {this = '~/.inputrc', to_this = '~/dotfiles/shells/bash/.inputrc'}
38
-
39
36
  [remmina]
40
37
  data = {this = '~/.var/app/org.remmina.Remmina/data/remmina', to_this = '~/dotfiles/creds/RDP/remmina/data/remmina'}
41
38
 
@@ -166,7 +163,7 @@ config = {this = '~/.config/pudb/pudb.cfg', to_this = 'CONFIG_ROOT/settings/pudb
166
163
  # AllUsersCurrentHost = {this = 'C:\Windows\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1', to_this = '~/dotfiles/shells/powershell/AllUsersCurrentHost/Microsoft.PowerShell_profile.ps1'}
167
164
  # AllUsersAllHosts = {this = 'C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1', to_this = '~/dotfiles/shells/windows_powershell/AllUsersAllHosts/profile.ps1'}
168
165
 
169
- [pwsh_windows]
166
+ # [pwsh_windows]
170
167
  # CurrentUserCurrentHost = {this = '~/Documents/PowerShell/Microsoft.PowerShell_profile.ps1', to_this = 'CONFIG_ROOT/settings/shells/pwsh/init.ps1'}
171
168
  # CurrentUserAllHosts = {this = '~/Documents/PowerShell/profile.ps1', to_this = 'CONFIG_ROOT/settings/shells/pwsh/profile.ps1'}
172
169
  # AllUsersCurrentHost = {this = 'C:\Program Files\PowerShell\7\Microsoft.PowerShell_profile.ps1', to_this = 'CONFIG_ROOT/settings/shells/pwsh/init.ps1'}
@@ -2,30 +2,30 @@
2
2
 
3
3
  """
4
4
  croshell
5
+
5
6
  """
6
7
 
7
8
  from typing import Annotated, Optional
8
9
  import typer
9
10
 
10
11
 
11
-
12
12
  def croshell(
13
13
  path: Annotated[Optional[str], typer.Argument(help="path of file to read.")] = None,
14
14
  python: Annotated[bool, typer.Option("--python", "-p", help="flag to use python over IPython.")] = False,
15
15
  profile: Annotated[Optional[str], typer.Option("--profile", "-P", help="ipython profile to use, defaults to default profile.")] = None,
16
16
  jupyter: Annotated[bool, typer.Option("--jupyter", "-j", help="run in jupyter interactive console")] = False,
17
17
  vscode: Annotated[bool, typer.Option("--vscode", "-c", help="open the script in vscode")] = False,
18
- streamlit_viewer: Annotated[bool, typer.Option("--streamlit", "-s", help="view in streamlit app")] = False,
18
+ # streamlit_viewer: Annotated[bool, typer.Option("--streamlit", "-s", help="view in streamlit app")] = False,
19
19
  visidata: Annotated[bool, typer.Option("--visidata", "-v", help="open data file in visidata")] = False,
20
20
  marimo: Annotated[bool, typer.Option("--marimo", "-m", help="open the notebook using marimo if available")] = False,
21
21
  ) -> None:
22
- from machineconfig.scripts.python.helpers_croshell.crosh import code, get_read_data_pycode
22
+ from machineconfig.scripts.python.helpers_croshell.crosh import get_read_python_file_pycode, get_read_data_pycode
23
23
  from machineconfig.utils.meta import lambda_to_python_script
24
+ from machineconfig.utils.path_helper import get_choice_file
24
25
  from machineconfig.utils.path_extended import PathExtended
25
26
  from pathlib import Path
26
27
  from machineconfig.utils.accessories import randstr
27
28
  import json
28
- from machineconfig.utils.options import choose_from_options
29
29
  from rich.console import Console
30
30
  from rich.panel import Panel
31
31
  console = Console()
@@ -35,41 +35,18 @@ def croshell(
35
35
  interactivity = "-i"
36
36
  interpreter = "python" if python else "ipython"
37
37
  ipython_profile: Optional[str] = profile
38
- file_obj = PathExtended.cwd() # initialization value, could be modified according to args.
39
-
40
- if path == ".":
41
- text = "🔍 Searching for Python files..."
42
- console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
43
- options = [str(item) for item in PathExtended.cwd().search("*.py", r=True)]
44
- file_selected = choose_from_options(msg="Choose a python file to run", options=options, fzf=True, multi=False)
45
- assert isinstance(file_selected, str)
46
- program = PathExtended(file_selected).read_text(encoding="utf-8")
47
- text = f"📄 Selected file: {PathExtended(file_selected).name}"
48
- console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
49
-
50
- elif path != "" and path is not None:
51
- if streamlit_viewer:
52
- # text = "📊 STARTING STREAMLIT VIEWER"
53
- # console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
54
- # from machineconfig.scripts.python.viewer import run
55
- # py_file_path = run(data_path=args.read, data=None, get_figure=None)
56
- # final_program = f"""
57
- # #!/bin/bash
58
- # streamlit run {py_file_path}
59
- # """
60
- # PROGRAM_PATH.write_text(data=final_program, encoding="utf-8")
61
- print("Streamlit viewer is not yet implemented in this version.")
62
- return None
63
- file_obj = PathExtended(str(path).lstrip()).expanduser().absolute()
64
- program = lambda_to_python_script(lambda: get_read_data_pycode(path=str(file_obj)), in_global=True, import_module=False)
65
- text = f"📄 Reading data from: {file_obj.name}"
66
- console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
38
+ file_obj = Path.cwd() # initialization value, could be modified according to args.
39
+ if path is not None:
40
+ choice_file = get_choice_file(path=path, suffixes={".*"})
41
+ if choice_file.suffix == ".py":
42
+ program = choice_file.read_text(encoding="utf-8")
43
+ text = f"📄 Selected file: {choice_file.name}"
44
+ console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
45
+ else:
46
+ program = lambda_to_python_script(lambda: get_read_data_pycode(path=str(choice_file)), in_global=True, import_module=False)
47
+ text = f"📄 Reading data from: {file_obj.name}"
48
+ console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
67
49
  else: # if nothing is specified, then run in interactive mode.
68
- # text = "⌨️ Entering interactive mode"
69
- # console.print(Panel(text, title="[bold blue]Info[/bold blue]"))
70
- # from machineconfig.scripts.python.croshell import InteractiveShell
71
- # InteractiveShell().run()
72
- # return None
73
50
  program = ""
74
51
  preprogram = """
75
52
  #%%
@@ -91,7 +68,7 @@ def croshell(
91
68
  pyfile.parent.mkdir(parents=True, exist_ok=True)
92
69
 
93
70
  title = "Reading Data"
94
- def_code = lambda_to_python_script(lambda: code(path=str(pyfile), title=title), in_global=False, import_module=False)
71
+ def_code = lambda_to_python_script(lambda: get_read_python_file_pycode(path=str(pyfile), title=title), in_global=False, import_module=False)
95
72
  # print(def_code)
96
73
  python_program = preprogram + "\n\n" + def_code + program
97
74
  pyfile.write_text(python_program, encoding="utf-8")
@@ -130,7 +107,7 @@ def croshell(
130
107
  fire_line = f"uv run --python 3.14 --with visidata,pyarrow vd {str(file_obj)}"
131
108
  elif marimo:
132
109
  if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--with marimo --project "{str(Path.home().joinpath("code/machineconfig"))}" """
133
- else: requirements = """--python 3.14 --with "marimo,machineconfig[plot]>=7.51" """
110
+ else: requirements = """--python 3.14 --with "marimo,machineconfig[plot]>=7.52" """
134
111
  fire_line = f"""
135
112
  cd {str(pyfile.parent)}
136
113
  uv run --python 3.14 --with "marimo" marimo convert {pyfile.name} -o marimo_nb.py
@@ -138,14 +115,14 @@ uv run {requirements} marimo edit --host 0.0.0.0 marimo_nb.py
138
115
  """
139
116
  elif jupyter:
140
117
  if Path.home().joinpath("code/machineconfig").exists(): requirements = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" --with jupyterlab """
141
- else: requirements = """--with "machineconfig[plot]>=7.51" """
118
+ else: requirements = """--with "machineconfig[plot]>=7.52" """
142
119
  fire_line = f"uv run {requirements} jupyter-lab {str(nb_target)}"
143
120
  elif vscode:
144
121
  fire_line = f"""
145
122
  cd {str(pyfile.parent)}
146
123
  uv init --python 3.14
147
124
  uv venv
148
- uv add "machineconfig[plot]>=7.51"
125
+ uv add "machineconfig[plot]>=7.52"
149
126
  # code serve-web
150
127
  code --new-window {str(pyfile)}
151
128
  """
@@ -153,7 +130,7 @@ code --new-window {str(pyfile)}
153
130
  if interpreter == "ipython": profile = f" --profile {ipython_profile} --no-banner"
154
131
  else: profile = ""
155
132
  if Path.home().joinpath("code/machineconfig").exists(): ve_line = f"""--project "{str(Path.home().joinpath("code/machineconfig"))}" """
156
- else: ve_line = """--python 3.14 --with "machineconfig[plot]>=7.51" """
133
+ else: ve_line = """--python 3.14 --with "machineconfig[plot]>=7.52" """
157
134
  # ve_path_maybe, ipython_profile_maybe = get_ve_path_and_ipython_profile(Path.cwd())
158
135
  # --python 3.14
159
136
  fire_line = f"uv run {ve_line} {interpreter} {interactivity} {profile} {str(pyfile)}"
@@ -14,7 +14,7 @@ def install(which: Annotated[Optional[str], typer.Argument(..., help="Comma-sepa
14
14
  group: Annotated[bool, typer.Option(..., "--group", "-g", help="Treat 'which' as a group name. A group is bundle of apps.")] = False,
15
15
  interactive: Annotated[bool, typer.Option(..., "--interactive", "-ia", help="Interactive selection of programs to install.")] = False,
16
16
  ) -> None:
17
- """📦 Install essential packages"""
17
+ """📦 Install packages"""
18
18
  import machineconfig.utils.installer_utils.installer as installer_entry_point
19
19
  installer_entry_point.main(which=which, group=group, interactive=interactive)
20
20
 
@@ -2,7 +2,7 @@
2
2
  # /// script
3
3
  # requires-python = ">=3.13"
4
4
  # dependencies = [
5
- # "machineconfig>=7.51",
5
+ # "machineconfig>=7.52",
6
6
  # "textual",
7
7
  # "pyperclip",
8
8
  # ]
@@ -8,11 +8,9 @@ fire
8
8
  """
9
9
 
10
10
  from machineconfig.utils.ve import get_ve_path_and_ipython_profile
11
- from machineconfig.utils.options import choose_from_options
12
- from machineconfig.utils.path_helper import match_file_name, sanitize_path
13
- from machineconfig.utils.path_extended import PathExtended
14
11
  from machineconfig.utils.accessories import get_repo_root, randstr
15
12
  from machineconfig.scripts.python.helpers_fire_command.fire_jobs_args_helper import FireJobArgs, extract_kwargs, parse_fire_args_from_context
13
+ from machineconfig.utils.path_helper import get_choice_file
16
14
 
17
15
  import platform
18
16
  from typing import Optional, Annotated
@@ -21,25 +19,12 @@ import typer
21
19
 
22
20
 
23
21
  def route(args: FireJobArgs, fire_args: str = "") -> None:
24
- path_obj = sanitize_path(args.path)
25
- if not path_obj.exists():
26
- suffixes = {".py", ".sh", ".ps1"}
27
- choice_file = match_file_name(sub_string=args.path, search_root=PathExtended.cwd(), suffixes=suffixes)
28
- elif path_obj.is_dir():
29
- from machineconfig.scripts.python.helpers_fire_command.file_wrangler import search_for_files_of_interest
30
- print(f"🔍 Searching recursively for Python, PowerShell and Shell scripts in directory `{path_obj}`")
31
- files = search_for_files_of_interest(path_obj)
32
- print(f"🔍 Got #{len(files)} results.")
33
- choice_file = choose_from_options(multi=False, options=files, fzf=True, msg="Choose one option")
34
- choice_file = PathExtended(choice_file)
35
- else:
36
- choice_file = path_obj
37
-
22
+ choice_file = get_choice_file(args.path, suffixes=None)
38
23
  repo_root = get_repo_root(Path(choice_file))
39
24
  print(f"💾 Selected file: {choice_file}.\nRepo root: {repo_root}")
40
25
  if args.marimo:
41
26
  print(f"🧽 Preparing to launch Marimo notebook for `{choice_file}`...")
42
- tmp_dir = PathExtended.tmp().joinpath(f"tmp_scripts/marimo/{choice_file.stem}_{randstr()}")
27
+ tmp_dir = Path.home().joinpath(f"tmp_results/tmp_scripts/marimo/{choice_file.stem}_{randstr()}")
43
28
  tmp_dir.mkdir(parents=True, exist_ok=True)
44
29
  script = f"""
45
30
  cd {tmp_dir}
@@ -47,13 +32,13 @@ uv run --python 3.14 --with marimo marimo convert {choice_file} -o marimo_nb.py
47
32
  uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.py
48
33
  """
49
34
  from machineconfig.utils.code import exit_then_run_shell_script
35
+
50
36
  print(f"🚀 Launching Marimo notebook for `{choice_file}`...")
51
37
  exit_then_run_shell_script(script)
52
38
  return
53
39
 
54
40
  # ========================= preparing kwargs_dict
55
41
  if choice_file.suffix == ".py":
56
-
57
42
  kwargs_dict = extract_kwargs(args) # This now returns empty dict, but kept for compatibility
58
43
  else:
59
44
  kwargs_dict = {}
@@ -62,17 +47,20 @@ uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.
62
47
  choice_function: Optional[str] = None # Initialize to avoid unbound variable
63
48
  if args.choose_function:
64
49
  from machineconfig.scripts.python.helpers_fire_command.fire_jobs_route_helper import choose_function_or_lines
50
+
65
51
  choice_function, choice_file, kwargs_dict = choose_function_or_lines(choice_file, kwargs_dict)
66
52
  else:
67
53
  choice_function = args.function
68
54
 
69
55
  if choice_file.suffix == ".py":
70
56
  from machineconfig.scripts.python.helpers_fire_command.fire_jobs_route_helper import get_command_streamlit
57
+
71
58
  with_project = f"--project {repo_root} " if repo_root is not None else ""
72
59
  if args.streamlit:
73
60
  exe = get_command_streamlit(choice_file=choice_file, environment=args.environment, repo_root=repo_root)
74
61
  exe = f"uv run {with_project} {exe} "
75
- elif args.jupyter: exe = f"uv run {with_project} jupyter-lab"
62
+ elif args.jupyter:
63
+ exe = f"uv run {with_project} jupyter-lab"
76
64
  else:
77
65
  if args.interactive:
78
66
  _ve_root_from_file, ipy_profile = get_ve_path_and_ipython_profile(choice_file)
@@ -81,20 +69,36 @@ uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.
81
69
  exe = f"uv run {with_project} ipython -i --no-banner --profile {ipy_profile} "
82
70
  else:
83
71
  exe = f"uv run {with_project} python "
84
- elif choice_file.suffix == ".ps1" or choice_file.suffix == ".sh": exe = "."
85
- elif choice_file.suffix == "": exe = ""
86
- else: raise NotImplementedError(f"File type {choice_file.suffix} not supported, in the sense that I don't know how to fire it.")
72
+ elif choice_file.suffix == ".ps1" or choice_file.suffix == ".sh":
73
+ exe = "."
74
+ elif choice_file.suffix == "":
75
+ exe = ""
76
+ else:
77
+ raise NotImplementedError(f"File type {choice_file.suffix} not supported, in the sense that I don't know how to fire it.")
87
78
 
88
- if args.module or (args.debug and args.choose_function): # because debugging tools do not support choosing functions and don't interplay with fire module. So the only way to have debugging and choose function options is to import the file as a module into a new script and run the function of interest there and debug the new script.
79
+ if (
80
+ args.module or (args.debug and args.choose_function)
81
+ ): # because debugging tools do not support choosing functions and don't interplay with fire module. So the only way to have debugging and choose function options is to import the file as a module into a new script and run the function of interest there and debug the new script.
89
82
  assert choice_file.suffix == ".py", f"File must be a python file to be imported as a module. Got {choice_file}"
90
83
  from machineconfig.scripts.python.helpers_fire_command.file_wrangler import get_import_module_code, wrap_import_in_try_except
91
84
  from machineconfig.utils.meta import lambda_to_python_script
92
85
  from machineconfig.utils.code import print_code
86
+
93
87
  import_code = get_import_module_code(str(choice_file))
94
- import_code_robust = lambda_to_python_script(lambda: wrap_import_in_try_except(import_line=import_code, pyfile=str(choice_file), repo_root=str(repo_root) if repo_root is not None else None), in_global=True, import_module=False)
95
- code_printing = lambda_to_python_script(lambda: print_code(code=import_code_robust, lexer="python", desc="import code"), in_global=True, import_module=False)
96
- if choice_function is not None: calling = f"""res = {choice_function}({("**" + str(kwargs_dict)) if kwargs_dict else ""})"""
97
- else: calling = """# No function selected to call. You can add your code here."""
88
+ import_code_robust = lambda_to_python_script(
89
+ lambda: wrap_import_in_try_except(
90
+ import_line=import_code, pyfile=str(choice_file), repo_root=str(repo_root) if repo_root is not None else None
91
+ ),
92
+ in_global=True,
93
+ import_module=False,
94
+ )
95
+ code_printing = lambda_to_python_script(
96
+ lambda: print_code(code=import_code_robust, lexer="python", desc="import code"), in_global=True, import_module=False
97
+ )
98
+ if choice_function is not None:
99
+ calling = f"""res = {choice_function}({("**" + str(kwargs_dict)) if kwargs_dict else ""})"""
100
+ else:
101
+ calling = """# No function selected to call. You can add your code here."""
98
102
  choice_file = Path.home().joinpath(f"tmp_results/tmp_scripts/python/{Path(choice_file).parent.name}_{Path(choice_file).stem}_{randstr()}.py")
99
103
  choice_file.parent.mkdir(parents=True, exist_ok=True)
100
104
  choice_file.write_text(import_code_robust + "\n" + code_printing + "\n" + calling, encoding="utf-8")
@@ -117,15 +121,17 @@ uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.
117
121
  if args.holdDirectory:
118
122
  command = f"{exe} {choice_file}"
119
123
  else:
120
- command = f"cd {choice_file.parent}\n{exe} {choice_file.name}\ncd {PathExtended.cwd()}"
124
+ command = f"cd {choice_file.parent}\n{exe} {choice_file.name}\ncd {Path.cwd()}"
121
125
  elif args.cmd:
122
126
  command = rf""" cd /d {choice_file.parent} & {exe} {choice_file.name} """
123
127
  else:
124
- if choice_file.suffix == "": command = f"{exe} {choice_file} {fire_args}"
125
- else: command = f"{exe} {choice_file} "
126
-
128
+ if choice_file.suffix == "":
129
+ command = f"{exe} {choice_file} {fire_args}"
130
+ else:
131
+ command = f"{exe} {choice_file} "
127
132
 
128
- if not args.cmd: pass
133
+ if not args.cmd:
134
+ pass
129
135
  else:
130
136
  new_line = "\n"
131
137
  command = rf"""start cmd -Argument "/k {command.replace(new_line, " & ")} " """ # this works from powershell
@@ -134,23 +140,27 @@ uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.
134
140
  if choice_function is not None:
135
141
  command += f"--function {choice_function} "
136
142
 
137
- if args.optimized: command = command.replace("python ", "python -OO ")
143
+ if args.optimized:
144
+ command = command.replace("python ", "python -OO ")
138
145
 
139
146
  from rich.panel import Panel
140
147
  from rich.console import Console
141
148
  from rich.syntax import Syntax
149
+
142
150
  console = Console()
143
151
  if args.zellij_tab is not None:
144
- comman_path__ = PathExtended.tmpfile(suffix=".sh")
152
+ comman_path__ = Path.home().joinpath(f"tmp_results/tmp_scripts/zellij_commands/{choice_file.stem}_{randstr()}.sh")
145
153
  comman_path__.parent.mkdir(parents=True, exist_ok=True)
146
154
  comman_path__.write_text(command, encoding="utf-8")
147
155
  console.print(Panel(Syntax(command, lexer="shell"), title=f"🔥 fire command @ {comman_path__}: "), style="bold red")
148
156
  import subprocess
157
+
149
158
  existing_tab_names = subprocess.run(["zellij", "action", "query-tab-names"], capture_output=True, text=True, check=True).stdout.splitlines()
150
159
  if args.zellij_tab in existing_tab_names:
151
160
  print(f"⚠️ Tab name `{args.zellij_tab}` already exists. Please choose a different name.")
152
161
  args.zellij_tab += f"_{randstr(3)}"
153
162
  from machineconfig.cluster.sessions_managers.zellij_local import run_command_in_zellij_tab
163
+
154
164
  command = run_command_in_zellij_tab(command=str(comman_path__), tab_name=args.zellij_tab, cwd=None)
155
165
  if args.watch:
156
166
  command = "watchexec --restart --exts py,sh,ps1 " + command
@@ -158,6 +168,7 @@ uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.
158
168
  command = f"\ngit -C {choice_file.parent} pull\n" + command
159
169
  if args.PathExport:
160
170
  from machineconfig.scripts.python.helpers_fire_command.file_wrangler import add_to_path
171
+
161
172
  export_line = add_to_path(path_variable="PYTHONPATH", directory=str(repo_root))
162
173
  command = export_line + "\n" + command
163
174
  if args.loop:
@@ -169,6 +180,7 @@ uv run --project {repo_root} --with marimo marimo edit --host 0.0.0.0 marimo_nb.
169
180
  raise NotImplementedError(f"Platform {platform.system()} not supported.")
170
181
 
171
182
  from machineconfig.utils.code import exit_then_run_shell_script
183
+
172
184
  exit_then_run_shell_script(script=command, strict=False)
173
185
 
174
186
 
@@ -187,15 +199,14 @@ def fire(
187
199
  module: Annotated[bool, typer.Option("--module", "-m", help="Launch the main file")] = False,
188
200
  optimized: Annotated[bool, typer.Option("--optimized", "-O", help="Run the optimized version of the function")] = False,
189
201
  zellij_tab: Annotated[Optional[str], typer.Option("--zellij-tab", "-z", help="Open in a new zellij tab")] = None,
190
-
191
202
  submit_to_cloud: Annotated[bool, typer.Option("--submit-to-cloud", "-C", help="Submit to cloud compute")] = False,
192
203
  remote: Annotated[bool, typer.Option("--remote", "-r", help="Launch on a remote machine")] = False,
193
-
194
204
  streamlit: Annotated[bool, typer.Option("--streamlit", "-S", help="Run as streamlit app")] = False,
195
205
  environment: Annotated[str, typer.Option("--environment", "-E", help="Choose ip, localhost, hostname or arbitrary url")] = "",
196
- holdDirectory: Annotated[bool, typer.Option("--holdDirectory", "-D", help="Hold current directory and avoid cd'ing to the script directory")] = False,
206
+ holdDirectory: Annotated[
207
+ bool, typer.Option("--holdDirectory", "-D", help="Hold current directory and avoid cd'ing to the script directory")
208
+ ] = False,
197
209
  PathExport: Annotated[bool, typer.Option("--PathExport", "-P", help="Augment the PYTHONPATH with repo root")] = False,
198
-
199
210
  git_pull: Annotated[bool, typer.Option("--git-pull", "-g", help="Start by pulling the git repo")] = False,
200
211
  watch: Annotated[bool, typer.Option("--watch", "-w", help="Watch the file for changes")] = False,
201
212
  ) -> None:
@@ -235,12 +246,14 @@ def fire(
235
246
  except Exception as e:
236
247
  # For other exceptions, print clean error message and exit
237
248
  import sys
249
+
238
250
  print(f"❌ Error: {e}", file=sys.stderr)
239
251
  sys.exit(1)
240
252
 
241
253
 
242
254
  def get_app():
243
255
  from typer import Typer
256
+
244
257
  app = Typer(add_completion=False)
245
258
  app.command(context_settings={"allow_extra_args": True, "allow_interspersed_args": False})(fire)
246
259
  return app
@@ -1,6 +1,6 @@
1
1
 
2
2
 
3
- def code(path: str, title: str):
3
+ def get_read_python_file_pycode(path: str, title: str):
4
4
  from pathlib import Path
5
5
  print("Reading code from path:", path)
6
6
  pycode = Path(path).read_text(encoding="utf-8")
@@ -7,7 +7,7 @@ import machineconfig.scripts.python.helpers_devops.cli_config_dotfile as dotfile
7
7
  import machineconfig.profile.create_links_export as create_links_export
8
8
 
9
9
 
10
- def shell(which: Annotated[Literal["default", "d", "nushell", "n"], typer.Option(..., "--which", "-w", help="Which shell profile to create/configure")]="default"):
10
+ def configure_shell_profile(which: Annotated[Literal["default", "d", "nushell", "n"], typer.Option(..., "--which", "-w", help="Which shell profile to create/configure")]="default"):
11
11
  """🔗 Configure your shell profile."""
12
12
  from machineconfig.profile.create_shell_profile import create_default_shell_profile, create_nu_shell_profile
13
13
  match which:
@@ -20,20 +20,6 @@ def shell(which: Annotated[Literal["default", "d", "nushell", "n"], typer.Option
20
20
  typer.echo(f"[red]Error:[/] Unknown shell profile type: {which}")
21
21
 
22
22
 
23
- def path():
24
- """📚 NAVIGATE PATH variable with TUI"""
25
- from machineconfig.scripts.python import env_manager as navigator
26
- from pathlib import Path
27
- path = Path(navigator.__file__).resolve().parent.joinpath("path_manager_tui.py")
28
- from machineconfig.utils.code import run_shell_script, get_uv_command_executing_python_script
29
- uv_with = ["textual"]
30
- uv_project_dir = None
31
- if not Path.home().joinpath("code/machineconfig").exists():
32
- uv_with.append("machineconfig>=7.51")
33
- else:
34
- uv_project_dir = str(Path.home().joinpath("code/machineconfig"))
35
- run_shell_script(get_uv_command_executing_python_script(python_script=path.read_text(encoding="utf-8"), uv_with=uv_with, uv_project_dir=uv_project_dir)[0])
36
-
37
23
 
38
24
  def pwsh_theme():
39
25
  """🔗 Select powershell prompt theme."""
@@ -97,10 +83,8 @@ def get_app():
97
83
  config_apps.command("b", no_args_is_help=True, help="Manage public configuration files.", hidden=True)(create_links_export.main_public_from_parser)
98
84
  config_apps.command("dotfile", no_args_is_help=True, help="🔗 [d] Manage dotfiles.")(dotfile_module.main)
99
85
  config_apps.command("d", no_args_is_help=True, hidden=True)(dotfile_module.main)
100
- config_apps.command("shell", no_args_is_help=False, help="🔗 [s] Configure your shell profile.")(shell)
101
- config_apps.command("s", no_args_is_help=False, help="Configure your shell profile.", hidden=True)(shell)
102
- config_apps.command("path", no_args_is_help=False, help="📚 [p] NAVIGATE PATH variable with TUI")(path)
103
- config_apps.command("p", no_args_is_help=False, help="NAVIGATE PATH variable with TUI", hidden=True)(path)
86
+ config_apps.command("shell", no_args_is_help=False, help="🔗 [s] Configure your shell profile.")(configure_shell_profile)
87
+ config_apps.command("s", no_args_is_help=False, help="Configure your shell profile.", hidden=True)(configure_shell_profile)
104
88
  config_apps.command("starship-theme", no_args_is_help=False, help="🔗 [t] Select starship prompt theme.")(starship_theme)
105
89
  config_apps.command("t", no_args_is_help=False, help="Select starship prompt theme.", hidden=True)(starship_theme)
106
90
  config_apps.command("pwsh-theme", no_args_is_help=False, help="🔗 [T] Select powershell prompt theme.")(pwsh_theme)