machineconfig 8.14__py3-none-any.whl → 8.45__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/remote/run_cluster.py +1 -1
- machineconfig/cluster/remote/run_remote.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +10 -8
- machineconfig/cluster/sessions_managers/wt_local.py +1 -1
- machineconfig/cluster/sessions_managers/wt_local_manager.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_local.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +1 -1
- machineconfig/jobs/installer/checks/check_installations.py +133 -0
- machineconfig/jobs/installer/checks/install_utils.py +132 -0
- machineconfig/jobs/installer/checks/report_utils.py +39 -0
- machineconfig/jobs/installer/checks/vt_utils.py +89 -0
- machineconfig/jobs/installer/installer_data.json +225 -140
- machineconfig/jobs/installer/linux_scripts/docker.sh +6 -9
- machineconfig/jobs/installer/package_groups.py +10 -9
- machineconfig/jobs/installer/python_scripts/boxes.py +1 -2
- machineconfig/jobs/installer/python_scripts/code.py +10 -8
- machineconfig/jobs/installer/python_scripts/hx.py +30 -13
- machineconfig/jobs/installer/python_scripts/nerfont_windows_helper.py +6 -5
- machineconfig/jobs/installer/python_scripts/sysabc.py +25 -19
- machineconfig/jobs/installer/python_scripts/yazi.py +33 -17
- machineconfig/jobs/scripts/powershell_scripts/cmatrix.ps1 +52 -0
- machineconfig/jobs/scripts/powershell_scripts/mount_ssh.ps1 +1 -1
- machineconfig/jobs/scripts_dynamic/a.py +413 -10
- machineconfig/profile/create_links.py +77 -20
- machineconfig/profile/create_links_export.py +40 -51
- machineconfig/profile/mapper_data.toml +30 -0
- machineconfig/profile/mapper_dotfiles.toml +253 -0
- machineconfig/scripts/python/agents.py +70 -172
- machineconfig/scripts/python/ai/initai.py +3 -1
- machineconfig/scripts/python/ai/scripts/__init__.py +1 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +2 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +7 -5
- machineconfig/scripts/python/ai/solutions/claude/claude.py +1 -1
- machineconfig/scripts/python/ai/solutions/cline/cline.py +1 -1
- machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +1 -1
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +29 -0
- machineconfig/scripts/python/ai/solutions/crush/crush.py +1 -1
- machineconfig/scripts/python/ai/solutions/cursor/cursors.py +1 -1
- machineconfig/scripts/python/ai/solutions/gemini/gemini.py +1 -1
- machineconfig/scripts/python/ai/solutions/gemini/settings.json +3 -0
- machineconfig/scripts/python/ai/{solutions → utils}/generic.py +2 -15
- machineconfig/scripts/python/ai/utils/vscode_tasks.py +6 -3
- machineconfig/scripts/python/cloud.py +58 -11
- machineconfig/scripts/python/croshell.py +4 -156
- machineconfig/scripts/python/devops.py +57 -40
- machineconfig/scripts/python/devops_navigator.py +17 -3
- machineconfig/scripts/python/fire_jobs.py +8 -207
- machineconfig/scripts/python/ftpx.py +5 -225
- machineconfig/scripts/python/graph/cli_graph.json +8743 -0
- machineconfig/scripts/python/{env_manager → helper_env}/path_manager_tui.py +2 -2
- machineconfig/scripts/python/{env_manager → helpers/helper_env}/env_manager_tui.py +1 -1
- machineconfig/scripts/python/helpers/helper_env/path_manager_tui.py +228 -0
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_cursor_agents.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_gemini.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_qwen.py +1 -1
- machineconfig/scripts/python/helpers/helpers_agents/agents_impl.py +168 -0
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_launch.py +5 -5
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_copy.py +6 -6
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_mount.py +10 -5
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_sync.py +3 -3
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers2.py +1 -1
- machineconfig/scripts/python/helpers/helpers_croshell/croshell_impl.py +225 -0
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/scheduler.py +4 -4
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/start_slidev.py +7 -6
- machineconfig/scripts/python/helpers/helpers_devops/backup_config.py +149 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_backup_retrieve.py +267 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_config.py +98 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_config_dotfile.py +274 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_data.py +76 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_nw.py +52 -72
- machineconfig/scripts/python/helpers/helpers_devops/cli_repos.py +265 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_self.py +39 -23
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_file.py +44 -30
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_server.py +26 -43
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_terminal.py +12 -6
- machineconfig/scripts/python/helpers/helpers_devops/cli_ssh.py +167 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_status.py +12 -6
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_update_repos.py +1 -1
- machineconfig/scripts/python/{interactive.py → helpers/helpers_devops/interactive.py} +68 -52
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/run_script.py +75 -58
- machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.ps1 +41 -0
- machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.sh +48 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_wezterm_theme.py +3 -3
- machineconfig/scripts/python/helpers/helpers_fire_command/fire_jobs_impl.py +233 -0
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_route_helper.py +3 -3
- machineconfig/scripts/python/helpers/helpers_msearch/msearch_impl.py +248 -0
- machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_linux/fzfg +4 -3
- machineconfig/scripts/python/helpers/helpers_msearch/scripts_linux/search_with_context.sh +48 -0
- machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_windows/fzfg.ps1 +1 -1
- machineconfig/scripts/python/helpers/helpers_navigator/__init__.py +20 -0
- machineconfig/scripts/python/helpers/helpers_navigator/cli_graph_loader.py +234 -0
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/command_builder.py +61 -13
- machineconfig/scripts/python/helpers/helpers_navigator/command_detail.py +153 -0
- machineconfig/scripts/python/helpers/helpers_navigator/command_tree.py +45 -0
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/data_models.py +18 -11
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/main_app.py +5 -5
- machineconfig/scripts/python/helpers/helpers_network/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/address.py +15 -17
- machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/address_switch.py +1 -1
- machineconfig/scripts/python/helpers/helpers_network/ftpx_impl.py +276 -0
- machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_ssh.py +2 -2
- machineconfig/scripts/python/helpers/helpers_network/ssh_add_identity.py +73 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_add_ssh_key.py +175 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_debug_linux.py +319 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_debug_windows.py +275 -0
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action.py +3 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action_helper.py +3 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/cloud_repo_sync.py +116 -33
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/grource.py +3 -2
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/record.py +33 -13
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_2.py +63 -19
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/update.py +0 -6
- machineconfig/scripts/python/helpers/helpers_search/script_help.py +81 -0
- machineconfig/scripts/python/helpers/helpers_sessions/__init__.py +0 -0
- machineconfig/scripts/python/helpers/helpers_sessions/sessions_impl.py +177 -0
- machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py +1 -1
- machineconfig/scripts/python/helpers/helpers_terminal/__init__.py +0 -0
- machineconfig/scripts/python/helpers/helpers_terminal/terminal_impl.py +96 -0
- machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/download.py +1 -1
- machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/python.py +46 -26
- machineconfig/scripts/python/helpers/helpers_utils/specs.py +246 -0
- machineconfig/scripts/python/mcfg_entry.py +133 -48
- machineconfig/scripts/python/msearch.py +15 -61
- machineconfig/scripts/python/sessions.py +59 -194
- machineconfig/scripts/python/terminal.py +18 -96
- machineconfig/scripts/python/utils.py +101 -20
- machineconfig/settings/atuin/config.toml +294 -0
- machineconfig/settings/atuin/themes/catppuccin-mocha-mauve.toml +12 -0
- machineconfig/settings/linters/.ruff.toml +1 -0
- machineconfig/settings/mprocs/windows/mprocs.yaml +2 -2
- machineconfig/settings/shells/bash/init.sh +6 -3
- machineconfig/settings/shells/pwsh/init.ps1 +69 -1
- machineconfig/settings/shells/pwsh/search_pwsh_history.ps1 +99 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +4 -1
- machineconfig/settings/shells/wt/settings.json +20 -7
- machineconfig/settings/shells/zsh/init.sh +34 -4
- machineconfig/settings/television/cable_unix/bash-history.toml +1 -1
- machineconfig/settings/television/cable_windows/pwsh-history.toml +1 -1
- machineconfig/settings/tv/config.toml +234 -0
- machineconfig/settings/tv/themes/catppuccin-mocha-sky.toml +22 -0
- machineconfig/settings/wsl/.wslconfig +5 -30
- machineconfig/settings/yazi/yazi_linux.toml +18 -8
- machineconfig/settings/zellij/layouts/st.kdl +2 -2
- machineconfig/settings/zellij/layouts/st2.kdl +1 -1
- machineconfig/setup_linux/web_shortcuts/interactive.sh +10 -10
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +3 -0
- machineconfig/setup_mac/__init__.py +0 -2
- machineconfig/setup_windows/__init__.py +0 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +14 -13
- machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +4 -3
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +3 -3
- machineconfig/type_hinting/sql/__init__.py +1 -0
- machineconfig/type_hinting/sql/base.py +216 -0
- machineconfig/type_hinting/sql/core_schema.py +64 -0
- machineconfig/type_hinting/sql/core_schema_typeddict.py +41 -0
- machineconfig/type_hinting/sql/typeddict_codegen.py +222 -0
- machineconfig/type_hinting/typedict/__init__.py +1 -0
- machineconfig/type_hinting/typedict/ast_utils.py +130 -0
- machineconfig/type_hinting/typedict/generator_helpers.py +319 -0
- machineconfig/type_hinting/typedict/generators.py +231 -0
- machineconfig/type_hinting/typedict/polars_schema.py +24 -0
- machineconfig/type_hinting/typedict/polars_schema_typeddict.py +63 -0
- machineconfig/utils/accessories.py +24 -0
- machineconfig/utils/code.py +41 -13
- machineconfig/utils/files/ascii_art.py +10 -14
- machineconfig/utils/files/headers.py +3 -5
- machineconfig/utils/files/read.py +8 -1
- machineconfig/utils/installer_utils/github_release_bulk.py +1 -0
- machineconfig/utils/installer_utils/install_from_url.py +1 -1
- machineconfig/utils/installer_utils/installer_class.py +12 -4
- machineconfig/utils/installer_utils/installer_cli.py +1 -15
- machineconfig/utils/installer_utils/installer_helper.py +2 -2
- machineconfig/utils/installer_utils/installer_locator_utils.py +13 -13
- machineconfig/utils/installer_utils/installer_runner.py +4 -4
- machineconfig/utils/meta.py +6 -4
- machineconfig/utils/options.py +49 -19
- machineconfig/utils/options_utils/__init__.py +0 -0
- machineconfig/utils/options_utils/options_tv_linux.py +211 -0
- machineconfig/utils/options_utils/options_tv_windows.py +88 -0
- machineconfig/utils/options_utils/tv_options.py +37 -0
- machineconfig/utils/path_extended.py +6 -6
- machineconfig/utils/scheduler.py +8 -2
- machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
- machineconfig/utils/source_of_truth.py +6 -1
- machineconfig/utils/ssh.py +69 -18
- machineconfig/utils/ssh_utils/abc.py +1 -1
- machineconfig/utils/ssh_utils/wsl.py +107 -170
- machineconfig/utils/ssh_utils/wsl_helper.py +217 -0
- machineconfig/utils/upgrade_packages.py +4 -8
- {machineconfig-8.14.dist-info → machineconfig-8.45.dist-info}/METADATA +29 -22
- {machineconfig-8.14.dist-info → machineconfig-8.45.dist-info}/RECORD +247 -208
- machineconfig/jobs/installer/check_installations.py +0 -248
- machineconfig/profile/backup.toml +0 -49
- machineconfig/profile/mapper.toml +0 -263
- machineconfig/scripts/python/helpers_devops/cli_config.py +0 -105
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +0 -89
- machineconfig/scripts/python/helpers_devops/cli_data.py +0 -25
- machineconfig/scripts/python/helpers_devops/cli_repos.py +0 -208
- machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +0 -80
- machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +0 -3
- machineconfig/scripts/python/helpers_navigator/__init__.py +0 -20
- machineconfig/scripts/python/helpers_navigator/command_detail.py +0 -44
- machineconfig/scripts/python/helpers_navigator/command_tree.py +0 -620
- machineconfig/scripts/python/helpers_network/ssh_add_identity.py +0 -116
- machineconfig/scripts/python/helpers_network/ssh_add_ssh_key.py +0 -153
- machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +0 -391
- machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +0 -338
- machineconfig/scripts/python/helpers_repos/entrypoint.py +0 -77
- machineconfig/setup_mac/ssh/openssh_setup.sh +0 -114
- machineconfig/setup_windows/ssh/add-sshkey.ps1 +0 -29
- machineconfig/setup_windows/ssh/openssh-server.ps1 +0 -37
- machineconfig/utils/options_tv.py +0 -119
- machineconfig/utils/tst.py +0 -20
- /machineconfig/{scripts/python/helpers_agents → jobs/installer/checks}/__init__.py +0 -0
- /machineconfig/scripts/python/ai/{solutions/_shared.py → utils/shared.py} +0 -0
- /machineconfig/scripts/python/{helpers_agents/agentic_frameworks → graph}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers}/__init__.py +0 -0
- /machineconfig/scripts/python/{env_manager → helpers/helper_env}/__init__.py +0 -0
- /machineconfig/scripts/python/{env_manager → helpers/helper_env}/path_manager_backend.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_agents}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_devops → helpers/helpers_agents/agentic_frameworks}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.json +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_search.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_helper_types.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_load_balancer.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/aichat/config.yaml +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/aider/.aider.conf.yml +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/copilot/config.yml +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/crush/crush.json +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/gemini/settings.json +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/privacy.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/prompt.txt +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.ps1 +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.sh +0 -0
- /machineconfig/scripts/python/{helpers_devops/themes → helpers/helpers_cloud}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_helpers.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers5.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_croshell}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/crosh.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/pomodoro.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer_template.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_devops}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_sessions → helpers/helpers_devops/themes}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
- /machineconfig/scripts/python/{helpers_devops/themes/choose_starship_theme.ps1 → helpers/helpers_fire_command/__init__.py} +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/cloud_manager.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/f.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/file_wrangler.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_args_helper.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_streamlit_helper.py +0 -0
- /machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/search_bar.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nfs.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nw_drive.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/onetimeshare.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/wifi_conn.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/clone.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_1.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/sync.py +0 -0
- /machineconfig/scripts/python/helpers/{ast_search.py → helpers_search/ast_search.py} +0 -0
- /machineconfig/scripts/python/helpers/{qr_code.py → helpers_search/qr_code.py} +0 -0
- /machineconfig/scripts/python/helpers/{repo_rag.py → helpers_search/repo_rag.py} +0 -0
- /machineconfig/scripts/python/helpers/{symantic_search.py → helpers_search/symantic_search.py} +0 -0
- /machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/pdf.py +0 -0
- {machineconfig-8.14.dist-info → machineconfig-8.45.dist-info}/WHEEL +0 -0
- {machineconfig-8.14.dist-info → machineconfig-8.45.dist-info}/entry_points.txt +0 -0
- {machineconfig-8.14.dist-info → machineconfig-8.45.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from typing import Any, TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
import polars as pl
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_polars_schema(typed_dict: type) -> "dict[str, pl.DataType]":
|
|
8
|
+
import polars as pl
|
|
9
|
+
|
|
10
|
+
def _get_polars_type(python_type: Any) -> pl.DataType:
|
|
11
|
+
if python_type == str:
|
|
12
|
+
return pl.String()
|
|
13
|
+
if python_type == float:
|
|
14
|
+
return pl.Float64()
|
|
15
|
+
if python_type == int:
|
|
16
|
+
return pl.Int64()
|
|
17
|
+
if python_type == bool:
|
|
18
|
+
return pl.Boolean()
|
|
19
|
+
return pl.String()
|
|
20
|
+
|
|
21
|
+
schema: dict[str, pl.DataType] = {}
|
|
22
|
+
for k, v in typed_dict.__annotations__.items():
|
|
23
|
+
schema[k] = _get_polars_type(v)
|
|
24
|
+
return schema
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from typing import Any, ReadOnly, get_origin, get_args, TYPE_CHECKING
|
|
2
|
+
import random
|
|
3
|
+
import secrets
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
import polars as pl
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _unwrap_type(python_type: Any) -> Any:
|
|
10
|
+
"""Unwrap ReadOnly and other type wrappers to get the inner type."""
|
|
11
|
+
origin = get_origin(python_type)
|
|
12
|
+
if origin is ReadOnly:
|
|
13
|
+
args = get_args(python_type)
|
|
14
|
+
return args[0] if args else python_type
|
|
15
|
+
return python_type
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _get_polars_type(python_type: Any) -> "pl.DataType":
|
|
19
|
+
"""Convert Python types to appropriate Polars types, handling ReadOnly wrappers."""
|
|
20
|
+
unwrapped = _unwrap_type(python_type)
|
|
21
|
+
import polars as pl
|
|
22
|
+
if unwrapped is str:
|
|
23
|
+
return pl.String()
|
|
24
|
+
if unwrapped is float:
|
|
25
|
+
return pl.Float64()
|
|
26
|
+
if unwrapped is int:
|
|
27
|
+
return pl.Int64()
|
|
28
|
+
if unwrapped is bool:
|
|
29
|
+
return pl.Boolean()
|
|
30
|
+
return pl.String()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_polars_schema_from_typeddict(typed_dict: type) -> dict[str, "pl.DataType"]:
|
|
34
|
+
"""Convert a TypedDict to a Polars schema, properly handling ReadOnly wrappers."""
|
|
35
|
+
# import polars as pl
|
|
36
|
+
schema: dict[str, "pl.DataType"] = {}
|
|
37
|
+
for k, v in typed_dict.__annotations__.items():
|
|
38
|
+
schema[k] = _get_polars_type(v)
|
|
39
|
+
return schema
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_polars_df_random_data_from_typeddict(typed_dict: type, n_rows: int) -> "pl.DataFrame":
|
|
43
|
+
"""Generate a Polars DataFrame with random data based on a TypedDict definition."""
|
|
44
|
+
data: dict[str, "pl.Series"] = {}
|
|
45
|
+
import polars as pl
|
|
46
|
+
for k, v in typed_dict.__annotations__.items():
|
|
47
|
+
unwrapped = _unwrap_type(v)
|
|
48
|
+
if unwrapped is str:
|
|
49
|
+
data[k] = pl.Series([secrets.token_hex(8) for _ in range(n_rows)])
|
|
50
|
+
elif unwrapped is int:
|
|
51
|
+
data[k] = pl.Series(random.choices(range(-1000, 1000), k=n_rows))
|
|
52
|
+
elif unwrapped is float:
|
|
53
|
+
data[k] = pl.Series([random.uniform(-1000.0, 1000.0) for _ in range(n_rows)])
|
|
54
|
+
elif unwrapped is bool:
|
|
55
|
+
data[k] = pl.Series(random.choices([True, False], k=n_rows))
|
|
56
|
+
elif unwrapped is bytes:
|
|
57
|
+
data[k] = pl.Series([secrets.token_bytes(16) for _ in range(n_rows)])
|
|
58
|
+
elif get_origin(unwrapped) is list:
|
|
59
|
+
data[k] = pl.Series([[random.randint(0, 100) for _ in range(3)] for _ in range(n_rows)])
|
|
60
|
+
else:
|
|
61
|
+
data[k] = pl.Series([None] * n_rows)
|
|
62
|
+
|
|
63
|
+
return pl.DataFrame(data, schema=get_polars_schema_from_typeddict(typed_dict))
|
|
@@ -110,3 +110,27 @@ def get_repo_root(path: "Path") -> Optional["Path"]:
|
|
|
110
110
|
|
|
111
111
|
if __name__ == "__main__":
|
|
112
112
|
from pathlib import Path
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def display_with_flashy_style(msg: str, title: str) -> None:
|
|
116
|
+
"""Display a flashy, unmissable share URL announcement."""
|
|
117
|
+
from rich.console import Console
|
|
118
|
+
from rich.panel import Panel
|
|
119
|
+
from rich.text import Text
|
|
120
|
+
from rich.align import Align
|
|
121
|
+
console = Console()
|
|
122
|
+
url_text = Text(msg, style="bold bright_cyan underline")
|
|
123
|
+
message = Text.assemble(
|
|
124
|
+
("🚀 ", "bright_red"),
|
|
125
|
+
url_text,
|
|
126
|
+
(" 🚀", "bright_red")
|
|
127
|
+
)
|
|
128
|
+
panel = Panel(
|
|
129
|
+
Align.center(message),
|
|
130
|
+
title=f"[bold bright_green]🌐 {title} 🌐[/bold bright_green]",
|
|
131
|
+
subtitle="[italic bright_yellow]⚡ Click the link above to access your shared files! ⚡[/italic bright_yellow]",
|
|
132
|
+
border_style="bright_magenta",
|
|
133
|
+
padding=(1, 2),
|
|
134
|
+
expand=False
|
|
135
|
+
)
|
|
136
|
+
console.print(panel)
|
machineconfig/utils/code.py
CHANGED
|
@@ -35,7 +35,8 @@ def print_code(code: str, lexer: str, desc: str, subtitle: str = ""):
|
|
|
35
35
|
print(f"--- End of {desc} ---")
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
def get_uv_command_executing_python_file(python_file: str, uv_with: Optional[list[str]],
|
|
38
|
+
def get_uv_command_executing_python_file(python_file: str, uv_with: Optional[list[str]],
|
|
39
|
+
uv_project_dir: Optional[str],
|
|
39
40
|
prepend_print: bool = True, ) -> str:
|
|
40
41
|
# shell script
|
|
41
42
|
if uv_with is not None and len(uv_with) > 0:
|
|
@@ -49,7 +50,7 @@ def get_uv_command_executing_python_file(python_file: str, uv_with: Optional[lis
|
|
|
49
50
|
if uv_project_dir is not None:
|
|
50
51
|
uv_project_dir_arg = "--project" + f' "{uv_project_dir}"'
|
|
51
52
|
else:
|
|
52
|
-
uv_project_dir_arg = ""
|
|
53
|
+
uv_project_dir_arg = "--no-project"
|
|
53
54
|
import platform
|
|
54
55
|
|
|
55
56
|
uv_command = get_uv_command(platform=platform.system())
|
|
@@ -72,11 +73,14 @@ def get_uv_command_executing_python_script(python_script: str, uv_with: Optional
|
|
|
72
73
|
return shell_script, python_file
|
|
73
74
|
|
|
74
75
|
|
|
75
|
-
def
|
|
76
|
+
def get_shell_script_running_lambda_function(lmb: Callable[[], Any], uv_with: Optional[list[str]], uv_project_dir: Optional[str]) -> tuple[str, Path]:
|
|
76
77
|
from machineconfig.utils.meta import lambda_to_python_script
|
|
77
78
|
code = lambda_to_python_script(lmb,
|
|
78
79
|
in_global=True, import_module=False)
|
|
79
|
-
uv_command,
|
|
80
|
+
uv_command, py_file = get_uv_command_executing_python_script(python_script=code, uv_with=uv_with, uv_project_dir=uv_project_dir)
|
|
81
|
+
return uv_command, py_file
|
|
82
|
+
def run_lambda_function(lmb: Callable[[], Any], uv_with: Optional[list[str]], uv_project_dir: Optional[str]) -> None:
|
|
83
|
+
uv_command, _py_file = get_shell_script_running_lambda_function(lmb=lmb, uv_with=uv_with, uv_project_dir=uv_project_dir)
|
|
80
84
|
run_shell_script(uv_command)
|
|
81
85
|
|
|
82
86
|
|
|
@@ -111,10 +115,7 @@ def run_shell_file(script_path: str, clean_env: bool):
|
|
|
111
115
|
else:
|
|
112
116
|
raise NotImplementedError(f"Platform {platform.system()} not supported.")
|
|
113
117
|
return proc
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
def run_shell_script(script: str, display_script: bool = True, clean_env: bool = False) -> Any:
|
|
117
|
-
|
|
118
|
+
def run_shell_script(script: str, display_script: bool = True, clean_env: bool = False):
|
|
118
119
|
import platform
|
|
119
120
|
if platform.system() == "Windows":
|
|
120
121
|
suffix = ".ps1"
|
|
@@ -122,12 +123,10 @@ def run_shell_script(script: str, display_script: bool = True, clean_env: bool =
|
|
|
122
123
|
else:
|
|
123
124
|
suffix = ".sh"
|
|
124
125
|
lexer = "bash"
|
|
125
|
-
|
|
126
126
|
import tempfile
|
|
127
127
|
with tempfile.NamedTemporaryFile(mode='w', suffix=suffix, delete=False, encoding='utf-8') as temp_file:
|
|
128
128
|
temp_file.write(script)
|
|
129
129
|
temp_shell_script_path = Path(temp_file.name)
|
|
130
|
-
|
|
131
130
|
from rich.panel import Panel
|
|
132
131
|
from rich.syntax import Syntax
|
|
133
132
|
from rich.console import Console
|
|
@@ -135,7 +134,6 @@ def run_shell_script(script: str, display_script: bool = True, clean_env: bool =
|
|
|
135
134
|
if display_script:
|
|
136
135
|
from rich.syntax import Syntax
|
|
137
136
|
console.print(Panel(Syntax(code=script, lexer=lexer), title=f"📄 shell script @ {temp_shell_script_path}", subtitle="shell script being executed"), style="bold red")
|
|
138
|
-
|
|
139
137
|
proc = run_shell_file(script_path=str(temp_shell_script_path), clean_env=clean_env)
|
|
140
138
|
# console.print(f"✅ [green]Script executed successfully:[/green] [blue]{temp_script_path}[/blue]")
|
|
141
139
|
if proc.returncode != 0:
|
|
@@ -144,7 +142,6 @@ def run_shell_script(script: str, display_script: bool = True, clean_env: bool =
|
|
|
144
142
|
console.print(f"✅ [green]Script executed successfully:[/green] [blue]{temp_shell_script_path}[/blue]")
|
|
145
143
|
else:
|
|
146
144
|
console.print(f"⚠️ [yellow]Script executed with warnings (return code {proc.returncode}):[/yellow] [blue]{temp_shell_script_path}[/blue]")
|
|
147
|
-
|
|
148
145
|
temp_shell_script_path.unlink(missing_ok=True)
|
|
149
146
|
console.print(f"🗑️ [blue]Temporary script deleted:[/blue] [green]{temp_shell_script_path}[/green]")
|
|
150
147
|
return proc
|
|
@@ -153,7 +150,6 @@ def run_shell_script(script: str, display_script: bool = True, clean_env: bool =
|
|
|
153
150
|
def exit_then_run_shell_script(script: str, strict: bool = False):
|
|
154
151
|
import os
|
|
155
152
|
from rich.console import Console
|
|
156
|
-
|
|
157
153
|
console = Console()
|
|
158
154
|
op_program_path = os.environ.get("OP_PROGRAM_PATH", None)
|
|
159
155
|
if op_program_path is not None:
|
|
@@ -196,3 +192,35 @@ def exit_then_run_shell_script(script: str, strict: bool = False):
|
|
|
196
192
|
run_shell_script(script)
|
|
197
193
|
import sys
|
|
198
194
|
sys.exit(0)
|
|
195
|
+
def exit_then_run_shell_file(script_path: str, strict: bool):
|
|
196
|
+
import os
|
|
197
|
+
from rich.console import Console
|
|
198
|
+
console = Console()
|
|
199
|
+
op_program_path = os.environ.get("OP_PROGRAM_PATH", None)
|
|
200
|
+
if op_program_path is None or Path(op_program_path).exists():
|
|
201
|
+
if strict:
|
|
202
|
+
console.print("[red]❌ OP_PROGRAM_PATH environment variable is not set or the file already exists in strict mode.[/red]")
|
|
203
|
+
import sys
|
|
204
|
+
sys.exit(1)
|
|
205
|
+
if op_program_path is None or Path(op_program_path).exists():
|
|
206
|
+
console.print("[cyan]ℹ️ OP_PROGRAM_PATH is not set.[/cyan] [yellow]Falling back to direct execution.[/yellow]")
|
|
207
|
+
run_shell_file(script_path=script_path, clean_env=False)
|
|
208
|
+
return
|
|
209
|
+
import platform
|
|
210
|
+
if platform.system() == "Windows":
|
|
211
|
+
suffix = ".ps1"
|
|
212
|
+
lexer = "powershell"
|
|
213
|
+
script = str(script_path)
|
|
214
|
+
elif platform.system() == "Linux" or platform.system() == "Darwin":
|
|
215
|
+
suffix = ".sh"
|
|
216
|
+
lexer = "bash"
|
|
217
|
+
script = f"source {str(script_path)}"
|
|
218
|
+
else:
|
|
219
|
+
raise NotImplementedError(f"Platform {platform.system()} not supported.")
|
|
220
|
+
op_program_path = Path(op_program_path)
|
|
221
|
+
op_program_path.parent.mkdir(parents=True, exist_ok=True)
|
|
222
|
+
op_program_path.write_text(script, encoding="utf-8")
|
|
223
|
+
_ = suffix, lexer
|
|
224
|
+
console.print(f"[cyan]🚀 Handing over to shell script runner via OP_PROGRAM_PATH @ {str(op_program_path)}[/cyan]")
|
|
225
|
+
import sys
|
|
226
|
+
sys.exit(0)
|
|
@@ -32,15 +32,11 @@ class BoxStyles:
|
|
|
32
32
|
|
|
33
33
|
class CowStyles:
|
|
34
34
|
eyes = ['-b', '-d', '-g', '-h', '-l', '-L', '-n', '-N', '-p', '-s', '-t', '-w', '-y']
|
|
35
|
-
#
|
|
36
|
-
figures = ['
|
|
37
|
-
'dragon-and-cow', 'duck', 'elephant', 'elephant-in-snake', 'eyes', 'fox', 'ghostbusters',
|
|
38
|
-
'gnu', 'kangaroo', 'kiss', 'milk',
|
|
39
|
-
'moose', 'pony', 'pony-smaller', 'sheep', 'skeleton', 'snowman', 'stegosaurus', # 'suse',
|
|
40
|
-
'three-eyes', 'turkey', 'turtle', 'tux', 'unipony', 'unipony-smaller', 'vader', 'vader'] # 'hellokitty' 'mech-and-cow' # 'moofasa', 'stimpy', 'calvin', , 'ren', 'koala', 'flaming-sheep' , 'bud-frogs' , 'kosh' , 'luke-koala'
|
|
35
|
+
# Available characters from Python cowsay package (uv tool install cowsay)
|
|
36
|
+
figures = ['beavis', 'cheese', 'cow', 'daemon', 'dragon', 'fox', 'ghostbusters', 'kitty', 'meow', 'miki', 'milk', 'octopus', 'pig', 'stegosaurus', 'stimpy', 'trex', 'turkey', 'turtle', 'tux']
|
|
41
37
|
|
|
42
38
|
|
|
43
|
-
FIGLET_FONTS = ['
|
|
39
|
+
FIGLET_FONTS = ['Banner', 'Big', 'Standard']
|
|
44
40
|
|
|
45
41
|
FIGJS_FONTS = ['3D Diagonal', '3D-ASCII', '4Max', '5 Line Oblique', 'Acrobatic', 'ANSI Regular', 'ANSI Shadow',
|
|
46
42
|
'Avatar', 'Banner', 'Banner3-D', 'Banner4',
|
|
@@ -55,8 +51,8 @@ FIGJS_FONTS = ['3D Diagonal', '3D-ASCII', '4Max', '5 Line Oblique', 'Acrobatic',
|
|
|
55
51
|
|
|
56
52
|
def get_art(comment: Optional[str] = None, artlib: Optional[BOX_OR_CHAR] = None, style: Optional[str] = None, super_style: str = 'scene', prefix: str = ' ', file: Optional[str] = None, verbose: bool = True):
|
|
57
53
|
""" takes in a comment and does the following wrangling:
|
|
58
|
-
* text => figlet font => boxes =>
|
|
59
|
-
* text => cowsay =>
|
|
54
|
+
* text => figlet font => boxes => lolcatjs
|
|
55
|
+
* text => cowsay => lolcatjs
|
|
60
56
|
"""
|
|
61
57
|
if comment is None:
|
|
62
58
|
try:
|
|
@@ -68,10 +64,10 @@ def get_art(comment: Optional[str] = None, artlib: Optional[BOX_OR_CHAR] = None,
|
|
|
68
64
|
if artlib == 'boxes':
|
|
69
65
|
if style is None: style = random.choice(BoxStyles.__dict__[super_style or random.choice(['language', 'scene', 'character'])])
|
|
70
66
|
fonting = f'figlet -f {random.choice(FIGLET_FONTS)}'
|
|
71
|
-
cmd = f"""
|
|
67
|
+
cmd = f"""{fonting} "{comment}" | boxes -d {style} {to_file}"""
|
|
72
68
|
else:
|
|
73
69
|
if style is None: style = random.choice(CowStyles.figures)
|
|
74
|
-
cmd = f"""
|
|
70
|
+
cmd = f"""cowsay -c {style} -t "{comment}" {to_file}"""
|
|
75
71
|
try:
|
|
76
72
|
res = subprocess.run(cmd, text=True, capture_output=True, shell=True, check=True).stdout
|
|
77
73
|
except subprocess.CalledProcessError as ex:
|
|
@@ -91,7 +87,7 @@ def font_box_color(logo: str):
|
|
|
91
87
|
box_style = random.choice(['whirly', 'xes', 'columns', 'parchment', 'scroll', 'scroll-akn', 'diamonds', 'headline', 'nuke', 'spring', 'stark1'])
|
|
92
88
|
_cmd = f'figlet -f "{font}" "{logo}" | boxes -d "{box_style}" | lolcatjs'
|
|
93
89
|
# print(_cmd)
|
|
94
|
-
os.system(_cmd) # |
|
|
90
|
+
os.system(_cmd) # | lolcatjs
|
|
95
91
|
# print("after")
|
|
96
92
|
|
|
97
93
|
|
|
@@ -100,7 +96,7 @@ def character_color(logo: str):
|
|
|
100
96
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
|
|
101
97
|
f.write(ArtLib.cowsay(logo))
|
|
102
98
|
_new_art = f.name
|
|
103
|
-
os.system(f'type {_new_art} | lolcatjs') # |
|
|
99
|
+
os.system(f'type {_new_art} | lolcatjs') # | lolcatjs
|
|
104
100
|
|
|
105
101
|
|
|
106
102
|
def character_or_box_color(logo: str):
|
|
@@ -110,7 +106,7 @@ def character_or_box_color(logo: str):
|
|
|
110
106
|
get_art(logo, artlib=None, file=_new_art, verbose=False)
|
|
111
107
|
# Prefer bat on mac if available, fallback to cat
|
|
112
108
|
pager = "bat" if (platform.system() == "Darwin" and any((Path(p).joinpath("bat").exists() for p in os.environ.get("PATH", "").split(os.pathsep)))) else "cat"
|
|
113
|
-
command = f"{pager} {_new_art} |
|
|
109
|
+
command = f"{pager} {_new_art} | lolcatjs"
|
|
114
110
|
os.system(command)
|
|
115
111
|
|
|
116
112
|
|
|
@@ -46,7 +46,7 @@ def print_logo(logo: str):
|
|
|
46
46
|
elif platform.system() in ["Linux", "Darwin"]: # Explicitly handle both Linux and macOS
|
|
47
47
|
from machineconfig.utils.installer_utils.installer_locator_utils import is_executable_in_path
|
|
48
48
|
avail_cowsay = is_executable_in_path("cowsay")
|
|
49
|
-
avail_lolcat = is_executable_in_path("
|
|
49
|
+
avail_lolcat = is_executable_in_path("lolcatjs")
|
|
50
50
|
avail_boxes = is_executable_in_path("boxes")
|
|
51
51
|
avail_figlet = is_executable_in_path("figlet")
|
|
52
52
|
if avail_cowsay and avail_lolcat and avail_boxes and avail_figlet:
|
|
@@ -56,10 +56,8 @@ def print_logo(logo: str):
|
|
|
56
56
|
# print(Path(random.choice(glob.glob(str(Path(__file__).parent.joinpath("art", "*"))))).read_text())
|
|
57
57
|
character_or_box_color(logo=logo)
|
|
58
58
|
else:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
print(f"🔍 Missing ASCII art dependencies. Install with: {install_cmd}")
|
|
62
|
-
print("🚫 " + "-" * 70 + " 🚫\n")
|
|
59
|
+
install_cmd = "devops install --group term-eye-candy "
|
|
60
|
+
print(f"🔍 Missing ASCII art dependencies. Install with: {install_cmd} | {avail_boxes=} {avail_cowsay} {avail_figlet} {avail_lolcat=}")
|
|
63
61
|
_default_art = Path(random.choice(glob.glob(str(Path(__file__).parent.joinpath("art", "*")))))
|
|
64
62
|
print(_default_art.read_text())
|
|
65
63
|
else:
|
|
@@ -14,7 +14,11 @@ class Read:
|
|
|
14
14
|
if suffix in ("sqlite", "sqlite3", "db", "duckdb"):
|
|
15
15
|
from machineconfig.utils.files.dbms import DBMS
|
|
16
16
|
res = DBMS.from_local_db(path=path)
|
|
17
|
-
|
|
17
|
+
try:
|
|
18
|
+
print(res.describe_db())
|
|
19
|
+
except Exception:
|
|
20
|
+
print("💥 Could not describe the database.")
|
|
21
|
+
pass
|
|
18
22
|
return res
|
|
19
23
|
try: return getattr(Read, suffix)(str(path), **kwargs)
|
|
20
24
|
except AttributeError as err:
|
|
@@ -28,6 +32,9 @@ class Read:
|
|
|
28
32
|
elif suffix == "csv":
|
|
29
33
|
import polars as pl
|
|
30
34
|
return pl.read_csv(path, **kwargs)
|
|
35
|
+
elif suffix == "npz" or suffix == "npy":
|
|
36
|
+
import numpy as np
|
|
37
|
+
return np.load(str(path), **kwargs)
|
|
31
38
|
try:
|
|
32
39
|
# guess = install_n_import('magic', 'python-magic').from_file(path)
|
|
33
40
|
guess = "IDKm"
|
|
@@ -86,6 +86,7 @@ def fetch_github_release_data(
|
|
|
86
86
|
response = requests.get(url, timeout=30)
|
|
87
87
|
if response.status_code != 200:
|
|
88
88
|
print(f"❌ Failed to fetch data for {username}/{repo_name}: HTTP {response.status_code}")
|
|
89
|
+
print(f" URL: {url}")
|
|
89
90
|
return None
|
|
90
91
|
|
|
91
92
|
response_data = response.json()
|
|
@@ -150,7 +150,7 @@ def install_from_github_url(github_url: str) -> None:
|
|
|
150
150
|
size_padded = item["size_str"].ljust(max_size_len)
|
|
151
151
|
downloads_padded = item["downloads_str"].rjust(max_downloads_len)
|
|
152
152
|
|
|
153
|
-
label = f"{name_padded} {size_padded} |
|
|
153
|
+
label = f"{name_padded} {size_padded} | #🔽 {downloads_padded} | 📅 {item['date_str']}"
|
|
154
154
|
options_map[label] = item["asset"]
|
|
155
155
|
|
|
156
156
|
if not options_map:
|
|
@@ -13,6 +13,9 @@ import subprocess
|
|
|
13
13
|
from typing import Optional
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
PACAKGE_MANAGERS = ["bun", "npm", "pip", "uv", "winget", "powershell", "irm", "brew", "curl", "sudo"]
|
|
17
|
+
|
|
18
|
+
|
|
16
19
|
class Installer:
|
|
17
20
|
def __init__(self, installer_data: InstallerData):
|
|
18
21
|
self.installer_data: InstallerData = installer_data
|
|
@@ -62,8 +65,13 @@ class Installer:
|
|
|
62
65
|
if installer_arch_os is None:
|
|
63
66
|
raise ValueError(f"No installation pattern for {exe_name} on {os_name} {arch}")
|
|
64
67
|
version_to_be_installed: str = "unknown" # Initialize to ensure it's always bound
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
|
|
69
|
+
package_manager_installer = any(pm in installer_arch_os.split(" ") for pm in PACAKGE_MANAGERS)
|
|
70
|
+
script_installer = installer_arch_os.endswith((".sh", ".py", ".ps1"))
|
|
71
|
+
binary_download_link = installer_arch_os.startswith("https://") or installer_arch_os.startswith("http://")
|
|
72
|
+
|
|
73
|
+
if (repo_url == "CMD") or package_manager_installer or script_installer or binary_download_link:
|
|
74
|
+
if package_manager_installer:
|
|
67
75
|
from rich import print as rprint
|
|
68
76
|
from rich.panel import Panel
|
|
69
77
|
from rich.console import Group
|
|
@@ -81,7 +89,7 @@ class Installer:
|
|
|
81
89
|
sub_panels.append(Panel(result.stderr, title="STDERR", style="red"))
|
|
82
90
|
group_content = Group(f"❌ {desc} failed\nReturn code: {result.returncode}", *sub_panels)
|
|
83
91
|
rprint(Panel(group_content, title=desc, style="red"))
|
|
84
|
-
elif
|
|
92
|
+
elif script_installer:
|
|
85
93
|
import machineconfig.jobs.installer as module
|
|
86
94
|
from pathlib import Path
|
|
87
95
|
search_root = Path(module.__file__).parent
|
|
@@ -106,7 +114,7 @@ class Installer:
|
|
|
106
114
|
import runpy
|
|
107
115
|
runpy.run_path(str(installer_path), run_name=None)["main"](self.installer_data, version=version)
|
|
108
116
|
version_to_be_installed = str(version)
|
|
109
|
-
elif
|
|
117
|
+
elif binary_download_link:
|
|
110
118
|
downloaded_object = download_and_prepare(installer_arch_os)
|
|
111
119
|
if downloaded_object.suffix in [".exe", ""]: # likely an executable
|
|
112
120
|
if platform.system() == "Windows":
|
|
@@ -1,18 +1,5 @@
|
|
|
1
|
-
"""Devops Devapps Install
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
sudo apt update && sudo apt install -y \
|
|
5
|
-
git gcc g++ clang \
|
|
6
|
-
yasm nasm pkg-config \
|
|
7
|
-
meson ninja-build \
|
|
8
|
-
autoconf automake libtool \
|
|
9
|
-
libx11-dev libxext-dev libxrandr-dev libxrender-dev libxss-dev \
|
|
10
|
-
libvdpau-dev libgl1-mesa-dev libegl1-mesa-dev libxv-dev \
|
|
11
|
-
libasound2-dev libpulse-dev \
|
|
12
|
-
libfribidi-dev libfreetype-dev libfontconfig1-dev libharfbuzz-dev \
|
|
13
|
-
libjpeg-dev libssl-dev zlib1g-dev python3-pip
|
|
14
|
-
|
|
15
1
|
|
|
2
|
+
"""Devops Devapps Install
|
|
16
3
|
"""
|
|
17
4
|
|
|
18
5
|
from machineconfig.utils.installer_utils.installer_helper import get_group_name_to_repr
|
|
@@ -20,7 +7,6 @@ import typer
|
|
|
20
7
|
from typing import Annotated, Optional
|
|
21
8
|
|
|
22
9
|
|
|
23
|
-
|
|
24
10
|
def main_installer_cli(
|
|
25
11
|
which: Annotated[Optional[str], typer.Argument(..., help="Comma-separated list of program/groups names to install (if --group flag is set).")] = None,
|
|
26
12
|
group: Annotated[bool, typer.Option(..., "--group", "-g", help="Treat 'which' as a group name. A group is bundle of apps.")] = False,
|
|
@@ -104,7 +104,7 @@ def install_deb_package(downloaded: Path) -> None:
|
|
|
104
104
|
|
|
105
105
|
def download_and_prepare(download_url: str) -> PathExtended:
|
|
106
106
|
# archive_path = PathExtended(download_url).download(folder=INSTALL_TMP_DIR)
|
|
107
|
-
from machineconfig.scripts.python.helpers_utils.download import download
|
|
107
|
+
from machineconfig.scripts.python.helpers.helpers_utils.download import download
|
|
108
108
|
downloaded_object = download(download_url, output_dir=str(INSTALL_TMP_DIR))
|
|
109
109
|
if downloaded_object is None:
|
|
110
110
|
raise ValueError(f"Failed to download from URL: {download_url}")
|
|
@@ -121,7 +121,7 @@ def download_and_prepare(download_url: str) -> PathExtended:
|
|
|
121
121
|
if nested_path.is_file() and any(ex in nested_path.suffixes for ex in DECOMPRESS_SUPPORTED_FORMATS):
|
|
122
122
|
extracted_path = nested_path.decompress()
|
|
123
123
|
nested_path.delete(sure=True)
|
|
124
|
-
elif extracted_path.is_dir() and len(extracted_path.
|
|
124
|
+
elif extracted_path.is_dir() and len([p for p in extracted_path.rglob("*") if not p.name.startswith(".")]) == 1:
|
|
125
125
|
only_file_in = next(extracted_path.glob("*"))
|
|
126
126
|
if only_file_in.is_file() and any(ext in str(only_file_in) for ext in DECOMPRESS_SUPPORTED_FORMATS): # further decompress
|
|
127
127
|
extracted_path = only_file_in.decompress()
|
|
@@ -22,15 +22,15 @@ def find_move_delete_windows(downloaded_file_path: PathExtended, tool_name: Opti
|
|
|
22
22
|
else:
|
|
23
23
|
print(f"🔎 Searching for executable in: {downloaded_file_path}")
|
|
24
24
|
if tool_name is None:
|
|
25
|
-
exe = downloaded_file_path.
|
|
25
|
+
exe = list(downloaded_file_path.rglob("*.exe"))[0]
|
|
26
26
|
print(f"✅ Found executable: {exe}")
|
|
27
27
|
else:
|
|
28
|
-
tmp = downloaded_file_path.
|
|
28
|
+
tmp = list(downloaded_file_path.rglob(f"{tool_name}.exe"))
|
|
29
29
|
if len(tmp) == 1:
|
|
30
30
|
exe = tmp[0]
|
|
31
31
|
print(f"✅ Found exact match for {tool_name}.exe: {exe}")
|
|
32
32
|
else:
|
|
33
|
-
search_res = downloaded_file_path.
|
|
33
|
+
search_res = list(downloaded_file_path.rglob("*.exe"))
|
|
34
34
|
if len(search_res) == 0:
|
|
35
35
|
print(f"❌ ERROR: No executable found in {downloaded_file_path}")
|
|
36
36
|
raise IndexError(f"No executable found in {downloaded_file_path}")
|
|
@@ -38,8 +38,8 @@ def find_move_delete_windows(downloaded_file_path: PathExtended, tool_name: Opti
|
|
|
38
38
|
exe = search_res[0]
|
|
39
39
|
print(f"✅ Found single executable: {exe}")
|
|
40
40
|
else:
|
|
41
|
-
exe = max(search_res, key=lambda x: x.
|
|
42
|
-
print(f"✅ Selected largest executable ({exe.
|
|
41
|
+
exe = max(search_res, key=lambda x: x.stat().st_size)
|
|
42
|
+
print(f"✅ Selected largest executable ({round(exe.stat().st_size / 1024, 1)} KB): {exe}")
|
|
43
43
|
if rename_to and exe.name != rename_to:
|
|
44
44
|
print(f"🏷️ Renaming '{exe.name}' to '{rename_to}'")
|
|
45
45
|
exe = exe.with_name(name=rename_to, inplace=True)
|
|
@@ -70,20 +70,20 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: Optional[str], d
|
|
|
70
70
|
print(f"📄 Found direct executable file: {exe}")
|
|
71
71
|
else:
|
|
72
72
|
print(f"🔎 Searching for executable in: {downloaded}")
|
|
73
|
-
res = downloaded.
|
|
73
|
+
res = [p for p in downloaded.rglob(f"*{tool_name}*") if p.is_file()]
|
|
74
74
|
if len(res) == 1:
|
|
75
75
|
exe = res[0]
|
|
76
76
|
print(f"✅ Found match for pattern '*{tool_name}*': {exe}")
|
|
77
77
|
else:
|
|
78
78
|
if tool_name is None: # no tool name provided, get the largest executable
|
|
79
|
-
search_res = downloaded.
|
|
79
|
+
search_res = [p for p in downloaded.rglob("*") if p.is_file()]
|
|
80
80
|
if len(search_res) == 0:
|
|
81
81
|
print(f"❌ ERROR: No search results in `{downloaded}`")
|
|
82
82
|
raise IndexError(f"No executable found in {downloaded}")
|
|
83
|
-
exe = max(search_res, key=lambda x: x.
|
|
84
|
-
print(f"✅ Selected largest executable ({exe.
|
|
83
|
+
exe = max(search_res, key=lambda x: x.stat().st_size)
|
|
84
|
+
print(f"✅ Selected largest executable ({round(exe.stat().st_size / 1024, 1)} KB): {exe}")
|
|
85
85
|
else:
|
|
86
|
-
exe_search_res = downloaded.
|
|
86
|
+
exe_search_res = [p for p in downloaded.rglob(tool_name) if p.is_file()]
|
|
87
87
|
if len(exe_search_res) == 0:
|
|
88
88
|
print(f"❌ ERROR: No search results for `{tool_name}` in `{downloaded}`")
|
|
89
89
|
raise IndexError(f"No executable found in {downloaded}")
|
|
@@ -91,8 +91,8 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: Optional[str], d
|
|
|
91
91
|
exe = exe_search_res[0]
|
|
92
92
|
print(f"✅ Found exact match for '{tool_name}': {exe}")
|
|
93
93
|
else:
|
|
94
|
-
exe = max(exe_search_res, key=lambda x: x.
|
|
95
|
-
print(f"✅ Selected largest executable ({exe.
|
|
94
|
+
exe = max(exe_search_res, key=lambda x: x.stat().st_size)
|
|
95
|
+
print(f"✅ Selected largest executable ({round(exe.stat().st_size / 1024, 1)} KB): {exe}")
|
|
96
96
|
|
|
97
97
|
if rename_to and exe.name != rename_to:
|
|
98
98
|
print(f"🏷️ Renaming '{exe.name}' to '{rename_to}'")
|
|
@@ -155,7 +155,7 @@ def check_tool_exists(tool_name: str) -> bool:
|
|
|
155
155
|
version = result.stdout.strip().lstrip('v')
|
|
156
156
|
nvm_bin_path = Path.home() / ".nvm" / "versions" / "node" / f"v{version}" / "bin" / tool_name
|
|
157
157
|
npm_check = nvm_bin_path.is_file()
|
|
158
|
-
except subprocess.CalledProcessError:
|
|
158
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
159
159
|
pass
|
|
160
160
|
return npm_check
|
|
161
161
|
else:
|
|
@@ -75,18 +75,18 @@ def get_installed_cli_apps():
|
|
|
75
75
|
print("🔍 LISTING INSTALLED CLI APPS 🔍")
|
|
76
76
|
if platform.system() == "Windows":
|
|
77
77
|
print("🪟 Searching for Windows executables...")
|
|
78
|
-
apps = PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps").
|
|
78
|
+
apps = [p for p in PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps").glob("*.exe") if "notepad" not in str(p)]
|
|
79
79
|
elif platform.system() in ["Linux", "Darwin"]:
|
|
80
80
|
print(f"🐧 Searching for {platform.system()} executables...")
|
|
81
81
|
if platform.system() == "Linux":
|
|
82
|
-
apps = PathExtended(LINUX_INSTALL_PATH).
|
|
82
|
+
apps = list(PathExtended(LINUX_INSTALL_PATH).glob("*")) + list(PathExtended("/usr/local/bin").glob("*"))
|
|
83
83
|
else: # Darwin/macOS
|
|
84
|
-
apps = PathExtended("/usr/local/bin").
|
|
84
|
+
apps = list(PathExtended("/usr/local/bin").glob("*")) + list(PathExtended("/opt/homebrew/bin").glob("*"))
|
|
85
85
|
else:
|
|
86
86
|
error_msg = f"❌ ERROR: System {platform.system()} not supported"
|
|
87
87
|
print(error_msg)
|
|
88
88
|
raise NotImplementedError(error_msg)
|
|
89
|
-
apps = [app for app in apps if app.
|
|
89
|
+
apps = [app for app in apps if (app.stat().st_size / 1024) > 0.1 and not app.is_symlink()] # no symlinks like paint and wsl and bash
|
|
90
90
|
print(f"✅ Found {len(apps)} installed applications")
|
|
91
91
|
return apps
|
|
92
92
|
|
machineconfig/utils/meta.py
CHANGED
|
@@ -5,7 +5,7 @@ from typing import Any
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def get_import_module_string(py_file: str) -> str:
|
|
8
|
-
from machineconfig.scripts.python.helpers_fire_command.file_wrangler import get_import_module_code
|
|
8
|
+
from machineconfig.scripts.python.helpers.helpers_fire_command.file_wrangler import get_import_module_code
|
|
9
9
|
from machineconfig.utils.accessories import get_repo_root
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
repo_root = get_repo_root(Path(py_file))
|
|
@@ -68,7 +68,7 @@ def lambda_to_python_script(lmb: Callable[[], Any],
|
|
|
68
68
|
|
|
69
69
|
# sanity checks
|
|
70
70
|
if not (callable(lmb) and isinstance(lmb, _types.LambdaType)):
|
|
71
|
-
raise TypeError("Expected a lambda function object")
|
|
71
|
+
raise TypeError(f"Expected a lambda function object, got {type(lmb)}")
|
|
72
72
|
|
|
73
73
|
src = _inspect.getsource(lmb)
|
|
74
74
|
src = _textwrap.dedent(src)
|
|
@@ -81,7 +81,7 @@ def lambda_to_python_script(lmb: Callable[[], Any],
|
|
|
81
81
|
lambda_node = n
|
|
82
82
|
break
|
|
83
83
|
if lambda_node is None:
|
|
84
|
-
raise ValueError("Could not find a lambda expression in source")
|
|
84
|
+
raise ValueError(f"""Could not find a lambda expression in source, got:\n{lmb}\nwhich is not a lambda, its a {src}""")
|
|
85
85
|
|
|
86
86
|
body = lambda_node.body
|
|
87
87
|
if not isinstance(body, _ast.Call):
|
|
@@ -113,7 +113,7 @@ def lambda_to_python_script(lmb: Callable[[], Any],
|
|
|
113
113
|
if not callable(func_obj):
|
|
114
114
|
raise TypeError("Resolved object is not callable")
|
|
115
115
|
|
|
116
|
-
func_name = getattr(func_obj, "__name__", "<unknown>")
|
|
116
|
+
func_name = getattr(getattr(func_obj, "__code__", None), "co_name", None) or getattr(func_obj, "__name__", "<unknown>")
|
|
117
117
|
|
|
118
118
|
import_prefix: str = ""
|
|
119
119
|
if import_module:
|
|
@@ -249,8 +249,10 @@ def lambda_to_python_script(lmb: Callable[[], Any],
|
|
|
249
249
|
if __name__ == "__main__":
|
|
250
250
|
from machineconfig.utils.code import print_code
|
|
251
251
|
import_code_robust = "<import_code_robust>"
|
|
252
|
+
print_code.__name__ = "blah"
|
|
252
253
|
res = lambda_to_python_script(
|
|
253
254
|
lambda: print_code(code=import_code_robust, lexer="python", desc="import as module code"),
|
|
254
255
|
in_global=True, import_module=False
|
|
255
256
|
)
|
|
257
|
+
|
|
256
258
|
print(res)
|