machineconfig 5.15__py3-none-any.whl → 7.98__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.
- machineconfig/__init__.py +0 -28
- machineconfig/cluster/remote/cloud_manager.py +1 -1
- machineconfig/cluster/remote/distribute.py +0 -1
- machineconfig/cluster/remote/file_manager.py +0 -2
- machineconfig/cluster/remote/script_execution.py +0 -1
- machineconfig/cluster/sessions_managers/{utils → helpers}/enhanced_command_runner.py +4 -6
- machineconfig/cluster/sessions_managers/utils/load_balancer.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +69 -0
- machineconfig/cluster/sessions_managers/wt_local.py +114 -289
- machineconfig/cluster/sessions_managers/wt_local_manager.py +70 -210
- machineconfig/cluster/sessions_managers/wt_remote.py +51 -43
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +52 -198
- machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +6 -19
- machineconfig/cluster/sessions_managers/wt_utils/manager_persistence.py +52 -0
- machineconfig/cluster/sessions_managers/wt_utils/monitoring_helpers.py +50 -0
- machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +4 -2
- machineconfig/cluster/sessions_managers/wt_utils/status_reporting.py +76 -0
- machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
- machineconfig/cluster/sessions_managers/zellij_local.py +81 -375
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +25 -170
- machineconfig/cluster/sessions_managers/zellij_remote.py +40 -41
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +16 -12
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +4 -8
- machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +5 -20
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +3 -9
- machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +3 -1
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper.py +298 -0
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_restart.py +77 -0
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_helper_with_panes.py +228 -0
- machineconfig/cluster/sessions_managers/zellij_utils/zellij_local_manager_helper.py +165 -0
- machineconfig/jobs/{python → installer}/check_installations.py +2 -3
- machineconfig/jobs/installer/custom/boxes.py +61 -0
- machineconfig/jobs/installer/custom/hx.py +76 -19
- machineconfig/jobs/installer/custom/yazi.py +119 -0
- machineconfig/jobs/installer/custom_dev/alacritty.py +4 -4
- machineconfig/jobs/installer/custom_dev/brave.py +5 -9
- machineconfig/jobs/installer/custom_dev/cloudflare_warp_cli.py +23 -0
- machineconfig/jobs/installer/custom_dev/code.py +4 -1
- machineconfig/jobs/installer/custom_dev/dubdb_adbc.py +30 -0
- machineconfig/jobs/installer/custom_dev/nerdfont.py +1 -1
- machineconfig/jobs/installer/custom_dev/nerfont_windows_helper.py +33 -28
- machineconfig/jobs/installer/custom_dev/sysabc.py +139 -0
- machineconfig/jobs/installer/custom_dev/wezterm.py +2 -19
- machineconfig/jobs/installer/custom_dev/winget.py +10 -14
- machineconfig/jobs/installer/installer_data.json +1487 -229
- machineconfig/jobs/installer/linux_scripts/brave.sh +4 -14
- machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +5 -17
- machineconfig/jobs/installer/linux_scripts/docker.sh +5 -17
- machineconfig/jobs/installer/linux_scripts/docker_start.sh +6 -14
- machineconfig/jobs/installer/linux_scripts/edge.sh +3 -11
- machineconfig/jobs/{linux/msc → installer/linux_scripts}/lid.sh +2 -8
- machineconfig/jobs/installer/linux_scripts/nerdfont.sh +5 -17
- machineconfig/jobs/{linux/msc → installer/linux_scripts}/network.sh +2 -8
- machineconfig/jobs/installer/linux_scripts/q.sh +10 -6
- machineconfig/jobs/installer/linux_scripts/redis.sh +6 -17
- machineconfig/jobs/installer/linux_scripts/vscode.sh +5 -17
- machineconfig/jobs/installer/linux_scripts/wezterm.sh +4 -12
- machineconfig/jobs/installer/package_groups.py +106 -177
- machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
- machineconfig/logger.py +0 -1
- machineconfig/profile/backup.toml +49 -0
- machineconfig/profile/bash_shell_profiles.md +11 -0
- machineconfig/profile/create_helper.py +62 -0
- machineconfig/profile/create_links.py +288 -0
- machineconfig/profile/create_links_export.py +100 -0
- machineconfig/profile/create_shell_profile.py +147 -0
- machineconfig/profile/mapper.toml +263 -0
- machineconfig/scripts/__init__.py +0 -4
- machineconfig/scripts/linux/{share_cloud.sh → other/share_cloud.sh} +14 -25
- machineconfig/scripts/linux/wrap_mcfg +46 -0
- machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
- machineconfig/scripts/python/agents.py +123 -117
- machineconfig/scripts/python/ai/initai.py +3 -28
- machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
- machineconfig/scripts/python/ai/scripts/command_runner.sh +9 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +17 -18
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +17 -18
- machineconfig/scripts/python/ai/solutions/_shared.py +9 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Thinking-Beast-Mode.chatmode.md → agents/Thinking-Beast-Mode.agent.md} +0 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md → agents/Ultimate-Transparent-Thinking-Beast-Mode.agent.md} +0 -1
- machineconfig/scripts/python/ai/solutions/copilot/{chatmodes/deepResearch.chatmode.md → agents/deepResearch.agent.md} +2 -2
- machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +5 -5
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +5 -1
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
- machineconfig/scripts/python/ai/solutions/copilot/prompts/pyright_fix.md +16 -0
- machineconfig/scripts/python/ai/solutions/generic.py +28 -5
- machineconfig/scripts/python/ai/utils/generate_files.py +348 -0
- machineconfig/scripts/python/ai/utils/vscode_tasks.py +37 -0
- machineconfig/scripts/python/cloud.py +29 -0
- machineconfig/scripts/python/croshell.py +137 -113
- machineconfig/scripts/python/devops.py +61 -101
- machineconfig/scripts/python/devops_navigator.py +6 -0
- machineconfig/scripts/python/env_manager/__init__.py +1 -0
- machineconfig/scripts/python/env_manager/env_manager_tui.py +204 -0
- machineconfig/scripts/python/env_manager/path_manager_backend.py +47 -0
- machineconfig/scripts/python/env_manager/path_manager_tui.py +228 -0
- machineconfig/scripts/python/fire_jobs.py +110 -150
- machineconfig/scripts/python/ftpx.py +51 -24
- machineconfig/scripts/python/helpers/ast_search.py +74 -0
- machineconfig/scripts/python/helpers/qr_code.py +166 -0
- machineconfig/scripts/python/helpers/repo_rag.py +325 -0
- machineconfig/scripts/python/helpers/run_py_script.py +79 -0
- machineconfig/scripts/python/helpers/symantic_search.py +25 -0
- machineconfig/scripts/python/helpers/tmp_py_scripts/a.py +26 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.json +14 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_cursor_agents.py +22 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
- machineconfig/scripts/python/helpers_agents/fire_agents_help_launch.py +126 -0
- machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +41 -0
- machineconfig/scripts/python/helpers_agents/templates/prompt.txt +10 -0
- machineconfig/scripts/python/helpers_agents/templates/template.ps1 +14 -0
- machineconfig/scripts/python/helpers_agents/templates/template.sh +32 -0
- machineconfig/scripts/python/{cloud_copy.py → helpers_cloud/cloud_copy.py} +30 -23
- machineconfig/scripts/python/{cloud_mount.py → helpers_cloud/cloud_mount.py} +29 -35
- machineconfig/scripts/python/{cloud_sync.py → helpers_cloud/cloud_sync.py} +12 -18
- machineconfig/scripts/python/{helpers → helpers_cloud}/helpers2.py +1 -1
- machineconfig/scripts/python/helpers_croshell/crosh.py +39 -0
- machineconfig/scripts/python/{start_slidev.py → helpers_croshell/start_slidev.py} +8 -9
- machineconfig/scripts/python/helpers_devops/cli_config.py +105 -0
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +89 -0
- machineconfig/scripts/python/helpers_devops/cli_data.py +25 -0
- machineconfig/scripts/python/helpers_devops/cli_nw.py +214 -0
- machineconfig/scripts/python/helpers_devops/cli_repos.py +215 -0
- machineconfig/scripts/python/helpers_devops/cli_self.py +172 -0
- machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
- machineconfig/scripts/python/helpers_devops/cli_share_server.py +142 -0
- machineconfig/scripts/python/{share_terminal.py → helpers_devops/cli_share_terminal.py} +45 -35
- machineconfig/scripts/python/helpers_devops/cli_utils.py +96 -0
- machineconfig/scripts/python/{devops_backup_retrieve.py → helpers_devops/devops_backup_retrieve.py} +7 -10
- machineconfig/scripts/python/helpers_devops/devops_status.py +499 -0
- machineconfig/scripts/python/{devops_update_repos.py → helpers_devops/devops_update_repos.py} +68 -49
- machineconfig/scripts/python/helpers_devops/themes/choose_pwsh_theme.ps1 +81 -0
- machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +3 -0
- machineconfig/scripts/python/{choose_wezterm_theme.py → helpers_devops/themes/choose_wezterm_theme.py} +3 -3
- machineconfig/scripts/python/helpers_fire_command/__init__.py +0 -0
- machineconfig/scripts/python/helpers_fire_command/f.py +0 -0
- machineconfig/scripts/python/{helpers/helpers4.py → helpers_fire_command/file_wrangler.py} +56 -20
- machineconfig/scripts/python/{fire_jobs_args_helper.py → helpers_fire_command/fire_jobs_args_helper.py} +5 -1
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +121 -0
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_streamlit_helper.py +0 -0
- machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
- machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +3 -3
- machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
- machineconfig/scripts/python/helpers_navigator/__init__.py +20 -0
- machineconfig/scripts/python/helpers_navigator/command_builder.py +111 -0
- machineconfig/scripts/python/helpers_navigator/command_detail.py +44 -0
- machineconfig/scripts/python/helpers_navigator/command_tree.py +620 -0
- machineconfig/scripts/python/helpers_navigator/data_models.py +28 -0
- machineconfig/scripts/python/helpers_navigator/main_app.py +272 -0
- machineconfig/scripts/python/helpers_navigator/search_bar.py +15 -0
- machineconfig/scripts/python/helpers_network/__init__.py +0 -0
- machineconfig/scripts/python/helpers_network/address.py +132 -0
- machineconfig/scripts/python/{devops_add_identity.py → helpers_network/devops_add_identity.py} +0 -2
- machineconfig/scripts/python/helpers_network/devops_add_ssh_key.py +153 -0
- machineconfig/scripts/{linux → python/helpers_network}/mount_nfs +0 -1
- machineconfig/scripts/python/{mount_nfs.py → helpers_network/mount_nfs.py} +3 -3
- machineconfig/scripts/{linux → python/helpers_network}/mount_nw_drive +1 -2
- machineconfig/scripts/python/{mount_ssh.py → helpers_network/mount_ssh.py} +3 -3
- machineconfig/scripts/python/{onetimeshare.py → helpers_network/onetimeshare.py} +0 -1
- machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +391 -0
- machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +338 -0
- machineconfig/scripts/python/{wifi_conn.py → helpers_network/wifi_conn.py} +1 -53
- machineconfig/scripts/python/{wsl_windows_transfer.py → helpers_network/wsl_windows_transfer.py} +5 -4
- machineconfig/scripts/python/helpers_repos/action.py +209 -0
- machineconfig/scripts/python/helpers_repos/action_helper.py +150 -0
- machineconfig/scripts/python/{repos_helper_clone.py → helpers_repos/clone.py} +2 -3
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +218 -0
- machineconfig/scripts/python/{repos_helper.py → helpers_repos/entrypoint.py} +9 -17
- machineconfig/scripts/python/helpers_repos/grource.py +340 -0
- machineconfig/scripts/python/{repos_helper_record.py → helpers_repos/record.py} +4 -3
- machineconfig/scripts/python/helpers_repos/repo_analyzer_1.py +160 -0
- machineconfig/scripts/python/{count_lines.py → helpers_repos/repo_analyzer_2.py} +113 -192
- machineconfig/scripts/python/helpers_repos/sync.py +66 -0
- machineconfig/scripts/python/{repos_helper_update.py → helpers_repos/update.py} +3 -3
- machineconfig/scripts/python/helpers_sessions/__init__.py +0 -0
- machineconfig/scripts/python/helpers_sessions/sessions_multiprocess.py +65 -0
- machineconfig/scripts/python/helpers_utils/download.py +150 -0
- machineconfig/scripts/python/helpers_utils/path.py +185 -0
- machineconfig/scripts/python/interactive.py +64 -84
- machineconfig/scripts/python/mcfg_entry.py +58 -0
- machineconfig/scripts/python/msearch.py +71 -0
- machineconfig/scripts/python/sessions.py +119 -45
- machineconfig/scripts/python/terminal.py +133 -0
- machineconfig/scripts/python/utils.py +64 -0
- machineconfig/scripts/windows/mounts/Restore-ThunderbirdProfile.ps1 +92 -0
- machineconfig/scripts/windows/{mount_nfs.ps1 → mounts/mount_nfs.ps1} +1 -3
- machineconfig/scripts/windows/{mount_ssh.ps1 → mounts/mount_ssh.ps1} +1 -1
- machineconfig/scripts/windows/{share_smb.ps1 → mounts/share_smb.ps1} +0 -6
- machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
- machineconfig/settings/broot/br.sh +0 -4
- machineconfig/settings/broot/conf.toml +1 -1
- machineconfig/settings/helix/config.toml +16 -0
- machineconfig/settings/helix/languages.toml +13 -4
- machineconfig/settings/helix/yazi-picker.sh +12 -0
- machineconfig/settings/lf/linux/exe/lfcd.sh +1 -0
- machineconfig/settings/lf/linux/exe/previewer.sh +9 -3
- machineconfig/settings/lf/linux/lfrc +10 -12
- machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
- machineconfig/settings/lf/windows/lfrc +18 -38
- machineconfig/settings/lf/windows/mkfile.ps1 +1 -1
- machineconfig/settings/linters/.ruff.toml +1 -1
- machineconfig/settings/lvim/windows/archive/config_additional.lua +0 -6
- machineconfig/settings/marimo/marimo.toml +80 -0
- machineconfig/settings/marimo/snippets/globalize.py +34 -0
- machineconfig/settings/pistol/pistol.conf +1 -1
- machineconfig/settings/shells/bash/init.sh +82 -31
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
- machineconfig/settings/shells/nushell/config.nu +2 -35
- machineconfig/settings/shells/nushell/env.nu +45 -6
- machineconfig/settings/shells/nushell/init.nu +314 -0
- machineconfig/settings/shells/pwsh/init.ps1 +61 -43
- machineconfig/settings/shells/starship/starship.toml +16 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
- machineconfig/settings/shells/wt/settings.json +32 -17
- machineconfig/settings/shells/zsh/init.sh +89 -0
- machineconfig/settings/svim/linux/init.toml +0 -4
- machineconfig/settings/svim/windows/init.toml +0 -3
- machineconfig/settings/television/cable_unix/alias.toml +8 -0
- machineconfig/settings/television/cable_unix/aws-buckets.toml +14 -0
- machineconfig/settings/television/cable_unix/aws-instances.toml +13 -0
- machineconfig/settings/television/cable_unix/bash-history.toml +8 -0
- machineconfig/settings/television/cable_unix/channels.toml +19 -0
- machineconfig/settings/television/cable_unix/dirs.toml +13 -0
- machineconfig/settings/television/cable_unix/distrobox-list.toml +42 -0
- machineconfig/settings/television/cable_unix/docker-images.toml +13 -0
- machineconfig/settings/television/cable_unix/dotfiles.toml +11 -0
- machineconfig/settings/television/cable_unix/env.toml +17 -0
- machineconfig/settings/television/cable_unix/files.toml +11 -0
- machineconfig/settings/television/cable_unix/fish-history.toml +8 -0
- machineconfig/settings/television/cable_unix/git-branch.toml +11 -0
- machineconfig/settings/television/cable_unix/git-diff.toml +10 -0
- machineconfig/settings/television/cable_unix/git-log.toml +12 -0
- machineconfig/settings/television/cable_unix/git-reflog.toml +12 -0
- machineconfig/settings/television/cable_unix/git-repos.toml +16 -0
- machineconfig/settings/television/cable_unix/guix.toml +20 -0
- machineconfig/settings/television/cable_unix/just-recipes.toml +18 -0
- machineconfig/settings/television/cable_unix/k8s-deployments.toml +36 -0
- machineconfig/settings/television/cable_unix/k8s-pods.toml +50 -0
- machineconfig/settings/television/cable_unix/k8s-services.toml +36 -0
- machineconfig/settings/television/cable_unix/man-pages.toml +24 -0
- machineconfig/settings/television/cable_unix/nu-history.toml +7 -0
- machineconfig/settings/television/cable_unix/procs.toml +20 -0
- machineconfig/settings/television/cable_unix/text.toml +17 -0
- machineconfig/settings/television/cable_unix/tldr.toml +18 -0
- machineconfig/settings/television/cable_unix/zsh-history.toml +9 -0
- machineconfig/settings/television/cable_windows/alias.toml +7 -0
- machineconfig/settings/television/cable_windows/dirs.toml +13 -0
- machineconfig/settings/television/cable_windows/docker-images.toml +13 -0
- machineconfig/settings/television/cable_windows/dotfiles.toml +11 -0
- machineconfig/settings/television/cable_windows/env.toml +17 -0
- machineconfig/settings/television/cable_windows/files.toml +14 -0
- machineconfig/settings/television/cable_windows/git-branch.toml +11 -0
- machineconfig/settings/television/cable_windows/git-diff.toml +10 -0
- machineconfig/settings/television/cable_windows/git-log.toml +11 -0
- machineconfig/settings/television/cable_windows/git-reflog.toml +11 -0
- machineconfig/settings/television/cable_windows/git-repos.toml +15 -0
- machineconfig/settings/television/cable_windows/nu-history.toml +7 -0
- machineconfig/settings/television/cable_windows/pwsh-history.toml +6 -0
- machineconfig/settings/television/cable_windows/text.toml +17 -0
- machineconfig/settings/yazi/init.lua +61 -0
- machineconfig/settings/yazi/keymap_linux.toml +94 -0
- machineconfig/settings/yazi/keymap_windows.toml +78 -0
- machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
- machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
- machineconfig/settings/yazi/theme.toml +4 -0
- machineconfig/settings/yazi/yazi_linux.toml +84 -0
- machineconfig/settings/yazi/yazi_windows.toml +58 -0
- machineconfig/setup_linux/__init__.py +11 -0
- machineconfig/setup_linux/apps_desktop.sh +89 -0
- machineconfig/setup_linux/apps_gui.sh +64 -0
- machineconfig/setup_linux/ssh/openssh_all.sh +25 -0
- machineconfig/setup_linux/ssh/openssh_wsl.sh +38 -0
- machineconfig/setup_linux/uv.sh +15 -0
- machineconfig/setup_linux/web_shortcuts/interactive.sh +26 -6
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +31 -0
- machineconfig/setup_mac/__init__.py +16 -0
- machineconfig/setup_mac/apps_gui.sh +248 -0
- machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
- machineconfig/setup_mac/uv.sh +36 -0
- machineconfig/setup_windows/__init__.py +11 -0
- machineconfig/setup_windows/others/power_options.ps1 +7 -0
- machineconfig/setup_windows/ssh/add-sshkey.ps1 +29 -0
- machineconfig/setup_windows/ssh/add_identity.ps1 +11 -0
- machineconfig/setup_windows/ssh/openssh-server.ps1 +37 -0
- machineconfig/setup_windows/uv.ps1 +17 -0
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +27 -10
- machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +30 -0
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
- machineconfig/utils/accessories.py +7 -5
- machineconfig/utils/cloud/onedrive/README.md +139 -0
- machineconfig/utils/code.py +155 -105
- machineconfig/utils/files/art/fat_croco.txt +10 -0
- machineconfig/utils/files/art/halfwit_croco.txt +9 -0
- machineconfig/utils/files/art/happy_croco.txt +22 -0
- machineconfig/utils/files/art/water_croco.txt +11 -0
- machineconfig/utils/files/ascii_art.py +1 -1
- machineconfig/utils/files/dbms.py +257 -0
- machineconfig/utils/files/headers.py +11 -14
- machineconfig/utils/files/ouch/__init__.py +0 -0
- machineconfig/utils/files/ouch/decompress.py +45 -0
- machineconfig/utils/files/read.py +10 -18
- machineconfig/utils/installer_utils/github_release_bulk.py +156 -119
- machineconfig/utils/installer_utils/install_from_url.py +183 -0
- machineconfig/utils/installer_utils/installer_class.py +64 -181
- machineconfig/utils/installer_utils/installer_cli.py +175 -0
- machineconfig/utils/installer_utils/installer_helper.py +129 -0
- machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +66 -97
- machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +49 -82
- machineconfig/utils/io.py +77 -23
- machineconfig/utils/links.py +254 -162
- machineconfig/utils/meta.py +256 -0
- machineconfig/utils/notifications.py +1 -1
- machineconfig/utils/options.py +46 -18
- machineconfig/utils/options_tv.py +119 -0
- machineconfig/utils/path_extended.py +48 -101
- machineconfig/utils/path_helper.py +76 -23
- machineconfig/utils/procs.py +50 -70
- machineconfig/utils/scheduler.py +88 -124
- machineconfig/utils/scheduling.py +0 -3
- machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
- machineconfig/utils/schemas/layouts/layout_types.py +1 -1
- machineconfig/utils/source_of_truth.py +3 -6
- machineconfig/utils/ssh.py +263 -274
- machineconfig/utils/ssh_utils/abc.py +5 -0
- machineconfig/utils/ssh_utils/copy_from_here.py +111 -0
- machineconfig/utils/ssh_utils/copy_to_here.py +302 -0
- machineconfig/utils/ssh_utils/utils.py +142 -0
- machineconfig/utils/ssh_utils/wsl.py +210 -0
- machineconfig/utils/terminal.py +3 -113
- machineconfig/utils/tst.py +20 -0
- machineconfig/utils/upgrade_packages.py +114 -28
- machineconfig/utils/ve.py +12 -4
- machineconfig-7.98.dist-info/METADATA +132 -0
- machineconfig-7.98.dist-info/RECORD +504 -0
- machineconfig-7.98.dist-info/entry_points.txt +13 -0
- machineconfig/cluster/sessions_managers/ffile.py +0 -4
- machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -49
- machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -85
- machineconfig/jobs/linux/msc/cli_agents.sh +0 -16
- machineconfig/jobs/python/python_ve_symlink.py +0 -37
- machineconfig/jobs/python/vscode/api.py +0 -57
- machineconfig/jobs/python/vscode/sync_code.py +0 -73
- machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +0 -14
- machineconfig/jobs/windows/start_terminal.ps1 +0 -6
- machineconfig/jobs/windows/startup_file.cmd +0 -2
- machineconfig/profile/create.py +0 -303
- machineconfig/profile/shell.py +0 -176
- machineconfig/scripts/cloud/init.sh +0 -119
- machineconfig/scripts/linux/agents +0 -2
- machineconfig/scripts/linux/choose_wezterm_theme +0 -3
- machineconfig/scripts/linux/cloud_copy +0 -2
- machineconfig/scripts/linux/cloud_mount +0 -2
- machineconfig/scripts/linux/cloud_repo_sync +0 -2
- machineconfig/scripts/linux/cloud_sync +0 -2
- machineconfig/scripts/linux/croshell +0 -3
- machineconfig/scripts/linux/devops +0 -2
- machineconfig/scripts/linux/fire +0 -2
- machineconfig/scripts/linux/ftpx +0 -2
- machineconfig/scripts/linux/fzf2g +0 -21
- machineconfig/scripts/linux/fzfag +0 -17
- machineconfig/scripts/linux/fzffg +0 -25
- machineconfig/scripts/linux/fzfrga +0 -21
- machineconfig/scripts/linux/gh_models +0 -2
- machineconfig/scripts/linux/initai +0 -2
- machineconfig/scripts/linux/kill_process +0 -2
- machineconfig/scripts/linux/scheduler +0 -2
- machineconfig/scripts/linux/sessions +0 -2
- machineconfig/scripts/linux/share_smb +0 -1
- machineconfig/scripts/linux/skrg +0 -4
- machineconfig/scripts/linux/start_slidev +0 -2
- machineconfig/scripts/linux/start_terminals +0 -3
- machineconfig/scripts/linux/warp-cli.sh +0 -122
- machineconfig/scripts/linux/wifi_conn +0 -2
- machineconfig/scripts/linux/z_ls +0 -104
- machineconfig/scripts/python/ai/generate_files.py +0 -83
- machineconfig/scripts/python/ai/solutions/copilot/prompts/allLintersAndTypeCheckers.prompt.md +0 -5
- machineconfig/scripts/python/cloud_repo_sync.py +0 -190
- machineconfig/scripts/python/count_lines_frontend.py +0 -16
- machineconfig/scripts/python/devops_add_ssh_key.py +0 -120
- machineconfig/scripts/python/dotfile.py +0 -78
- machineconfig/scripts/python/fire_agents_help_launch.py +0 -120
- machineconfig/scripts/python/fire_agents_helper_types.py +0 -12
- machineconfig/scripts/python/fire_jobs_route_helper.py +0 -65
- machineconfig/scripts/python/get_zellij_cmd.py +0 -15
- machineconfig/scripts/python/gh_models.py +0 -104
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +0 -116
- machineconfig/scripts/python/repos.py +0 -132
- machineconfig/scripts/python/repos_helper_action.py +0 -378
- machineconfig/scripts/python/snapshot.py +0 -25
- machineconfig/scripts/python/start_terminals.py +0 -121
- machineconfig/scripts/python/t4.py +0 -17
- machineconfig/scripts/windows/agents.ps1 +0 -1
- machineconfig/scripts/windows/choose_wezterm_theme.ps1 +0 -1
- machineconfig/scripts/windows/cloud_copy.ps1 +0 -1
- machineconfig/scripts/windows/cloud_mount.ps1 +0 -1
- machineconfig/scripts/windows/cloud_repo_sync.ps1 +0 -1
- machineconfig/scripts/windows/cloud_sync.ps1 +0 -1
- machineconfig/scripts/windows/croshell.ps1 +0 -1
- machineconfig/scripts/windows/devops.ps1 +0 -1
- machineconfig/scripts/windows/dotfile.ps1 +0 -1
- machineconfig/scripts/windows/fire.ps1 +0 -1
- machineconfig/scripts/windows/ftpx.ps1 +0 -1
- machineconfig/scripts/windows/fzfb.ps1 +0 -3
- machineconfig/scripts/windows/fzfg.ps1 +0 -2
- machineconfig/scripts/windows/fzfrga.bat +0 -20
- machineconfig/scripts/windows/gpt.ps1 +0 -1
- machineconfig/scripts/windows/grep.ps1 +0 -2
- machineconfig/scripts/windows/initai.ps1 +0 -1
- machineconfig/scripts/windows/kill_process.ps1 +0 -1
- machineconfig/scripts/windows/nano.ps1 +0 -3
- machineconfig/scripts/windows/pomodoro.ps1 +0 -1
- machineconfig/scripts/windows/reload_path.ps1 +0 -3
- machineconfig/scripts/windows/scheduler.ps1 +0 -1
- machineconfig/scripts/windows/sessions.ps1 +0 -1
- machineconfig/scripts/windows/snapshot.ps1 +0 -1
- machineconfig/scripts/windows/start_slidev.ps1 +0 -1
- machineconfig/scripts/windows/start_terminals.ps1 +0 -1
- machineconfig/scripts/windows/wifi_conn.ps1 +0 -2
- machineconfig/scripts/windows/wsl_rdp_windows_port_forwarding.ps1 +0 -46
- machineconfig/scripts/windows/wsl_ssh_windows_port_forwarding.ps1 +0 -76
- machineconfig/settings/lf/linux/exe/fzf_nano.sh +0 -16
- machineconfig/settings/lf/windows/fzf_edit.ps1 +0 -6
- machineconfig/settings/lf/windows/tst.ps1 +0 -1
- machineconfig/settings/yazi/yazi.toml +0 -4
- machineconfig/setup_linux/nix/cli_installation.sh +0 -157
- machineconfig/setup_linux/others/openssh-server_add_pub_key.sh +0 -57
- machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -11
- machineconfig/setup_linux/web_shortcuts/ssh.sh +0 -52
- machineconfig/setup_windows/web_shortcuts/all.ps1 +0 -18
- machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +0 -36
- machineconfig/setup_windows/web_shortcuts/croshell.ps1 +0 -16
- machineconfig/setup_windows/web_shortcuts/ssh.ps1 +0 -11
- machineconfig/utils/ai/generate_file_checklist.py +0 -68
- machineconfig/utils/installer_utils/installer.py +0 -189
- machineconfig-5.15.dist-info/METADATA +0 -188
- machineconfig-5.15.dist-info/RECORD +0 -415
- machineconfig-5.15.dist-info/entry_points.txt +0 -18
- machineconfig/cluster/sessions_managers/{utils → helpers}/load_balancer_helper.py +0 -0
- machineconfig/scripts/linux/{share_nfs → other/share_nfs} +0 -0
- machineconfig/scripts/linux/{start_docker → other/start_docker} +0 -0
- machineconfig/scripts/linux/{switch_ip → other/switch_ip} +0 -0
- machineconfig/{jobs/python → scripts/python/ai/utils}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers → helpers_agents}/__init__.py +0 -0
- machineconfig/{jobs/windows/msc/cli_agents.bat → scripts/python/helpers_agents/agentic_frameworks/__init__.py} +0 -0
- machineconfig/scripts/python/{fire_agents_help_search.py → helpers_agents/fire_agents_help_search.py} +0 -0
- machineconfig/scripts/python/{fire_agents_load_balancer.py → helpers_agents/fire_agents_load_balancer.py} +0 -0
- machineconfig/{jobs/windows/msc/cli_agents.ps1 → scripts/python/helpers_cloud/__init__.py} +0 -0
- machineconfig/scripts/python/{helpers → helpers_cloud}/cloud_helpers.py +1 -1
- /machineconfig/scripts/python/{helpers → helpers_cloud}/helpers5.py +0 -0
- /machineconfig/scripts/python/{fire_jobs_streamlit_helper.py → helpers_croshell/__init__.py} +0 -0
- /machineconfig/scripts/python/{pomodoro.py → helpers_croshell/pomodoro.py} +0 -0
- /machineconfig/scripts/python/{scheduler.py → helpers_croshell/scheduler.py} +0 -0
- /machineconfig/scripts/python/{viewer.py → helpers_croshell/viewer.py} +0 -0
- /machineconfig/scripts/python/{viewer_template.py → helpers_croshell/viewer_template.py} +0 -0
- /machineconfig/scripts/{windows/share_nfs.ps1 → python/helpers_devops/__init__.py} +0 -0
- /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers_devops/themes/__init__.py} +0 -0
- /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers_devops/themes/choose_starship_theme.ps1} +0 -0
- /machineconfig/scripts/python/{cloud_manager.py → helpers_fire_command/cloud_manager.py} +0 -0
- /machineconfig/scripts/{linux → python/helpers_network}/mount_drive +0 -0
- /machineconfig/scripts/python/{mount_nw_drive.py → helpers_network/mount_nw_drive.py} +0 -0
- /machineconfig/scripts/{linux → python/helpers_network}/mount_smb +0 -0
- /machineconfig/scripts/windows/{mount_nw.ps1 → mounts/mount_nw.ps1} +0 -0
- /machineconfig/scripts/windows/{mount_smb.ps1 → mounts/mount_smb.ps1} +0 -0
- /machineconfig/scripts/windows/{share_cloud.cmd → mounts/share_cloud.cmd} +0 -0
- /machineconfig/scripts/windows/{unlock_bitlocker.ps1 → mounts/unlock_bitlocker.ps1} +0 -0
- /machineconfig/setup_linux/{web_shortcuts → others}/android.sh +0 -0
- /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_add_key.ps1 +0 -0
- /machineconfig/{jobs/windows/archive → setup_windows/ssh}/openssh-server_copy-ssh-id.ps1 +0 -0
- {machineconfig-5.15.dist-info → machineconfig-7.98.dist-info}/WHEEL +0 -0
- {machineconfig-5.15.dist-info → machineconfig-7.98.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,175 @@
|
|
|
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
|
+
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from machineconfig.utils.installer_utils.installer_helper import get_group_name_to_repr
|
|
19
|
+
import typer
|
|
20
|
+
from typing import Annotated, Optional
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def main_installer_cli(
|
|
25
|
+
which: Annotated[Optional[str], typer.Argument(..., help="Comma-separated list of program/groups names to install (if --group flag is set).")] = None,
|
|
26
|
+
group: Annotated[bool, typer.Option(..., "--group", "-g", help="Treat 'which' as a group name. A group is bundle of apps.")] = False,
|
|
27
|
+
interactive: Annotated[bool, typer.Option(..., "--interactive", "-i", help="Interactive selection of programs to install.")] = False,
|
|
28
|
+
) -> None:
|
|
29
|
+
if interactive:
|
|
30
|
+
return install_interactively()
|
|
31
|
+
if which is not None:
|
|
32
|
+
if group:
|
|
33
|
+
for a_group in [x.strip() for x in which.split(",") if x.strip() != ""]:
|
|
34
|
+
return install_group(package_group=a_group)
|
|
35
|
+
else:
|
|
36
|
+
return install_clis(clis_names=[x.strip() for x in which.split(",") if x.strip() != ""])
|
|
37
|
+
else:
|
|
38
|
+
if group:
|
|
39
|
+
from rich.console import Console
|
|
40
|
+
from rich.table import Table
|
|
41
|
+
console = Console()
|
|
42
|
+
|
|
43
|
+
typer.echo("❌ You must provide a group name when using the --group/-g option.")
|
|
44
|
+
from machineconfig.utils.installer_utils.installer_helper import get_group_name_to_repr
|
|
45
|
+
res = get_group_name_to_repr()
|
|
46
|
+
console.print("[bold blue]Here are the available groups:[/bold blue]")
|
|
47
|
+
table = Table(show_header=True, header_style="bold magenta")
|
|
48
|
+
table.add_column("Group", style="cyan", no_wrap=True)
|
|
49
|
+
table.add_column("AppsBundled", style="green", overflow="fold")
|
|
50
|
+
for display, group_name in res.items():
|
|
51
|
+
# Parse display
|
|
52
|
+
if " -- " in display:
|
|
53
|
+
group_part, items_part = display.split(" -- ", 1)
|
|
54
|
+
group_name_parsed = group_part.replace("📦 ", "").strip()
|
|
55
|
+
items_str = items_part.strip()
|
|
56
|
+
else:
|
|
57
|
+
group_name_parsed = display
|
|
58
|
+
items_str = group_name
|
|
59
|
+
table.add_row(group_name_parsed, items_str)
|
|
60
|
+
console.print(table)
|
|
61
|
+
raise typer.Exit(1)
|
|
62
|
+
typer.echo("❌ You must provide either a program name/group name, or use --interactive/-ia option.")
|
|
63
|
+
import click
|
|
64
|
+
ctx = click.get_current_context()
|
|
65
|
+
typer.echo(ctx.get_help())
|
|
66
|
+
raise typer.Exit(1)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def install_interactively():
|
|
73
|
+
from machineconfig.utils.options import choose_from_options
|
|
74
|
+
from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
|
|
75
|
+
from machineconfig.utils.installer_utils.installer_runner import get_installers
|
|
76
|
+
from machineconfig.utils.installer_utils.installer_class import Installer
|
|
77
|
+
from rich.console import Console
|
|
78
|
+
from rich.panel import Panel
|
|
79
|
+
# from rich.table import Table
|
|
80
|
+
installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=None)
|
|
81
|
+
installer_options = [Installer(installer_data=x).get_description() for x in installers]
|
|
82
|
+
category_display_to_name = get_group_name_to_repr()
|
|
83
|
+
options = list(category_display_to_name.keys()) + installer_options
|
|
84
|
+
program_names = choose_from_options(multi=True, msg="Categories are prefixed with 📦", options=options, header="🚀 CHOOSE DEV APP OR CATEGORY", tv=True)
|
|
85
|
+
installation_messages: list[str] = []
|
|
86
|
+
for _an_idx, a_program_name in enumerate(program_names):
|
|
87
|
+
if a_program_name.startswith("📦 "):
|
|
88
|
+
category_name = category_display_to_name.get(a_program_name)
|
|
89
|
+
if category_name:
|
|
90
|
+
install_group(package_group=category_name)
|
|
91
|
+
else:
|
|
92
|
+
installer_idx = installer_options.index(a_program_name)
|
|
93
|
+
an_installer_data = installers[installer_idx]
|
|
94
|
+
status_message = Installer(an_installer_data).install_robust(version=None) # finish the task - this returns a status message, not a command
|
|
95
|
+
installation_messages.append(status_message)
|
|
96
|
+
if installation_messages:
|
|
97
|
+
console = Console()
|
|
98
|
+
|
|
99
|
+
panel = Panel("\n".join([f"[blue]• {message}[/blue]" for message in installation_messages]), title="[bold green]📊 Installation Summary[/bold green]", border_style="green", padding=(1, 2))
|
|
100
|
+
console.print(panel)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def install_group(package_group: str):
|
|
104
|
+
from machineconfig.utils.installer_utils.installer_runner import get_installers, install_bulk
|
|
105
|
+
from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
|
|
106
|
+
from rich.console import Console
|
|
107
|
+
from rich.panel import Panel
|
|
108
|
+
# from rich.table import Table
|
|
109
|
+
from machineconfig.jobs.installer.package_groups import PACKAGE_GROUP2NAMES
|
|
110
|
+
if package_group in PACKAGE_GROUP2NAMES:
|
|
111
|
+
panel = Panel(f"[bold yellow]Installing programs from category: [green]{package_group}[/green][/bold yellow]", title="[bold blue]📦 Category Installation[/bold blue]", border_style="blue", padding=(1, 2))
|
|
112
|
+
console = Console()
|
|
113
|
+
console.print(panel)
|
|
114
|
+
installers_ = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=[package_group])
|
|
115
|
+
install_bulk(installers_data=installers_)
|
|
116
|
+
return
|
|
117
|
+
console = Console()
|
|
118
|
+
console.print(f"❌ ERROR: Unknown package group: {package_group}. Available groups are: {list(PACKAGE_GROUP2NAMES.keys())}")
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def install_clis(clis_names: list[str]):
|
|
122
|
+
from machineconfig.utils.schemas.installer.installer_types import get_normalized_arch, get_os_name
|
|
123
|
+
from machineconfig.utils.installer_utils.installer_runner import get_installers
|
|
124
|
+
from machineconfig.utils.installer_utils.installer_class import Installer
|
|
125
|
+
from rich.console import Console
|
|
126
|
+
all_installers_data = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=None)
|
|
127
|
+
total_messages: list[str] = []
|
|
128
|
+
for a_cli_name in clis_names:
|
|
129
|
+
if "github.com" in a_cli_name.lower():
|
|
130
|
+
from machineconfig.utils.installer_utils.install_from_url import install_from_github_url
|
|
131
|
+
install_from_github_url(github_url=a_cli_name)
|
|
132
|
+
continue
|
|
133
|
+
elif a_cli_name.startswith("https://") or a_cli_name.startswith("http://"):
|
|
134
|
+
print(f"⏳ Installing from binary URL: {a_cli_name} ...")
|
|
135
|
+
from machineconfig.utils.installer_utils.install_from_url import install_from_binary_url
|
|
136
|
+
install_from_binary_url(binary_url=a_cli_name)
|
|
137
|
+
continue
|
|
138
|
+
selected_installer = None
|
|
139
|
+
for installer in all_installers_data:
|
|
140
|
+
app_name = installer["appName"]
|
|
141
|
+
if app_name.lower() == a_cli_name.lower():
|
|
142
|
+
selected_installer = installer
|
|
143
|
+
break
|
|
144
|
+
if selected_installer is None:
|
|
145
|
+
from machineconfig.utils.installer_utils.installer_helper import handle_installer_not_found
|
|
146
|
+
handle_installer_not_found(a_cli_name, all_installers_data)
|
|
147
|
+
return None
|
|
148
|
+
message = Installer(selected_installer).install_robust(version=None) # finish the task
|
|
149
|
+
total_messages.append(message)
|
|
150
|
+
if total_messages:
|
|
151
|
+
console = Console()
|
|
152
|
+
console.print("\n[bold green]📊 Installation Results:[/bold green]")
|
|
153
|
+
for a_message in total_messages:
|
|
154
|
+
console.print(f"[blue]• {a_message}[/blue]")
|
|
155
|
+
return None
|
|
156
|
+
def install_if_missing(which: str) -> bool:
|
|
157
|
+
from machineconfig.utils.installer_utils.installer_locator_utils import check_tool_exists
|
|
158
|
+
exists = check_tool_exists(which)
|
|
159
|
+
if exists:
|
|
160
|
+
print(f"✅ {which} is already installed.")
|
|
161
|
+
return True
|
|
162
|
+
print(f"⏳ {which} not found. Installing...")
|
|
163
|
+
from machineconfig.utils.installer_utils.installer_cli import main_installer_cli
|
|
164
|
+
try:
|
|
165
|
+
main_installer_cli(which=which, interactive=False)
|
|
166
|
+
return True
|
|
167
|
+
except Exception as e:
|
|
168
|
+
print(f"❌ Error installing {which}: {e}")
|
|
169
|
+
return False
|
|
170
|
+
|
|
171
|
+
if __name__ == "__main__":
|
|
172
|
+
from machineconfig.utils.schemas.installer.installer_types import InstallerData
|
|
173
|
+
from machineconfig.utils.installer_utils.installer_class import Installer
|
|
174
|
+
_ = InstallerData, Installer
|
|
175
|
+
pass
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
from machineconfig.jobs.installer.package_groups import PACKAGE_GROUP2NAMES
|
|
2
|
+
from machineconfig.utils.schemas.installer.installer_types import InstallerData
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from machineconfig.utils.path_extended import DECOMPRESS_SUPPORTED_FORMATS, PathExtended
|
|
5
|
+
from machineconfig.utils.source_of_truth import INSTALL_TMP_DIR
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_group_name_to_repr() -> dict[str, str]:
|
|
9
|
+
# Build category options and maintain a mapping from display text to actual category name
|
|
10
|
+
category_display_to_name: dict[str, str] = {}
|
|
11
|
+
for group_name, group_values in PACKAGE_GROUP2NAMES.items():
|
|
12
|
+
display = f"📦 {group_name:<20}" + " -- " + f"{'|'.join(group_values):<60}"
|
|
13
|
+
category_display_to_name[display] = group_name
|
|
14
|
+
return category_display_to_name
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def handle_installer_not_found(search_term: str, app_apps: list[InstallerData]) -> None: # type: ignore
|
|
18
|
+
"""Handle installer not found with friendly suggestions using fuzzy matching."""
|
|
19
|
+
from difflib import get_close_matches
|
|
20
|
+
from rich.console import Console
|
|
21
|
+
from rich.panel import Panel
|
|
22
|
+
from rich.table import Table
|
|
23
|
+
all_names = sorted([inst["appName"] for inst in app_apps])
|
|
24
|
+
name_to_doc = {inst["appName"]: inst["doc"] for inst in app_apps}
|
|
25
|
+
all_descriptions = {f"{inst['appName']}: {inst['doc']}": inst["appName"] for inst in app_apps}
|
|
26
|
+
|
|
27
|
+
close_name_matches = get_close_matches(search_term, all_names, n=5, cutoff=0.4)
|
|
28
|
+
close_description_matches = get_close_matches(search_term, list(all_descriptions.keys()), n=5, cutoff=0.4)
|
|
29
|
+
|
|
30
|
+
search_lower = search_term.lower()
|
|
31
|
+
substring_matches = [
|
|
32
|
+
inst["appName"]
|
|
33
|
+
for inst in app_apps
|
|
34
|
+
if search_lower in inst["appName"].lower() or search_lower in inst["doc"].lower()
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
ordered_matches: list[str] = list(
|
|
38
|
+
dict.fromkeys(
|
|
39
|
+
close_name_matches
|
|
40
|
+
+ [all_descriptions[desc] for desc in close_description_matches]
|
|
41
|
+
+ substring_matches
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
top_matches = ordered_matches[:10]
|
|
45
|
+
console = Console()
|
|
46
|
+
|
|
47
|
+
console.print(f"\n❌ '[red]{search_term}[/red]' was not found.", style="bold")
|
|
48
|
+
if top_matches:
|
|
49
|
+
console.print("🤔 Did you mean one of these?", style="yellow")
|
|
50
|
+
table = Table(show_header=True, header_style="bold", box=None, pad_edge=False)
|
|
51
|
+
table.add_column("#", justify="right", width=3)
|
|
52
|
+
table.add_column("Installer", style="green")
|
|
53
|
+
table.add_column("Description", style="dim", overflow="fold")
|
|
54
|
+
for i, match in enumerate(top_matches, 1):
|
|
55
|
+
table.add_row(f"[cyan]{i}[/cyan]", match, name_to_doc.get(match, ""))
|
|
56
|
+
console.print(table)
|
|
57
|
+
else:
|
|
58
|
+
console.print("📋 Here are some available options:", style="blue")
|
|
59
|
+
# Show first 10 installers as examples
|
|
60
|
+
if len(all_names) > 10:
|
|
61
|
+
sample_names = all_names[:10]
|
|
62
|
+
else:
|
|
63
|
+
sample_names = all_names
|
|
64
|
+
table = Table(show_header=True, header_style="bold", box=None, pad_edge=False)
|
|
65
|
+
table.add_column("#", justify="right", width=3)
|
|
66
|
+
table.add_column("Installer", style="green")
|
|
67
|
+
table.add_column("Description", style="dim", overflow="fold")
|
|
68
|
+
for i, name in enumerate(sample_names, 1):
|
|
69
|
+
table.add_row(f"[cyan]{i}[/cyan]", name, name_to_doc.get(name, ""))
|
|
70
|
+
console.print(table)
|
|
71
|
+
if len(all_names) > 10:
|
|
72
|
+
console.print(f" [dim]... and {len(all_names) - 10} more[/dim]")
|
|
73
|
+
|
|
74
|
+
panel = Panel(f"[bold blue]💡 Use 'ia' to interactively browse all available installers.[/bold blue]\n[bold blue]💡 Use one of the categories: {list(PACKAGE_GROUP2NAMES.keys())}[/bold blue]", title="[yellow]Helpful Tips[/yellow]", border_style="yellow")
|
|
75
|
+
console.print(panel)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def install_deb_package(downloaded: Path) -> None:
|
|
79
|
+
from rich import print as rprint
|
|
80
|
+
from rich.panel import Panel
|
|
81
|
+
print(f"📦 Installing .deb package: {downloaded}")
|
|
82
|
+
import platform
|
|
83
|
+
import subprocess
|
|
84
|
+
assert platform.system() == "Linux"
|
|
85
|
+
result = subprocess.run(f"sudo nala install -y {downloaded}", shell=True, capture_output=True, text=True)
|
|
86
|
+
success = result.returncode == 0 and result.stderr == ""
|
|
87
|
+
if not success:
|
|
88
|
+
from rich.console import Group
|
|
89
|
+
desc = "Installing .deb"
|
|
90
|
+
sub_panels = []
|
|
91
|
+
if result.stdout:
|
|
92
|
+
sub_panels.append(Panel(result.stdout, title="STDOUT", style="blue"))
|
|
93
|
+
if result.stderr:
|
|
94
|
+
sub_panels.append(Panel(result.stderr, title="STDERR", style="red"))
|
|
95
|
+
group_content = Group(f"❌ {desc} failed\nReturn code: {result.returncode}", *sub_panels)
|
|
96
|
+
rprint(Panel(group_content, title=desc, style="red"))
|
|
97
|
+
print("🗑️ Cleaning up .deb package...")
|
|
98
|
+
if downloaded.is_file():
|
|
99
|
+
downloaded.unlink(missing_ok=True)
|
|
100
|
+
elif downloaded.is_dir():
|
|
101
|
+
import shutil
|
|
102
|
+
shutil.rmtree(downloaded, ignore_errors=True)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def download_and_prepare(download_url: str) -> PathExtended:
|
|
106
|
+
# archive_path = PathExtended(download_url).download(folder=INSTALL_TMP_DIR)
|
|
107
|
+
from machineconfig.scripts.python.helpers_utils.download import download
|
|
108
|
+
downloaded_object = download(download_url, output_dir=str(INSTALL_TMP_DIR))
|
|
109
|
+
if downloaded_object is None:
|
|
110
|
+
raise ValueError(f"Failed to download from URL: {download_url}")
|
|
111
|
+
archive_path = PathExtended(downloaded_object)
|
|
112
|
+
extracted_path = archive_path
|
|
113
|
+
if extracted_path.is_file() and any(ext in archive_path.suffixes for ext in DECOMPRESS_SUPPORTED_FORMATS):
|
|
114
|
+
extracted_path = archive_path.decompress()
|
|
115
|
+
# print(f"Decompressed {archive_path} to {extracted_path}")
|
|
116
|
+
archive_path.delete(sure=True)
|
|
117
|
+
if extracted_path.is_dir():
|
|
118
|
+
nested_items = list(extracted_path.glob("*"))
|
|
119
|
+
if len(nested_items) == 1:
|
|
120
|
+
nested_path = PathExtended(nested_items[0])
|
|
121
|
+
if nested_path.is_file() and any(ex in nested_path.suffixes for ex in DECOMPRESS_SUPPORTED_FORMATS):
|
|
122
|
+
extracted_path = nested_path.decompress()
|
|
123
|
+
nested_path.delete(sure=True)
|
|
124
|
+
elif extracted_path.is_dir() and len(extracted_path.search("*", r=True)) == 1:
|
|
125
|
+
only_file_in = next(extracted_path.glob("*"))
|
|
126
|
+
if only_file_in.is_file() and any(ext in str(only_file_in) for ext in DECOMPRESS_SUPPORTED_FORMATS): # further decompress
|
|
127
|
+
extracted_path = only_file_in.decompress()
|
|
128
|
+
only_file_in.delete(sure=True)
|
|
129
|
+
return extracted_path
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
from machineconfig.utils.path_extended import PathExtended
|
|
3
2
|
from machineconfig.utils.source_of_truth import WINDOWS_INSTALL_PATH, LINUX_INSTALL_PATH, INSTALL_VERSION_ROOT
|
|
4
3
|
|
|
@@ -8,23 +7,28 @@ import subprocess
|
|
|
8
7
|
import platform
|
|
9
8
|
|
|
10
9
|
|
|
11
|
-
def find_move_delete_windows(downloaded_file_path: PathExtended,
|
|
12
|
-
print(
|
|
13
|
-
if exe_name is not None and
|
|
14
|
-
|
|
10
|
+
def find_move_delete_windows(downloaded_file_path: PathExtended, tool_name: Optional[str], delete: bool, rename_to: Optional[str]):
|
|
11
|
+
# print("🔍 PROCESSING WINDOWS EXECUTABLE 🔍")
|
|
12
|
+
# if exe_name is not None and len(exe_name.split("+")) > 1:
|
|
13
|
+
# last_result = None
|
|
14
|
+
# for a_binary in [x.strip() for x in exe_name.split("+") if x.strip() != ""]:
|
|
15
|
+
# last_result = find_move_delete_windows(downloaded_file_path=downloaded_file_path, exe_name=a_binary, delete=delete, rename_to=rename_to)
|
|
16
|
+
# return last_result
|
|
17
|
+
if tool_name is not None and ".exe" in tool_name:
|
|
18
|
+
tool_name = tool_name.replace(".exe", "")
|
|
15
19
|
if downloaded_file_path.is_file():
|
|
16
20
|
exe = downloaded_file_path
|
|
17
21
|
print(f"📄 Found direct executable file: {exe}")
|
|
18
22
|
else:
|
|
19
23
|
print(f"🔎 Searching for executable in: {downloaded_file_path}")
|
|
20
|
-
if
|
|
24
|
+
if tool_name is None:
|
|
21
25
|
exe = downloaded_file_path.search("*.exe", r=True)[0]
|
|
22
26
|
print(f"✅ Found executable: {exe}")
|
|
23
27
|
else:
|
|
24
|
-
tmp = downloaded_file_path.search(f"{
|
|
28
|
+
tmp = downloaded_file_path.search(f"{tool_name}.exe", r=True)
|
|
25
29
|
if len(tmp) == 1:
|
|
26
30
|
exe = tmp[0]
|
|
27
|
-
print(f"✅ Found exact match for {
|
|
31
|
+
print(f"✅ Found exact match for {tool_name}.exe: {exe}")
|
|
28
32
|
else:
|
|
29
33
|
search_res = downloaded_file_path.search("*.exe", r=True)
|
|
30
34
|
if len(search_res) == 0:
|
|
@@ -53,8 +57,14 @@ def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optio
|
|
|
53
57
|
return exe_new_location
|
|
54
58
|
|
|
55
59
|
|
|
56
|
-
def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete:
|
|
57
|
-
|
|
60
|
+
def find_move_delete_linux(downloaded: PathExtended, tool_name: Optional[str], delete: bool, rename_to: Optional[str]):
|
|
61
|
+
# if len(tool_name.split("+")) > 1:
|
|
62
|
+
# last_result = None
|
|
63
|
+
# for a_binary in [x.strip() for x in tool_name.split("+") if x.strip() != ""]:
|
|
64
|
+
# last_result = find_move_delete_linux(downloaded=downloaded, tool_name=a_binary, delete=False, rename_to=rename_to)
|
|
65
|
+
# return last_result
|
|
66
|
+
|
|
67
|
+
print("🔍 PROCESSING LINUX EXECUTABLE 🔍")
|
|
58
68
|
if downloaded.is_file():
|
|
59
69
|
exe = downloaded
|
|
60
70
|
print(f"📄 Found direct executable file: {exe}")
|
|
@@ -65,16 +75,24 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Opt
|
|
|
65
75
|
exe = res[0]
|
|
66
76
|
print(f"✅ Found match for pattern '*{tool_name}*': {exe}")
|
|
67
77
|
else:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
exe =
|
|
74
|
-
print(f"✅ Found exact match for '{tool_name}': {exe}")
|
|
75
|
-
else:
|
|
76
|
-
exe = max(exe_search_res, key=lambda x: x.size("kb"))
|
|
78
|
+
if tool_name is None: # no tool name provided, get the largest executable
|
|
79
|
+
search_res = downloaded.search("*", folders=False, files=True, r=True)
|
|
80
|
+
if len(search_res) == 0:
|
|
81
|
+
print(f"❌ ERROR: No search results in `{downloaded}`")
|
|
82
|
+
raise IndexError(f"No executable found in {downloaded}")
|
|
83
|
+
exe = max(search_res, key=lambda x: x.size("kb"))
|
|
77
84
|
print(f"✅ Selected largest executable ({exe.size('kb')} KB): {exe}")
|
|
85
|
+
else:
|
|
86
|
+
exe_search_res = downloaded.search(tool_name, folders=False, r=True)
|
|
87
|
+
if len(exe_search_res) == 0:
|
|
88
|
+
print(f"❌ ERROR: No search results for `{tool_name}` in `{downloaded}`")
|
|
89
|
+
raise IndexError(f"No executable found in {downloaded}")
|
|
90
|
+
elif len(exe_search_res) == 1:
|
|
91
|
+
exe = exe_search_res[0]
|
|
92
|
+
print(f"✅ Found exact match for '{tool_name}': {exe}")
|
|
93
|
+
else:
|
|
94
|
+
exe = max(exe_search_res, key=lambda x: x.size("kb"))
|
|
95
|
+
print(f"✅ Selected largest executable ({exe.size('kb')} KB): {exe}")
|
|
78
96
|
|
|
79
97
|
if rename_to and exe.name != rename_to:
|
|
80
98
|
print(f"🏷️ Renaming '{exe.name}' to '{rename_to}'")
|
|
@@ -108,33 +126,52 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Opt
|
|
|
108
126
|
print("✅ Temporary files removed")
|
|
109
127
|
|
|
110
128
|
exe_new_location = PathExtended(LINUX_INSTALL_PATH).joinpath(exe.name)
|
|
111
|
-
print(f"✅ Executable installed at: {exe_new_location}
|
|
129
|
+
print(f"✅ Executable installed at: {exe_new_location}")
|
|
112
130
|
return exe_new_location
|
|
113
131
|
|
|
114
132
|
|
|
115
133
|
def check_tool_exists(tool_name: str) -> bool:
|
|
116
134
|
if platform.system() == "Windows":
|
|
117
|
-
|
|
118
|
-
res1 = any([Path(WINDOWS_INSTALL_PATH).joinpath(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
135
|
+
tool_name_exe = tool_name.replace(".exe", "") + ".exe"
|
|
136
|
+
res1 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name_exe).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name_exe).is_file()])
|
|
137
|
+
if res1:
|
|
138
|
+
return True
|
|
139
|
+
tool_name_no_exe = tool_name.replace(".exe", "")
|
|
140
|
+
res2 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name_no_exe).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name_no_exe).is_file()])
|
|
141
|
+
return res2
|
|
122
142
|
elif platform.system() in ["Linux", "Darwin"]:
|
|
123
143
|
root_path = Path(LINUX_INSTALL_PATH)
|
|
124
|
-
|
|
144
|
+
standard_checks = [
|
|
145
|
+
Path("/usr/local/bin").joinpath(tool_name).is_file(),
|
|
146
|
+
Path("/usr/bin").joinpath(tool_name).is_file(),
|
|
147
|
+
root_path.joinpath(tool_name).is_file()
|
|
148
|
+
]
|
|
149
|
+
if any(standard_checks):
|
|
150
|
+
return True
|
|
151
|
+
# Check for npm packages via nvm
|
|
152
|
+
npm_check = False
|
|
153
|
+
try:
|
|
154
|
+
result = subprocess.run(["node", "--version"], capture_output=True, text=True, check=True)
|
|
155
|
+
version = result.stdout.strip().lstrip('v')
|
|
156
|
+
nvm_bin_path = Path.home() / ".nvm" / "versions" / "node" / f"v{version}" / "bin" / tool_name
|
|
157
|
+
npm_check = nvm_bin_path.is_file()
|
|
158
|
+
except subprocess.CalledProcessError:
|
|
159
|
+
pass
|
|
160
|
+
return npm_check
|
|
125
161
|
else:
|
|
126
162
|
raise NotImplementedError(f"platform {platform.system()} not implemented")
|
|
127
|
-
|
|
163
|
+
|
|
164
|
+
def is_executable_in_path(name: str) -> bool:
|
|
128
165
|
import os
|
|
129
166
|
path_dirs = os.environ['PATH'].split(os.pathsep)
|
|
130
167
|
for path_dir in path_dirs:
|
|
131
|
-
path_to_executable = os.path.join(path_dir,
|
|
168
|
+
path_to_executable = os.path.join(path_dir, name)
|
|
132
169
|
if os.path.isfile(path_to_executable) and os.access(path_to_executable, os.X_OK): return True
|
|
133
170
|
return False
|
|
134
171
|
|
|
135
172
|
|
|
136
173
|
def check_if_installed_already(exe_name: str, version: Optional[str], use_cache: bool) -> tuple[str, str, str]:
|
|
137
|
-
print(f"
|
|
174
|
+
print(f"🔍 CHECKING INSTALLATION STATUS: {exe_name} 🔍")
|
|
138
175
|
INSTALL_VERSION_ROOT.joinpath(exe_name).parent.mkdir(parents=True, exist_ok=True)
|
|
139
176
|
tmp_path = INSTALL_VERSION_ROOT.joinpath(exe_name)
|
|
140
177
|
|
|
@@ -173,71 +210,3 @@ def check_if_installed_already(exe_name: str, version: Optional[str], use_cache:
|
|
|
173
210
|
return ("⚠️ NotInstalled", "None", version or "unknown")
|
|
174
211
|
|
|
175
212
|
|
|
176
|
-
def parse_apps_installer_linux(txt: str) -> dict[str, tuple[str, str]]:
|
|
177
|
-
"""Parse Linux shell installation scripts into logical chunks.
|
|
178
|
-
|
|
179
|
-
Splits scripts by # --GROUP:<name>:<description> comment signatures into a dictionary
|
|
180
|
-
mapping block names to (description, shell script content) tuples.
|
|
181
|
-
|
|
182
|
-
Returns:
|
|
183
|
-
dict[str, tuple[str, str]]: Dictionary mapping block/section names to (description, installation_script) tuples
|
|
184
|
-
"""
|
|
185
|
-
chunks = txt.split('# --GROUP:')
|
|
186
|
-
res: dict[str, tuple[str, str]] = {}
|
|
187
|
-
|
|
188
|
-
for chunk in chunks[1:]: # Skip first empty chunk before first group
|
|
189
|
-
lines = chunk.split('\n')
|
|
190
|
-
# First line contains the group name and description in format "NAME:DESCRIPTION"
|
|
191
|
-
group_line = lines[0].strip()
|
|
192
|
-
|
|
193
|
-
# Extract group name and description
|
|
194
|
-
if ':' in group_line:
|
|
195
|
-
parts = group_line.split(':', 1) # Split only on first colon
|
|
196
|
-
group_name = parts[0].strip()
|
|
197
|
-
group_description = parts[1].strip() if len(parts) > 1 else ""
|
|
198
|
-
else:
|
|
199
|
-
group_name = group_line
|
|
200
|
-
group_description = ""
|
|
201
|
-
|
|
202
|
-
# Rest is the content
|
|
203
|
-
content = '\n'.join(lines[1:]).strip()
|
|
204
|
-
|
|
205
|
-
if group_name and content:
|
|
206
|
-
res[group_name] = (group_description, content)
|
|
207
|
-
|
|
208
|
-
return res
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
def parse_apps_installer_windows(txt: str) -> dict[str, tuple[str, str]]:
|
|
212
|
-
"""Parse Windows PowerShell installation scripts into logical chunks.
|
|
213
|
-
|
|
214
|
-
Splits scripts by # --GROUP:<name>:<description> comment signatures into a dictionary
|
|
215
|
-
mapping block names to (description, PowerShell script content) tuples.
|
|
216
|
-
|
|
217
|
-
Returns:
|
|
218
|
-
dict[str, tuple[str, str]]: Dictionary mapping block/section names to (description, installation_script) tuples
|
|
219
|
-
"""
|
|
220
|
-
chunks = txt.split('# --GROUP:')
|
|
221
|
-
res: dict[str, tuple[str, str]] = {}
|
|
222
|
-
|
|
223
|
-
for chunk in chunks[1:]: # Skip first chunk before first group
|
|
224
|
-
lines = chunk.split('\n')
|
|
225
|
-
# First line contains the group name and description in format "NAME:DESCRIPTION"
|
|
226
|
-
group_line = lines[0].strip()
|
|
227
|
-
|
|
228
|
-
# Extract group name and description
|
|
229
|
-
if ':' in group_line:
|
|
230
|
-
parts = group_line.split(':', 1) # Split only on first colon
|
|
231
|
-
group_name = parts[0].strip()
|
|
232
|
-
group_description = parts[1].strip() if len(parts) > 1 else ""
|
|
233
|
-
else:
|
|
234
|
-
group_name = group_line
|
|
235
|
-
group_description = ""
|
|
236
|
-
|
|
237
|
-
# Rest is the content
|
|
238
|
-
content = '\n'.join(lines[1:]).strip()
|
|
239
|
-
|
|
240
|
-
if group_name and content:
|
|
241
|
-
res[group_name] = (group_description, content)
|
|
242
|
-
|
|
243
|
-
return res
|