machineconfig 6.82__py3-none-any.whl → 8.51__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/cluster/remote/cloud_manager.py +1 -1
- machineconfig/cluster/remote/run_cluster.py +1 -1
- machineconfig/cluster/remote/run_remote.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +29 -15
- machineconfig/cluster/sessions_managers/wt_local.py +17 -222
- machineconfig/cluster/sessions_managers/wt_local_manager.py +56 -194
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +42 -198
- 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_reporting.py +76 -0
- machineconfig/cluster/sessions_managers/wt_utils/wt_helpers.py +199 -0
- machineconfig/cluster/sessions_managers/zellij_local.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +4 -2
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +3 -2
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +2 -2
- 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 +1500 -310
- machineconfig/jobs/installer/linux_scripts/docker.sh +6 -9
- machineconfig/jobs/installer/linux_scripts/q.sh +10 -7
- machineconfig/jobs/installer/linux_scripts/redis.sh +1 -0
- machineconfig/jobs/installer/package_groups.py +62 -91
- machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
- machineconfig/jobs/installer/{custom → python_scripts}/boxes.py +2 -3
- machineconfig/jobs/installer/{custom_dev → python_scripts}/brave.py +5 -3
- machineconfig/jobs/installer/python_scripts/cloudflare_warp_cli.py +23 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/code.py +14 -9
- machineconfig/jobs/installer/{custom_dev → python_scripts}/dubdb_adbc.py +1 -1
- machineconfig/jobs/installer/python_scripts/hx.py +214 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerdfont.py +2 -2
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerfont_windows_helper.py +32 -26
- machineconfig/jobs/installer/python_scripts/sysabc.py +145 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/wezterm.py +2 -19
- machineconfig/jobs/installer/{custom_dev → python_scripts}/winget.py +10 -14
- machineconfig/jobs/installer/python_scripts/yazi.py +139 -0
- machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nfs +0 -1
- machineconfig/jobs/scripts/powershell_scripts/cmatrix.ps1 +52 -0
- machineconfig/jobs/scripts/powershell_scripts/mount_ssh.ps1 +13 -0
- machineconfig/jobs/scripts/powershell_scripts/obs.ps1 +4 -0
- machineconfig/jobs/scripts_dynamic/a.py +428 -0
- machineconfig/logger.py +1 -2
- machineconfig/profile/create_helper.py +56 -18
- machineconfig/profile/create_links.py +79 -21
- machineconfig/profile/create_links_export.py +87 -36
- machineconfig/profile/create_shell_profile.py +92 -127
- machineconfig/profile/mapper_data.toml +45 -0
- machineconfig/profile/mapper_dotfiles.toml +249 -0
- machineconfig/scripts/__init__.py +0 -4
- machineconfig/scripts/linux/wrap_mcfg +46 -0
- machineconfig/scripts/nu/wrap_mcfg.nu +69 -0
- machineconfig/scripts/python/agents.py +85 -165
- machineconfig/scripts/python/ai/initai.py +4 -2
- machineconfig/scripts/python/ai/scripts/__init__.py +1 -0
- machineconfig/scripts/python/ai/scripts/command_runner.ps1 +33 -0
- machineconfig/scripts/python/ai/{command_runner → scripts}/command_runner.sh +1 -1
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +2 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +8 -6
- 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/{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 +6 -6
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +33 -0
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -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/{generate_files.py → utils/generate_files.py} +2 -2
- machineconfig/scripts/python/ai/{solutions → utils}/generic.py +2 -15
- machineconfig/scripts/python/ai/{vscode_tasks.py → utils/vscode_tasks.py} +13 -5
- machineconfig/scripts/python/cloud.py +58 -11
- machineconfig/scripts/python/croshell.py +10 -162
- machineconfig/scripts/python/devops.py +73 -36
- machineconfig/scripts/python/devops_navigator.py +16 -6
- machineconfig/scripts/python/fire_jobs.py +8 -222
- machineconfig/scripts/python/ftpx.py +7 -200
- 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/helpers/helper_env/env_manager_tui.py +204 -0
- machineconfig/scripts/python/helpers/helper_env/path_manager_tui.py +228 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/fire_crush.json +1 -1
- machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/fire_cursor_agents.py +3 -4
- machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
- machineconfig/scripts/python/helpers/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
- machineconfig/scripts/python/helpers/helpers_agents/agents_impl.py +168 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_help_launch.py +38 -16
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_helper_types.py +11 -14
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aichat/config.yaml +5 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/aider/.aider.conf.yml +2 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/copilot/config.yml +1 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/crush/crush.json +10 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/configs/gemini/settings.json +12 -0
- machineconfig/scripts/python/helpers/helpers_agents/privacy/privacy.py +109 -0
- machineconfig/scripts/python/helpers/helpers_agents/templates/prompt.txt +10 -0
- machineconfig/scripts/python/helpers/helpers_agents/templates/template.sh +34 -0
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_copy.py +32 -25
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_mount.py +29 -22
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_sync.py +9 -8
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers2.py +1 -1
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/crosh.py +3 -3
- 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 +12 -12
- machineconfig/scripts/python/helpers/helpers_devops/backup_config.py +149 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_backup_retrieve.py +262 -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 +67 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_nw.py +201 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_repos.py +274 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_self.py +197 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_share_file.py +151 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_share_server.py +125 -0
- machineconfig/scripts/python/{helpers_devops/cli_terminal.py → helpers/helpers_devops/cli_share_terminal.py} +26 -22
- machineconfig/scripts/python/helpers/helpers_devops/cli_ssh.py +167 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_status.py +17 -23
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_update_repos.py +1 -1
- machineconfig/scripts/python/{interactive.py → helpers/helpers_devops/interactive.py} +78 -71
- machineconfig/scripts/python/helpers/helpers_devops/run_script.py +197 -0
- 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 +4 -4
- machineconfig/scripts/python/{helpers_fire/helpers4.py → helpers/helpers_fire_command/file_wrangler.py} +57 -20
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_args_helper.py +1 -0
- 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 +26 -16
- machineconfig/scripts/python/helpers/helpers_msearch/__init__.py +5 -0
- machineconfig/scripts/python/helpers/helpers_msearch/msearch_impl.py +248 -0
- machineconfig/scripts/{linux → python/helpers/helpers_msearch/scripts_linux}/fzfg +6 -5
- machineconfig/scripts/python/helpers/helpers_msearch/scripts_linux/search_with_context.sh +48 -0
- machineconfig/scripts/python/helpers/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
- 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/address.py +174 -0
- machineconfig/scripts/python/helpers/helpers_network/address_switch.py +78 -0
- machineconfig/scripts/python/helpers/helpers_network/ftpx_impl.py +276 -0
- machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_nfs.py +2 -2
- machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_ssh.py +3 -3
- 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/{nw → helpers/helpers_network}/wifi_conn.py +1 -53
- 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}/clone.py +0 -1
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/cloud_repo_sync.py +159 -48
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/grource.py +4 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/record.py +33 -12
- machineconfig/scripts/python/helpers/helpers_repos/repo_analyzer_1.py +160 -0
- machineconfig/scripts/python/{helpers_repos/count_lines.py → helpers/helpers_repos/repo_analyzer_2.py} +156 -191
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/update.py +0 -6
- machineconfig/scripts/python/helpers/helpers_search/ast_search.py +74 -0
- machineconfig/scripts/python/helpers/helpers_search/qr_code.py +166 -0
- machineconfig/scripts/python/helpers/helpers_search/repo_rag.py +325 -0
- machineconfig/scripts/python/helpers/helpers_search/script_help.py +81 -0
- machineconfig/scripts/python/helpers/helpers_search/symantic_search.py +25 -0
- machineconfig/scripts/python/helpers/helpers_sessions/__init__.py +0 -0
- machineconfig/scripts/python/helpers/helpers_sessions/sessions_impl.py +186 -0
- machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py +20 -14
- 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/helpers_utils/download.py +150 -0
- machineconfig/scripts/python/helpers/helpers_utils/pdf.py +96 -0
- machineconfig/scripts/python/helpers/helpers_utils/python.py +210 -0
- machineconfig/scripts/python/helpers/helpers_utils/specs.py +246 -0
- machineconfig/scripts/python/mcfg_entry.py +143 -0
- machineconfig/scripts/python/msearch.py +26 -0
- machineconfig/scripts/python/sessions.py +69 -135
- machineconfig/scripts/python/terminal.py +58 -0
- machineconfig/scripts/python/utils.py +115 -38
- machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -0
- machineconfig/settings/atuin/config.toml +294 -0
- machineconfig/settings/atuin/themes/catppuccin-mocha-mauve.toml +12 -0
- 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 +3 -2
- machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
- machineconfig/settings/lf/windows/lfrc +14 -16
- machineconfig/settings/linters/.ruff.toml +2 -1
- machineconfig/settings/marimo/marimo.toml +1 -1
- machineconfig/settings/marimo/snippets/globalize.py +34 -0
- machineconfig/settings/mprocs/windows/mprocs.yaml +2 -2
- machineconfig/settings/shells/bash/init.sh +47 -12
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
- machineconfig/settings/shells/nushell/config.nu +25 -33
- machineconfig/settings/shells/nushell/env.nu +21 -8
- machineconfig/settings/shells/nushell/init.nu +138 -0
- machineconfig/settings/shells/pwsh/init.ps1 +111 -17
- machineconfig/settings/shells/pwsh/search_pwsh_history.ps1 +99 -0
- machineconfig/settings/shells/starship/starship.toml +16 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +6 -1
- machineconfig/settings/shells/wt/settings.json +27 -18
- machineconfig/settings/shells/zsh/init.sh +42 -23
- 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/tv/config.toml +234 -0
- machineconfig/settings/tv/themes/catppuccin-mocha-sky.toml +22 -0
- machineconfig/settings/wsl/.wslconfig +5 -30
- machineconfig/settings/wt/__init__.py +0 -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 +94 -0
- machineconfig/settings/yazi/yazi_windows.toml +58 -0
- machineconfig/settings/zellij/layouts/st.kdl +40 -9
- machineconfig/settings/zellij/layouts/st2.kdl +1 -1
- machineconfig/setup_linux/__init__.py +2 -2
- machineconfig/setup_linux/apps_desktop.sh +8 -27
- machineconfig/setup_linux/web_shortcuts/interactive.sh +27 -12
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +34 -0
- machineconfig/setup_mac/__init__.py +1 -4
- machineconfig/setup_mac/apps_gui.sh +248 -0
- machineconfig/setup_windows/__init__.py +2 -5
- machineconfig/setup_windows/uv.ps1 +8 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +28 -12
- machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +31 -0
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
- 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 +31 -4
- machineconfig/utils/code.py +163 -51
- machineconfig/utils/files/ascii_art.py +11 -15
- machineconfig/utils/files/headers.py +6 -7
- machineconfig/utils/files/read.py +8 -1
- machineconfig/utils/installer_utils/github_release_bulk.py +95 -138
- machineconfig/utils/installer_utils/github_release_scraper.py +99 -0
- machineconfig/utils/installer_utils/install_from_url.py +183 -0
- machineconfig/utils/installer_utils/installer_class.py +53 -102
- machineconfig/utils/installer_utils/installer_cli.py +161 -0
- machineconfig/utils/installer_utils/installer_helper.py +129 -0
- machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +42 -91
- machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +20 -65
- machineconfig/utils/io.py +94 -9
- machineconfig/utils/links.py +56 -38
- machineconfig/utils/meta.py +38 -21
- machineconfig/utils/options.py +81 -23
- 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 +52 -102
- machineconfig/utils/path_helper.py +76 -23
- machineconfig/utils/procs.py +1 -1
- machineconfig/utils/scheduler.py +26 -53
- machineconfig/utils/scheduling.py +0 -2
- 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 +6 -1
- machineconfig/utils/ssh.py +216 -419
- machineconfig/utils/ssh_utils/abc.py +5 -0
- machineconfig/utils/ssh_utils/copy_from_here.py +116 -0
- machineconfig/utils/ssh_utils/copy_to_here.py +303 -0
- machineconfig/utils/ssh_utils/utils.py +158 -0
- machineconfig/utils/ssh_utils/wsl.py +147 -0
- machineconfig/utils/ssh_utils/wsl_helper.py +217 -0
- machineconfig/utils/terminal.py +1 -0
- machineconfig/utils/upgrade_packages.py +107 -35
- machineconfig/utils/ve.py +12 -4
- machineconfig-8.51.dist-info/METADATA +140 -0
- machineconfig-8.51.dist-info/RECORD +543 -0
- {machineconfig-6.82.dist-info → machineconfig-8.51.dist-info}/entry_points.txt +4 -1
- machineconfig/jobs/installer/check_installations.py +0 -248
- machineconfig/jobs/installer/custom/hx.py +0 -140
- machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -41
- machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -71
- machineconfig/jobs/installer/powershell_scripts/archive_pygraphviz.ps1 +0 -12
- machineconfig/jobs/installer/powershell_scripts/openssh-server_add_key.ps1 +0 -7
- machineconfig/jobs/installer/powershell_scripts/openssh-server_copy-ssh-id.ps1 +0 -14
- machineconfig/profile/backup.toml +0 -49
- machineconfig/profile/mapper.toml +0 -256
- 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/mcfgs +0 -38
- machineconfig/scripts/linux/other/share_smb +0 -1
- machineconfig/scripts/linux/other/switch_ip +0 -20
- machineconfig/scripts/linux/skrg +0 -4
- machineconfig/scripts/linux/warp-cli.sh +0 -122
- machineconfig/scripts/linux/z_ls +0 -104
- machineconfig/scripts/python/ai/command_runner/prompt.txt +0 -9
- machineconfig/scripts/python/helpers_devops/cli_config.py +0 -120
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +0 -77
- machineconfig/scripts/python/helpers_devops/cli_data.py +0 -25
- machineconfig/scripts/python/helpers_devops/cli_nw.py +0 -73
- machineconfig/scripts/python/helpers_devops/cli_repos.py +0 -181
- machineconfig/scripts/python/helpers_devops/cli_self.py +0 -122
- machineconfig/scripts/python/helpers_devops/cli_share_server.py +0 -104
- machineconfig/scripts/python/helpers_devops/cli_utils.py +0 -221
- 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_fire/agentic_frameworks/fire_crush.py +0 -37
- machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_gemini.py +0 -44
- machineconfig/scripts/python/helpers_fire/agentic_frameworks/fire_qwen.py +0 -43
- machineconfig/scripts/python/helpers_fire/prompt.txt +0 -2
- machineconfig/scripts/python/helpers_fire/template.sh +0 -15
- 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 -588
- machineconfig/scripts/python/helpers_repos/count_lines_frontend.py +0 -17
- machineconfig/scripts/python/helpers_repos/entrypoint.py +0 -76
- machineconfig/scripts/python/helpers_repos/secure_repo.py +0 -15
- machineconfig/scripts/python/mcfg.py +0 -48
- machineconfig/scripts/python/nw/add_ssh_key.py +0 -148
- machineconfig/scripts/python/nw/devops_add_identity.py +0 -82
- machineconfig/scripts/python/nw/devops_add_ssh_key.py +0 -134
- machineconfig/scripts/python/nw/ssh_debug_linux.py +0 -391
- machineconfig/scripts/python/nw/ssh_debug_windows.py +0 -338
- machineconfig/scripts/python/nw/wsl_windows_transfer.py +0 -66
- machineconfig/scripts/windows/fzfb.ps1 +0 -3
- machineconfig/scripts/windows/fzfg.ps1 +0 -2
- machineconfig/scripts/windows/fzfrga.bat +0 -20
- machineconfig/scripts/windows/mcfgs.ps1 +0 -17
- machineconfig/scripts/windows/mounts/mount_ssh.ps1 +0 -13
- 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/apps.sh +0 -66
- machineconfig/setup_linux/others/cli_installation.sh +0 -137
- machineconfig/setup_linux/others/mint_keyboard_shortcuts.sh +0 -30
- machineconfig/setup_linux/ssh/openssh_all.sh +0 -25
- machineconfig/setup_linux/ssh/openssh_wsl.sh +0 -38
- machineconfig/setup_mac/apps.sh +0 -73
- machineconfig/setup_mac/ssh/openssh_setup.sh +0 -114
- machineconfig/setup_windows/apps.ps1 +0 -62
- machineconfig/setup_windows/others/obs.ps1 +0 -4
- machineconfig/setup_windows/ssh/add-sshkey.ps1 +0 -29
- machineconfig/setup_windows/ssh/add_identity.ps1 +0 -11
- machineconfig/setup_windows/ssh/openssh-server.ps1 +0 -37
- machineconfig/utils/installer_utils/installer.py +0 -225
- machineconfig/utils/tst.py +0 -20
- machineconfig-6.82.dist-info/METADATA +0 -82
- machineconfig-6.82.dist-info/RECORD +0 -441
- machineconfig/jobs/installer/{custom_dev → checks}/__init__.py +0 -0
- machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +0 -0
- machineconfig/{scripts/python/helpers_cloud → jobs/installer/python_scripts}/__init__.py +0 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/alacritty.py +0 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/bypass_paywall.py +0 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/cursor.py +0 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/espanso.py +0 -0
- machineconfig/jobs/installer/{custom → python_scripts}/gh.py +0 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/goes.py +0 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/lvim.py +0 -0
- machineconfig/jobs/installer/{custom_dev → python_scripts}/redis.py +0 -0
- machineconfig/{setup_linux/others → jobs/scripts/bash_scripts}/android.sh +0 -0
- machineconfig/jobs/{installer/linux_scripts → scripts/bash_scripts}/lid.sh +0 -0
- machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_drive +0 -0
- machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nw_drive +0 -0
- machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_smb +0 -0
- machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_cloud.sh +0 -0
- machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/share_nfs +0 -0
- machineconfig/{scripts/linux/other → jobs/scripts/bash_scripts}/start_docker +0 -0
- machineconfig/{scripts → jobs/scripts/powershell_scripts}/Restore-ThunderbirdProfile.ps1 +0 -0
- machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/docker.ps1 +0 -0
- machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nfs.ps1 +0 -0
- machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_nw.ps1 +0 -0
- machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/mount_smb.ps1 +0 -0
- machineconfig/{setup_windows/others → jobs/scripts/powershell_scripts}/power_options.ps1 +0 -0
- machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_cloud.cmd +0 -0
- machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/share_smb.ps1 +0 -0
- machineconfig/{scripts/windows/mounts → jobs/scripts/powershell_scripts}/unlock_bitlocker.ps1 +0 -0
- machineconfig/scripts/python/{helpers_croshell → ai/utils}/__init__.py +0 -0
- machineconfig/scripts/python/ai/{solutions/_shared.py → utils/shared.py} +0 -0
- machineconfig/scripts/python/{helpers_devops → graph}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_devops/themes → 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_fire → helpers/helpers_agents}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/agentic_frameworks/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_help_search.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents}/fire_agents_load_balancer.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers/helpers_agents/templates}/template.ps1 +0 -0
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_cloud}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_helpers.py +1 -1
- /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers5.py +0 -0
- /machineconfig/scripts/python/{helpers_sessions → helpers/helpers_croshell}/__init__.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/{nw → helpers/helpers_devops}/__init__.py +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → scripts/python/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/fire_jobs_streamlit_helper.py → helpers/helpers_fire_command/f.py} +0 -0
- /machineconfig/{settings/shells/pwsh/profile.ps1 → scripts/python/helpers/helpers_fire_command/fire_jobs_streamlit_helper.py} +0 -0
- /machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/search_bar.py +0 -0
- /machineconfig/{settings/yazi/keymap.toml → scripts/python/helpers/helpers_network/__init__.py} +0 -0
- /machineconfig/scripts/python/{nw → helpers/helpers_network}/mount_nw_drive.py +0 -0
- /machineconfig/scripts/python/{nw → helpers/helpers_network}/onetimeshare.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/sync.py +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → settings/wt}/set_wt_settings.py +0 -0
- {machineconfig-6.82.dist-info → machineconfig-8.51.dist-info}/WHEEL +0 -0
- {machineconfig-6.82.dist-info → machineconfig-8.51.dist-info}/top_level.txt +0 -0
|
@@ -7,25 +7,30 @@ import subprocess
|
|
|
7
7
|
import platform
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
def find_move_delete_windows(downloaded_file_path: PathExtended,
|
|
11
|
-
print("🔍 PROCESSING WINDOWS EXECUTABLE 🔍")
|
|
12
|
-
if exe_name is not None and
|
|
13
|
-
|
|
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", "")
|
|
14
19
|
if downloaded_file_path.is_file():
|
|
15
20
|
exe = downloaded_file_path
|
|
16
21
|
print(f"📄 Found direct executable file: {exe}")
|
|
17
22
|
else:
|
|
18
23
|
print(f"🔎 Searching for executable in: {downloaded_file_path}")
|
|
19
|
-
if
|
|
20
|
-
exe = downloaded_file_path.
|
|
24
|
+
if tool_name is None:
|
|
25
|
+
exe = list(downloaded_file_path.rglob("*.exe"))[0]
|
|
21
26
|
print(f"✅ Found executable: {exe}")
|
|
22
27
|
else:
|
|
23
|
-
tmp = downloaded_file_path.
|
|
28
|
+
tmp = list(downloaded_file_path.rglob(f"{tool_name}.exe"))
|
|
24
29
|
if len(tmp) == 1:
|
|
25
30
|
exe = tmp[0]
|
|
26
|
-
print(f"✅ Found exact match for {
|
|
31
|
+
print(f"✅ Found exact match for {tool_name}.exe: {exe}")
|
|
27
32
|
else:
|
|
28
|
-
search_res = downloaded_file_path.
|
|
33
|
+
search_res = list(downloaded_file_path.rglob("*.exe"))
|
|
29
34
|
if len(search_res) == 0:
|
|
30
35
|
print(f"❌ ERROR: No executable found in {downloaded_file_path}")
|
|
31
36
|
raise IndexError(f"No executable found in {downloaded_file_path}")
|
|
@@ -33,8 +38,8 @@ def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optio
|
|
|
33
38
|
exe = search_res[0]
|
|
34
39
|
print(f"✅ Found single executable: {exe}")
|
|
35
40
|
else:
|
|
36
|
-
exe = max(search_res, key=lambda x: x.
|
|
37
|
-
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}")
|
|
38
43
|
if rename_to and exe.name != rename_to:
|
|
39
44
|
print(f"🏷️ Renaming '{exe.name}' to '{rename_to}'")
|
|
40
45
|
exe = exe.with_name(name=rename_to, inplace=True)
|
|
@@ -52,28 +57,42 @@ def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optio
|
|
|
52
57
|
return exe_new_location
|
|
53
58
|
|
|
54
59
|
|
|
55
|
-
def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete:
|
|
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
|
+
|
|
56
67
|
print("🔍 PROCESSING LINUX EXECUTABLE 🔍")
|
|
57
68
|
if downloaded.is_file():
|
|
58
69
|
exe = downloaded
|
|
59
70
|
print(f"📄 Found direct executable file: {exe}")
|
|
60
71
|
else:
|
|
61
72
|
print(f"🔎 Searching for executable in: {downloaded}")
|
|
62
|
-
res = downloaded.
|
|
73
|
+
res = [p for p in downloaded.rglob(f"*{tool_name}*") if p.is_file()]
|
|
63
74
|
if len(res) == 1:
|
|
64
75
|
exe = res[0]
|
|
65
76
|
print(f"✅ Found match for pattern '*{tool_name}*': {exe}")
|
|
66
77
|
else:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
exe =
|
|
73
|
-
print(f"✅
|
|
78
|
+
if tool_name is None: # no tool name provided, get the largest executable
|
|
79
|
+
search_res = [p for p in downloaded.rglob("*") if p.is_file()]
|
|
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.stat().st_size)
|
|
84
|
+
print(f"✅ Selected largest executable ({round(exe.stat().st_size / 1024, 1)} KB): {exe}")
|
|
74
85
|
else:
|
|
75
|
-
|
|
76
|
-
|
|
86
|
+
exe_search_res = [p for p in downloaded.rglob(tool_name) if p.is_file()]
|
|
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.stat().st_size)
|
|
95
|
+
print(f"✅ Selected largest executable ({round(exe.stat().st_size / 1024, 1)} KB): {exe}")
|
|
77
96
|
|
|
78
97
|
if rename_to and exe.name != rename_to:
|
|
79
98
|
print(f"🏷️ Renaming '{exe.name}' to '{rename_to}'")
|
|
@@ -136,7 +155,7 @@ def check_tool_exists(tool_name: str) -> bool:
|
|
|
136
155
|
version = result.stdout.strip().lstrip('v')
|
|
137
156
|
nvm_bin_path = Path.home() / ".nvm" / "versions" / "node" / f"v{version}" / "bin" / tool_name
|
|
138
157
|
npm_check = nvm_bin_path.is_file()
|
|
139
|
-
except subprocess.CalledProcessError:
|
|
158
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
140
159
|
pass
|
|
141
160
|
return npm_check
|
|
142
161
|
else:
|
|
@@ -191,71 +210,3 @@ def check_if_installed_already(exe_name: str, version: Optional[str], use_cache:
|
|
|
191
210
|
return ("⚠️ NotInstalled", "None", version or "unknown")
|
|
192
211
|
|
|
193
212
|
|
|
194
|
-
def parse_apps_installer_linux(txt: str) -> dict[str, tuple[str, str]]:
|
|
195
|
-
"""Parse Linux shell installation scripts into logical chunks.
|
|
196
|
-
|
|
197
|
-
Splits scripts by # --GROUP:<name>:<description> comment signatures into a dictionary
|
|
198
|
-
mapping block names to (description, shell script content) tuples.
|
|
199
|
-
|
|
200
|
-
Returns:
|
|
201
|
-
dict[str, tuple[str, str]]: Dictionary mapping block/section names to (description, installation_script) tuples
|
|
202
|
-
"""
|
|
203
|
-
chunks = txt.split('# --GROUP:')
|
|
204
|
-
res: dict[str, tuple[str, str]] = {}
|
|
205
|
-
|
|
206
|
-
for chunk in chunks[1:]: # Skip first empty chunk before first group
|
|
207
|
-
lines = chunk.split('\n')
|
|
208
|
-
# First line contains the group name and description in format "NAME:DESCRIPTION"
|
|
209
|
-
group_line = lines[0].strip()
|
|
210
|
-
|
|
211
|
-
# Extract group name and description
|
|
212
|
-
if ':' in group_line:
|
|
213
|
-
parts = group_line.split(':', 1) # Split only on first colon
|
|
214
|
-
group_name = parts[0].strip()
|
|
215
|
-
group_description = parts[1].strip() if len(parts) > 1 else ""
|
|
216
|
-
else:
|
|
217
|
-
group_name = group_line
|
|
218
|
-
group_description = ""
|
|
219
|
-
|
|
220
|
-
# Rest is the content
|
|
221
|
-
content = '\n'.join(lines[1:]).strip()
|
|
222
|
-
|
|
223
|
-
if group_name and content:
|
|
224
|
-
res[group_name] = (group_description, content)
|
|
225
|
-
|
|
226
|
-
return res
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
def parse_apps_installer_windows(txt: str) -> dict[str, tuple[str, str]]:
|
|
230
|
-
"""Parse Windows PowerShell installation scripts into logical chunks.
|
|
231
|
-
|
|
232
|
-
Splits scripts by # --GROUP:<name>:<description> comment signatures into a dictionary
|
|
233
|
-
mapping block names to (description, PowerShell script content) tuples.
|
|
234
|
-
|
|
235
|
-
Returns:
|
|
236
|
-
dict[str, tuple[str, str]]: Dictionary mapping block/section names to (description, installation_script) tuples
|
|
237
|
-
"""
|
|
238
|
-
chunks = txt.split('# --GROUP:')
|
|
239
|
-
res: dict[str, tuple[str, str]] = {}
|
|
240
|
-
|
|
241
|
-
for chunk in chunks[1:]: # Skip first chunk before first group
|
|
242
|
-
lines = chunk.split('\n')
|
|
243
|
-
# First line contains the group name and description in format "NAME:DESCRIPTION"
|
|
244
|
-
group_line = lines[0].strip()
|
|
245
|
-
|
|
246
|
-
# Extract group name and description
|
|
247
|
-
if ':' in group_line:
|
|
248
|
-
parts = group_line.split(':', 1) # Split only on first colon
|
|
249
|
-
group_name = parts[0].strip()
|
|
250
|
-
group_description = parts[1].strip() if len(parts) > 1 else ""
|
|
251
|
-
else:
|
|
252
|
-
group_name = group_line
|
|
253
|
-
group_description = ""
|
|
254
|
-
|
|
255
|
-
# Rest is the content
|
|
256
|
-
content = '\n'.join(lines[1:]).strip()
|
|
257
|
-
|
|
258
|
-
if group_name and content:
|
|
259
|
-
res[group_name] = (group_description, content)
|
|
260
|
-
|
|
261
|
-
return res
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"""package manager"""
|
|
2
2
|
|
|
3
|
-
from machineconfig.utils.installer_utils.
|
|
3
|
+
from machineconfig.utils.installer_utils.installer_locator_utils import check_if_installed_already
|
|
4
4
|
from machineconfig.utils.installer_utils.installer_class import Installer
|
|
5
5
|
from machineconfig.utils.schemas.installer.installer_types import InstallerData, InstallerDataFiles, get_normalized_arch, get_os_name, OPERATING_SYSTEMS, CPU_ARCHITECTURES
|
|
6
|
-
from machineconfig.jobs.installer.package_groups import
|
|
6
|
+
from machineconfig.jobs.installer.package_groups import PACKAGE_GROUP2NAMES
|
|
7
7
|
from machineconfig.utils.path_extended import PathExtended
|
|
8
8
|
from machineconfig.utils.source_of_truth import INSTALL_VERSION_ROOT, LINUX_INSTALL_PATH
|
|
9
9
|
from machineconfig.utils.io import read_json
|
|
@@ -18,7 +18,7 @@ from joblib import Parallel, delayed
|
|
|
18
18
|
def check_latest():
|
|
19
19
|
console = Console() # Added console initialization
|
|
20
20
|
console.print(Panel("🔍 CHECKING FOR LATEST VERSIONS", title="Status", expand=False)) # Replaced print with Panel
|
|
21
|
-
installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=["
|
|
21
|
+
installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=["termabc"])
|
|
22
22
|
installers_github = []
|
|
23
23
|
for inst__ in installers:
|
|
24
24
|
app_name = inst__["appName"]
|
|
@@ -75,24 +75,28 @@ 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
|
|
|
93
93
|
|
|
94
|
-
def get_installers(os: OPERATING_SYSTEMS, arch: CPU_ARCHITECTURES, which_cats: Optional[list[
|
|
95
|
-
|
|
94
|
+
def get_installers(os: OPERATING_SYSTEMS, arch: CPU_ARCHITECTURES, which_cats: Optional[list[str]]) -> list[InstallerData]:
|
|
95
|
+
import machineconfig.jobs.installer as module
|
|
96
|
+
from pathlib import Path
|
|
97
|
+
res_raw: InstallerDataFiles = read_json(Path(module.__file__).parent.joinpath("installer_data.json"))
|
|
98
|
+
res_all: list[InstallerData] = res_raw["installers"]
|
|
99
|
+
|
|
96
100
|
acceptable_apps_names: list[str] | None = None
|
|
97
101
|
if which_cats is not None:
|
|
98
102
|
acceptable_apps_names = []
|
|
@@ -105,40 +109,17 @@ def get_installers(os: OPERATING_SYSTEMS, arch: CPU_ARCHITECTURES, which_cats: O
|
|
|
105
109
|
if acceptable_apps_names is not None:
|
|
106
110
|
if installer_data["appName"] not in acceptable_apps_names:
|
|
107
111
|
continue
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
try:
|
|
113
|
+
if installer_data["fileNamePattern"][arch][os] is None:
|
|
114
|
+
continue
|
|
115
|
+
except KeyError as ke:
|
|
116
|
+
print(f"❌ ERROR: Missing key in installer data: {ke}")
|
|
117
|
+
print(f"Installer data: {installer_data}")
|
|
118
|
+
raise KeyError(f"Missing key in installer data: {ke}")
|
|
110
119
|
all_installers.append(installer_data)
|
|
111
120
|
return all_installers
|
|
112
121
|
|
|
113
122
|
|
|
114
|
-
def get_all_installer_data_files() -> list[InstallerData]:
|
|
115
|
-
import machineconfig.jobs.installer as module
|
|
116
|
-
from pathlib import Path
|
|
117
|
-
res_raw: InstallerDataFiles = read_json(Path(module.__file__).parent.joinpath("installer_data.json"))
|
|
118
|
-
res_final: list[InstallerData] = res_raw["installers"]
|
|
119
|
-
return res_final
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
def dynamically_extract_installers_system_groups_from_scripts():
|
|
123
|
-
res_final: list[InstallerData] = []
|
|
124
|
-
from platform import system
|
|
125
|
-
if system() == "Windows":
|
|
126
|
-
from machineconfig.setup_windows import APPS
|
|
127
|
-
options_system = parse_apps_installer_windows(APPS.read_text(encoding="utf-8"))
|
|
128
|
-
elif system() == "Linux" or system() == "Darwin":
|
|
129
|
-
from machineconfig.setup_linux import APPS
|
|
130
|
-
options_system = parse_apps_installer_linux(APPS.read_text(encoding="utf-8"))
|
|
131
|
-
elif system() == "Darwin":
|
|
132
|
-
from machineconfig.setup_mac import APPS
|
|
133
|
-
options_system = parse_apps_installer_linux(APPS.read_text(encoding="utf-8"))
|
|
134
|
-
else:
|
|
135
|
-
raise NotImplementedError(f"❌ System {system()} not supported")
|
|
136
|
-
os_name = get_os_name()
|
|
137
|
-
for group_name, (docs, script) in options_system.items():
|
|
138
|
-
item: InstallerData = {"appName": group_name, "doc": docs, "repoURL": "CMD", "fileNamePattern": {"amd64": {os_name: script}, "arm64": {os_name: script}}}
|
|
139
|
-
res_final.append(item)
|
|
140
|
-
return res_final
|
|
141
|
-
|
|
142
123
|
|
|
143
124
|
def install_bulk(installers_data: list[InstallerData], safe: bool = False, jobs: int = 10, fresh: bool = False):
|
|
144
125
|
print("🚀 BULK INSTALLATION PROCESS 🚀")
|
|
@@ -146,33 +127,8 @@ def install_bulk(installers_data: list[InstallerData], safe: bool = False, jobs:
|
|
|
146
127
|
print("🧹 Fresh install requested - clearing version cache...")
|
|
147
128
|
PathExtended(INSTALL_VERSION_ROOT).delete(sure=True)
|
|
148
129
|
print("✅ Version cache cleared")
|
|
149
|
-
|
|
150
130
|
if safe:
|
|
151
131
|
pass
|
|
152
|
-
# print("⚠️ Safe installation mode activated...")
|
|
153
|
-
# from machineconfig.jobs.python.check_installations import APP_SUMMARY_PATH
|
|
154
|
-
# if platform.system().lower() == "windows":
|
|
155
|
-
# print("🪟 Moving applications to Windows Apps folder...")
|
|
156
|
-
# # PathExtended.get_env().WindowsPaths().WindowsApps)
|
|
157
|
-
# folder = PathExtended.home().joinpath("AppData/Local/Microsoft/WindowsApps")
|
|
158
|
-
# apps_dir.search("*").apply(lambda app: app.move(folder=folder))
|
|
159
|
-
# elif platform.system().lower() in ["linux", "darwin"]:
|
|
160
|
-
# system_name = "Linux" if platform.system().lower() == "linux" else "macOS"
|
|
161
|
-
# print(f"🐧 Moving applications to {system_name} bin folder...")
|
|
162
|
-
# if platform.system().lower() == "linux":
|
|
163
|
-
# install_path = LINUX_INSTALL_PATH
|
|
164
|
-
# else: # Darwin/macOS
|
|
165
|
-
# install_path = "/usr/local/bin"
|
|
166
|
-
# Terminal().run(f"sudo mv {apps_dir.as_posix()}/* {install_path}/").capture().print_if_unsuccessful(desc=f"MOVING executable to {install_path}", strict_err=True, strict_returncode=True)
|
|
167
|
-
# else:
|
|
168
|
-
# error_msg = f"❌ ERROR: System {platform.system()} not supported"
|
|
169
|
-
# print(error_msg)
|
|
170
|
-
# raise NotImplementedError(error_msg)
|
|
171
|
-
|
|
172
|
-
# apps_dir.delete(sure=True)
|
|
173
|
-
# print(f"✅ Safe installation completed\n{'='*80}")
|
|
174
|
-
# return None
|
|
175
|
-
|
|
176
132
|
print(f"🚀 Starting installation of {len(installers_data)} packages...")
|
|
177
133
|
print("📦 INSTALLING FIRST PACKAGE 📦")
|
|
178
134
|
Installer(installers_data[0]).install(version=None)
|
|
@@ -214,7 +170,6 @@ def get_machineconfig_version() -> str:
|
|
|
214
170
|
from importlib.metadata import PackageNotFoundError, version as _pkg_version
|
|
215
171
|
from pathlib import Path
|
|
216
172
|
import tomllib
|
|
217
|
-
|
|
218
173
|
name: str = "machineconfig"
|
|
219
174
|
try:
|
|
220
175
|
return _pkg_version(name)
|
machineconfig/utils/io.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
1
|
|
|
3
2
|
from typing import Any, Union, Optional, Mapping
|
|
4
3
|
from pathlib import Path
|
|
@@ -56,19 +55,36 @@ def read_ini(path: "Path", encoding: Optional[str] = None):
|
|
|
56
55
|
return res
|
|
57
56
|
|
|
58
57
|
|
|
58
|
+
def remove_c_style_comments(text: str) -> str:
|
|
59
|
+
import re
|
|
60
|
+
# Step 1: Escape URLs (https:// or any URLs you want to protect)
|
|
61
|
+
url_pattern = r'https?://[^\s]*'
|
|
62
|
+
urls = re.findall(url_pattern, text)
|
|
63
|
+
url_map = {url: f"__URL{index}__" for index, url in enumerate(urls)}
|
|
64
|
+
|
|
65
|
+
# Temporarily replace URLs with placeholders
|
|
66
|
+
for url, placeholder in url_map.items():
|
|
67
|
+
text = text.replace(url, placeholder)
|
|
68
|
+
|
|
69
|
+
# Step 2: Remove C-style comments
|
|
70
|
+
# Remove all // single-line comments
|
|
71
|
+
text = re.sub(r'//.*', '', text)
|
|
72
|
+
# Remove all /* … */ block comments (non-greedy)
|
|
73
|
+
text = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL)
|
|
74
|
+
|
|
75
|
+
# Step 3: Restore URLs
|
|
76
|
+
for url, placeholder in url_map.items():
|
|
77
|
+
text = text.replace(placeholder, url)
|
|
78
|
+
|
|
79
|
+
return text
|
|
80
|
+
|
|
81
|
+
|
|
59
82
|
def read_json(path: "Path", r: bool = False, **kwargs: Any) -> Any: # return could be list or dict etc
|
|
60
83
|
import json
|
|
61
84
|
try:
|
|
62
85
|
mydict = json.loads(Path(path).read_text(encoding="utf-8"), **kwargs)
|
|
63
86
|
except Exception:
|
|
64
|
-
|
|
65
|
-
def remove_comments(text: str) -> str:
|
|
66
|
-
# remove all // single-line comments
|
|
67
|
-
text = re.sub(r'//.*', '', text)
|
|
68
|
-
# remove all /* … */ block comments (non-greedy)
|
|
69
|
-
text = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL)
|
|
70
|
-
return text
|
|
71
|
-
mydict = json.loads(remove_comments(Path(path).read_text(encoding="utf-8")), **kwargs)
|
|
87
|
+
mydict = json.loads(remove_c_style_comments(Path(path).read_text(encoding="utf-8")), **kwargs)
|
|
72
88
|
_ = r
|
|
73
89
|
return mydict
|
|
74
90
|
|
|
@@ -77,3 +93,72 @@ def from_pickle(path: Path) -> Any:
|
|
|
77
93
|
import pickle
|
|
78
94
|
|
|
79
95
|
return pickle.loads(path.read_bytes())
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def pwd2key(password: str, salt: Optional[bytes] = None, iterations: int = 10) -> bytes: # Derive a secret key from a given password and salt"""
|
|
99
|
+
import base64
|
|
100
|
+
if salt is None:
|
|
101
|
+
import hashlib
|
|
102
|
+
m = hashlib.sha256()
|
|
103
|
+
m.update(password.encode(encoding="utf-8"))
|
|
104
|
+
return base64.urlsafe_b64encode(s=m.digest()) # make url-safe bytes required by Ferent.
|
|
105
|
+
from cryptography.hazmat.primitives import hashes
|
|
106
|
+
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|
107
|
+
return base64.urlsafe_b64encode(PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=iterations, backend=None).derive(password.encode()))
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def encrypt(msg: bytes, key: Optional[bytes] = None, pwd: Optional[str] = None, salted: bool = True, iteration: Optional[int] = None, gen_key: bool = False) -> bytes:
|
|
111
|
+
import base64
|
|
112
|
+
from cryptography.fernet import Fernet
|
|
113
|
+
|
|
114
|
+
salt, iteration = None, None
|
|
115
|
+
if pwd is not None: # generate it from password
|
|
116
|
+
assert (key is None) and (type(pwd) is str), "❌ You can either pass key or pwd, or none of them, but not both."
|
|
117
|
+
import secrets
|
|
118
|
+
iteration = iteration or secrets.randbelow(exclusive_upper_bound=1_000_000)
|
|
119
|
+
salt = secrets.token_bytes(nbytes=16) if salted else None
|
|
120
|
+
key_resolved = pwd2key(password=pwd, salt=salt, iterations=iteration)
|
|
121
|
+
elif key is None:
|
|
122
|
+
if gen_key:
|
|
123
|
+
key_resolved = Fernet.generate_key()
|
|
124
|
+
Path.home().joinpath("dotfiles/creds/data/encrypted_files_key.bytes").write_bytes(key_resolved)
|
|
125
|
+
else:
|
|
126
|
+
try:
|
|
127
|
+
key_resolved = Path.home().joinpath("dotfiles/creds/data/encrypted_files_key.bytes").read_bytes()
|
|
128
|
+
print(f"⚠️ Using key from: {Path.home().joinpath('dotfiles/creds/data/encrypted_files_key.bytes')}")
|
|
129
|
+
except FileNotFoundError as err:
|
|
130
|
+
print("\n" * 3, "~" * 50, """Consider Loading up your dotfiles or pass `gen_key=True` to make and save one.""", "~" * 50, "\n" * 3)
|
|
131
|
+
raise FileNotFoundError(err) from err
|
|
132
|
+
elif isinstance(key, (str, Path)):
|
|
133
|
+
key_resolved = Path(key).read_bytes() # a path to a key file was passed, read it:
|
|
134
|
+
elif type(key) is bytes:
|
|
135
|
+
key_resolved = key # key passed explicitly
|
|
136
|
+
else:
|
|
137
|
+
raise TypeError("❌ Key must be either a path, bytes object or None.")
|
|
138
|
+
code = Fernet(key=key_resolved).encrypt(msg)
|
|
139
|
+
if pwd is not None and salt is not None and iteration is not None:
|
|
140
|
+
return base64.urlsafe_b64encode(b"%b%b%b" % (salt, iteration.to_bytes(4, "big"), base64.urlsafe_b64decode(code)))
|
|
141
|
+
return code
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def decrypt(token: bytes, key: Optional[bytes] = None, pwd: Optional[str] = None, salted: bool = True) -> bytes:
|
|
145
|
+
import base64
|
|
146
|
+
if pwd is not None:
|
|
147
|
+
assert key is None, "❌ You can either pass key or pwd, or none of them, but not both."
|
|
148
|
+
if salted:
|
|
149
|
+
decoded = base64.urlsafe_b64decode(token)
|
|
150
|
+
salt, iterations, token = decoded[:16], decoded[16:20], base64.urlsafe_b64encode(decoded[20:])
|
|
151
|
+
key_resolved = pwd2key(password=pwd, salt=salt, iterations=int.from_bytes(bytes=iterations, byteorder="big"))
|
|
152
|
+
else:
|
|
153
|
+
key_resolved = pwd2key(password=pwd) # trailing `;` prevents IPython from caching the result.
|
|
154
|
+
elif type(key) is bytes:
|
|
155
|
+
assert pwd is None, "❌ You can either pass key or pwd, or none of them, but not both."
|
|
156
|
+
key_resolved = key # passsed explicitly
|
|
157
|
+
elif key is None:
|
|
158
|
+
key_resolved = Path.home().joinpath("dotfiles/creds/data/encrypted_files_key.bytes").read_bytes() # read from file
|
|
159
|
+
elif isinstance(key, (str, Path)):
|
|
160
|
+
key_resolved = Path(key).read_bytes() # passed a path to a file containing kwy
|
|
161
|
+
else:
|
|
162
|
+
raise TypeError(f"❌ Key must be either str, P, Path, bytes or None. Recieved: {type(key)}")
|
|
163
|
+
from cryptography.fernet import Fernet
|
|
164
|
+
return Fernet(key=key_resolved).decrypt(token)
|
machineconfig/utils/links.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from machineconfig.utils.path_extended import PathExtended, PLike
|
|
2
|
+
from machineconfig.profile.create_links_export import ON_CONFLICT_STRICT
|
|
2
3
|
from machineconfig.utils.accessories import randstr
|
|
3
4
|
from rich.console import Console
|
|
4
5
|
from rich.panel import Panel
|
|
@@ -96,18 +97,18 @@ def build_links(target_paths: list[tuple[PLike, str]], repo_root: PLike):
|
|
|
96
97
|
|
|
97
98
|
|
|
98
99
|
def symlink_map(config_file_default_path: PathExtended, self_managed_config_file_path: PathExtended,
|
|
99
|
-
on_conflict:
|
|
100
|
+
on_conflict: ON_CONFLICT_STRICT
|
|
100
101
|
) -> OperationResult:
|
|
101
102
|
"""helper function. creates a symlink from `config_file_default_path` to `self_managed_config_file_path`.
|
|
102
103
|
|
|
103
104
|
Returns a dict with 'action' and 'details' keys describing what was done.
|
|
104
105
|
|
|
105
106
|
on_conflict strategies:
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
107
|
+
- throw-error: Raise exception when files differ
|
|
108
|
+
- overwrite-self-managed: Delete self_managed_config_file_path (self-managed), move config_file_default_path to self_managed_config_file_path, create symlink
|
|
109
|
+
- backup-self-managed: Backup self_managed_config_file_path (self-managed), move config_file_default_path to self_managed_config_file_path, create symlink
|
|
110
|
+
- overwrite-default-path: Delete config_file_default_path (default path), create symlink to self_managed_config_file_path
|
|
111
|
+
- backup-default-path: Backup config_file_default_path (default path), create symlink to self_managed_config_file_path
|
|
111
112
|
|
|
112
113
|
Note: `config_file_default_path` is the default system location, `self_managed_config_file_path` is the self-managed config location
|
|
113
114
|
|
|
@@ -162,32 +163,41 @@ def symlink_map(config_file_default_path: PathExtended, self_managed_config_file
|
|
|
162
163
|
config_file_default_path.delete(sure=True)
|
|
163
164
|
else:
|
|
164
165
|
# Files are different, use on_conflict strategy
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
166
|
+
import subprocess
|
|
167
|
+
command = f"""delta --paging never --side-by-side "{config_file_default_path}" "{self_managed_config_file_path}" """
|
|
168
|
+
try:
|
|
169
|
+
console.print(Panel(f"🆘 CONFLICT DETECTED | Showing diff between {config_file_default_path} and {self_managed_config_file_path}", title="Conflict Detected", expand=False))
|
|
170
|
+
subprocess.run(command, shell=True, check=True)
|
|
171
|
+
except Exception:
|
|
172
|
+
console.print(Panel("⚠️ Could not show diff using 'delta'. Please install 'delta' for better diff visualization.", title="Delta Not Found", expand=False))
|
|
173
|
+
|
|
174
|
+
match on_conflict:
|
|
175
|
+
case "throw-error":
|
|
176
|
+
raise RuntimeError(f"Conflict detected: {config_file_default_path} and {self_managed_config_file_path} both exist with different content")
|
|
177
|
+
case "overwrite-self-managed":
|
|
178
|
+
action_taken = "backing_up_target"
|
|
179
|
+
details = "Overwriting self-managed config, moving default path to self-managed location"
|
|
180
|
+
console.print(Panel(f"📦 OVERWRITE SELF-MANAGED | Deleting {self_managed_config_file_path}, moving {config_file_default_path} to {self_managed_config_file_path}", title="Overwrite Self-Managed", expand=False))
|
|
181
|
+
self_managed_config_file_path.delete(sure=True)
|
|
182
|
+
config_file_default_path.move(path=self_managed_config_file_path)
|
|
183
|
+
case "backup-self-managed":
|
|
184
|
+
backup_name = f"{self_managed_config_file_path}.orig_{randstr()}"
|
|
185
|
+
action_taken = "backing_up_target"
|
|
186
|
+
details = f"Backed up self-managed config to {backup_name}"
|
|
187
|
+
console.print(Panel(f"📦 BACKUP SELF-MANAGED | Moving {self_managed_config_file_path} to {backup_name}, moving {config_file_default_path} to {self_managed_config_file_path}", title="Backup Self-Managed", expand=False))
|
|
188
|
+
self_managed_config_file_path.move(path=backup_name)
|
|
189
|
+
config_file_default_path.move(path=self_managed_config_file_path)
|
|
190
|
+
case "overwrite-default-path":
|
|
191
|
+
action_taken = "backupConfigDefaultPath"
|
|
192
|
+
details = "Overwriting default path, creating symlink to self-managed config"
|
|
193
|
+
console.print(Panel(f"📦 OVERWRITE DEFAULT | Deleting {config_file_default_path}, creating symlink to {self_managed_config_file_path}", title="Overwrite Default", expand=False))
|
|
194
|
+
config_file_default_path.delete(sure=True)
|
|
195
|
+
case "backup-default-path":
|
|
196
|
+
backup_name = f"{config_file_default_path}.orig_{randstr()}"
|
|
197
|
+
action_taken = "backupConfigDefaultPath"
|
|
198
|
+
details = f"Backed up default path to {backup_name}"
|
|
199
|
+
console.print(Panel(f"📦 BACKUP DEFAULT | Moving {config_file_default_path} to {backup_name}, creating symlink to {self_managed_config_file_path}", title="Backup Default", expand=False))
|
|
200
|
+
config_file_default_path.move(path=backup_name)
|
|
191
201
|
else:
|
|
192
202
|
# self_managed_config_file_path doesn't exist
|
|
193
203
|
if config_file_default_path.is_symlink():
|
|
@@ -235,7 +245,7 @@ def symlink_map(config_file_default_path: PathExtended, self_managed_config_file
|
|
|
235
245
|
return {"action": action_taken, "details": details}
|
|
236
246
|
|
|
237
247
|
|
|
238
|
-
def copy_map(config_file_default_path: PathExtended, self_managed_config_file_path: PathExtended, on_conflict:
|
|
248
|
+
def copy_map(config_file_default_path: PathExtended, self_managed_config_file_path: PathExtended, on_conflict: ON_CONFLICT_STRICT) -> OperationResult:
|
|
239
249
|
config_file_default_path = PathExtended(config_file_default_path).expanduser().absolute()
|
|
240
250
|
self_managed_config_file_path = PathExtended(self_managed_config_file_path).expanduser().absolute()
|
|
241
251
|
|
|
@@ -282,28 +292,36 @@ def copy_map(config_file_default_path: PathExtended, self_managed_config_file_pa
|
|
|
282
292
|
config_file_default_path.delete(sure=True)
|
|
283
293
|
else:
|
|
284
294
|
# Files are different, use on_conflict strategy
|
|
295
|
+
import subprocess
|
|
296
|
+
command = f"""delta --paging never --side-by-side "{config_file_default_path}" "{self_managed_config_file_path}" """
|
|
297
|
+
try:
|
|
298
|
+
console.print(Panel(f"🆘 CONFLICT DETECTED | Showing diff between {config_file_default_path} and {self_managed_config_file_path}", title="Conflict Detected", expand=False))
|
|
299
|
+
subprocess.run(command, shell=True, check=True)
|
|
300
|
+
except Exception:
|
|
301
|
+
console.print(Panel("⚠️ Could not show diff using 'delta'. Please install 'delta' for better diff visualization.", title="Delta Not Found", expand=False))
|
|
302
|
+
|
|
285
303
|
match on_conflict:
|
|
286
|
-
case "
|
|
304
|
+
case "throw-error":
|
|
287
305
|
raise RuntimeError(f"Conflict detected: {config_file_default_path} and {self_managed_config_file_path} both exist with different content")
|
|
288
|
-
case "
|
|
306
|
+
case "overwrite-self-managed":
|
|
289
307
|
action_taken = "backing_up_target"
|
|
290
308
|
details = "Overwriting self-managed config with default path content"
|
|
291
309
|
console.print(Panel(f"📦 OVERWRITE SELF-MANAGED | Deleting {self_managed_config_file_path}, moving {config_file_default_path} to {self_managed_config_file_path}", title="Overwrite Self-Managed", expand=False))
|
|
292
310
|
self_managed_config_file_path.delete(sure=True)
|
|
293
311
|
config_file_default_path.move(path=self_managed_config_file_path)
|
|
294
|
-
case "
|
|
312
|
+
case "backup-self-managed":
|
|
295
313
|
backup_name = f"{self_managed_config_file_path}.orig_{randstr()}"
|
|
296
314
|
action_taken = "backing_up_target"
|
|
297
315
|
details = f"Backed up self-managed config to {backup_name}"
|
|
298
316
|
console.print(Panel(f"📦 BACKUP SELF-MANAGED | Moving {self_managed_config_file_path} to {backup_name}, moving {config_file_default_path} to {self_managed_config_file_path}", title="Backup Self-Managed", expand=False))
|
|
299
317
|
self_managed_config_file_path.move(path=backup_name)
|
|
300
318
|
config_file_default_path.move(path=self_managed_config_file_path)
|
|
301
|
-
case "
|
|
319
|
+
case "overwrite-default-path":
|
|
302
320
|
action_taken = "backupConfigDefaultPath"
|
|
303
321
|
details = "Overwriting default path with self-managed config"
|
|
304
322
|
console.print(Panel(f"📦 OVERWRITE DEFAULT | Deleting {config_file_default_path}, will copy from {self_managed_config_file_path}", title="Overwrite Default", expand=False))
|
|
305
323
|
config_file_default_path.delete(sure=True)
|
|
306
|
-
case "
|
|
324
|
+
case "backup-default-path":
|
|
307
325
|
backup_name = f"{config_file_default_path}.orig_{randstr()}"
|
|
308
326
|
action_taken = "backupConfigDefaultPath"
|
|
309
327
|
details = f"Backed up default path to {backup_name}"
|