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
|
@@ -1,28 +1,68 @@
|
|
|
1
|
-
import git
|
|
2
|
-
from rich.console import Console
|
|
3
|
-
from rich.panel import Panel
|
|
4
|
-
import typer
|
|
5
1
|
|
|
6
|
-
|
|
7
|
-
from machineconfig.utils.terminal import Response
|
|
8
|
-
from machineconfig.utils.source_of_truth import CONFIG_ROOT, DEFAULTS_PATH
|
|
9
|
-
from machineconfig.utils.code import get_uv_command_executing_python_script
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
import platform
|
|
12
|
-
import subprocess
|
|
2
|
+
|
|
13
3
|
from typing import Optional, Literal, Annotated
|
|
4
|
+
import typer
|
|
5
|
+
from machineconfig.utils.ssh_utils.abc import MACHINECONFIG_VERSION
|
|
14
6
|
|
|
15
7
|
|
|
16
|
-
|
|
8
|
+
def get_tmp_file():
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
import platform
|
|
11
|
+
from machineconfig.utils.accessories import randstr
|
|
12
|
+
name = randstr(8)
|
|
13
|
+
if platform.system() == "Windows":
|
|
14
|
+
suffix = "ps1"
|
|
15
|
+
else:
|
|
16
|
+
suffix = "sh"
|
|
17
|
+
tmp_file = Path.home().joinpath(f"tmp_results/tmp_files/{name}.{suffix}")
|
|
18
|
+
tmp_file.parent.mkdir(parents=True, exist_ok=True)
|
|
19
|
+
return tmp_file
|
|
17
20
|
|
|
18
21
|
|
|
19
22
|
def main(
|
|
20
23
|
cloud: Annotated[Optional[str], typer.Option(..., "--cloud", "-c", help="Cloud storage profile name. If not provided, uses default from config.")] = None,
|
|
21
24
|
repo: Annotated[Optional[str], typer.Option(..., "--repo", "-r", help="Path to the local repository. Defaults to current working directory.")] = None,
|
|
22
25
|
message: Annotated[Optional[str], typer.Option(..., "--message", "-m", help="Commit message for local changes.")] = None,
|
|
23
|
-
on_conflict: Annotated[Literal["ask", "
|
|
26
|
+
on_conflict: Annotated[Literal["ask", "a",
|
|
27
|
+
"push-local-merge", "p",
|
|
28
|
+
"overwrite-local", "o",
|
|
29
|
+
"stop-on-conflict", "s",
|
|
30
|
+
"remove-rclone-conflict", "r"
|
|
31
|
+
], typer.Option(..., "--on-conflict", "-o", help="Action to take on merge conflict. Default is 'ask'.")] = "ask",
|
|
24
32
|
pwd: Annotated[Optional[str], typer.Option(..., "--password", help="Password for encryption/decryption of the remote repository.")] = None,
|
|
25
33
|
):
|
|
34
|
+
on_conflict_mapper: dict[str, Literal["ask", "push-local-merge", "overwrite-local", "stop-on-conflict", "remove-rclone-conflict"]] = {
|
|
35
|
+
"a": "ask",
|
|
36
|
+
"ask": "ask",
|
|
37
|
+
"p": "push-local-merge",
|
|
38
|
+
"push-local-merge": "push-local-merge",
|
|
39
|
+
"o": "overwrite-local",
|
|
40
|
+
"overwrite-local": "overwrite-local",
|
|
41
|
+
"s": "stop-on-conflict",
|
|
42
|
+
"stop-on-conflict": "stop-on-conflict",
|
|
43
|
+
"r": "remove-rclone-conflict",
|
|
44
|
+
"remove-rclone-conflict": "remove-rclone-conflict",
|
|
45
|
+
}
|
|
46
|
+
on_conflict = on_conflict_mapper[on_conflict]
|
|
47
|
+
import platform
|
|
48
|
+
import git
|
|
49
|
+
from rich.console import Console
|
|
50
|
+
from rich.panel import Panel
|
|
51
|
+
|
|
52
|
+
from machineconfig.utils.path_extended import PathExtended
|
|
53
|
+
from machineconfig.utils.terminal import Response
|
|
54
|
+
from machineconfig.utils.source_of_truth import CONFIG_ROOT, DEFAULTS_PATH
|
|
55
|
+
from machineconfig.utils.code import get_uv_command_executing_python_script
|
|
56
|
+
from pathlib import Path
|
|
57
|
+
import subprocess
|
|
58
|
+
console = Console()
|
|
59
|
+
|
|
60
|
+
def _bash_single_quote(val: str) -> str:
|
|
61
|
+
return "'" + val.replace("'", "'\"'\"'") + "'"
|
|
62
|
+
|
|
63
|
+
def _ps_single_quote(val: str) -> str:
|
|
64
|
+
return "'" + val.replace("'", "''") + "'"
|
|
65
|
+
|
|
26
66
|
if cloud is None:
|
|
27
67
|
try:
|
|
28
68
|
from machineconfig.utils.io import read_ini
|
|
@@ -35,10 +75,17 @@ def main(
|
|
|
35
75
|
else:
|
|
36
76
|
cloud_resolved = cloud
|
|
37
77
|
repo_local_root = PathExtended.cwd() if repo is None else PathExtended(repo).expanduser().absolute()
|
|
38
|
-
|
|
78
|
+
try:
|
|
79
|
+
repo_local_obj = git.Repo(repo_local_root, search_parent_directories=True)
|
|
80
|
+
except git.InvalidGitRepositoryError:
|
|
81
|
+
msg = typer.style("Error: ", fg=typer.colors.RED) + f"The specified path '{repo_local_root}' is not a valid git repository."
|
|
82
|
+
typer.echo(msg)
|
|
83
|
+
typer.Exit(code=1)
|
|
84
|
+
return ""
|
|
39
85
|
repo_local_root = PathExtended(repo_local_obj.working_dir) # cwd might have been in a sub directory of repo_root, so its better to redefine it.
|
|
86
|
+
local_relative_home = PathExtended(repo_local_root.expanduser().absolute().relative_to(Path.home()))
|
|
40
87
|
PathExtended(CONFIG_ROOT).joinpath("remote").mkdir(parents=True, exist_ok=True)
|
|
41
|
-
repo_remote_root = PathExtended(CONFIG_ROOT).joinpath("remote",
|
|
88
|
+
repo_remote_root = PathExtended(CONFIG_ROOT).joinpath("remote", local_relative_home)
|
|
42
89
|
repo_remote_root.delete(sure=True)
|
|
43
90
|
try:
|
|
44
91
|
console.print(Panel("📥 DOWNLOADING REMOTE REPOSITORY", title_align="left", border_style="blue"))
|
|
@@ -55,43 +102,89 @@ def main(
|
|
|
55
102
|
if repo_remote_obj.is_dirty():
|
|
56
103
|
console.print(Panel(f"⚠️ WARNING: REMOTE REPOSITORY IS DIRTY\nLocation: {repo_remote_root}\nPlease commit or stash changes before proceeding.", title="Warning", border_style="yellow"))
|
|
57
104
|
|
|
58
|
-
|
|
105
|
+
message_resolved = "sync" if message is None or message.strip() == "" else message
|
|
106
|
+
|
|
107
|
+
repo_local_root_str = str(repo_local_root)
|
|
108
|
+
repo_remote_root_str = str(repo_remote_root)
|
|
109
|
+
|
|
110
|
+
script_bash = f"""
|
|
59
111
|
echo ""
|
|
60
|
-
echo
|
|
61
|
-
cd {
|
|
112
|
+
echo -e "\\033[1;34m═════ COMMITTING LOCAL CHANGES ═════\\033[0m"
|
|
113
|
+
cd {_bash_single_quote(repo_local_root_str)}
|
|
62
114
|
git status
|
|
63
|
-
git add
|
|
64
|
-
git
|
|
115
|
+
git add -A
|
|
116
|
+
if git diff --cached --quiet; then
|
|
117
|
+
echo "-> No staged changes to commit."
|
|
118
|
+
else
|
|
119
|
+
git commit -m {_bash_single_quote(message_resolved)} || true
|
|
120
|
+
fi
|
|
65
121
|
echo ""
|
|
66
122
|
echo ""
|
|
67
|
-
echo
|
|
68
|
-
cd {
|
|
69
|
-
echo
|
|
70
|
-
# git remote remove originEnc
|
|
123
|
+
echo -e "\\033[1;34m═════ PULLING LATEST FROM REMOTE ═════\\033[0m"
|
|
124
|
+
cd {_bash_single_quote(repo_local_root_str)}
|
|
125
|
+
echo "-> Trying to removing originEnc remote from local repo if it exists."
|
|
71
126
|
git remote remove originEnc 2>/dev/null || true
|
|
72
|
-
echo
|
|
73
|
-
git remote add originEnc {
|
|
74
|
-
echo
|
|
127
|
+
echo "-> Adding originEnc remote to local repo"
|
|
128
|
+
git remote add originEnc {_bash_single_quote(repo_remote_root_str)}
|
|
129
|
+
echo "-> Fetching originEnc remote."
|
|
75
130
|
git pull originEnc master
|
|
76
131
|
|
|
77
132
|
"""
|
|
78
133
|
|
|
134
|
+
script_powershell = f"""
|
|
135
|
+
Write-Host ""
|
|
136
|
+
Write-Host "═════ COMMITTING LOCAL CHANGES ═════" -ForegroundColor Blue
|
|
137
|
+
Set-Location -LiteralPath {_ps_single_quote(repo_local_root_str)}
|
|
138
|
+
git status
|
|
139
|
+
git add -A
|
|
140
|
+
git diff --cached --quiet
|
|
141
|
+
if ($LASTEXITCODE -eq 0) {{
|
|
142
|
+
Write-Host "-> No staged changes to commit."
|
|
143
|
+
}} else {{
|
|
144
|
+
git commit -m {_ps_single_quote(message_resolved)}
|
|
145
|
+
if ($LASTEXITCODE -ne 0) {{
|
|
146
|
+
Write-Host "-> Commit skipped/failed (continuing)."
|
|
147
|
+
}}
|
|
148
|
+
}}
|
|
149
|
+
|
|
150
|
+
Write-Host ""
|
|
151
|
+
Write-Host ""
|
|
152
|
+
Write-Host "═════ PULLING LATEST FROM REMOTE ═════" -ForegroundColor Blue
|
|
153
|
+
Set-Location -LiteralPath {_ps_single_quote(repo_local_root_str)}
|
|
154
|
+
Write-Host "-> Trying to remove originEnc remote from local repo if it exists."
|
|
155
|
+
git remote remove originEnc 2>$null
|
|
156
|
+
Write-Host "-> Adding originEnc remote to local repo"
|
|
157
|
+
git remote add originEnc {_ps_single_quote(repo_remote_root_str)}
|
|
158
|
+
Write-Host "-> Fetching originEnc remote."
|
|
159
|
+
git pull originEnc master
|
|
160
|
+
exit $LASTEXITCODE
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
script = script_powershell if platform.system() == "Windows" else script_bash
|
|
164
|
+
|
|
79
165
|
if Path.home().joinpath("code/machineconfig").exists():
|
|
80
166
|
uv_project_dir = f"""{str(Path.home().joinpath("code/machineconfig"))}"""
|
|
81
167
|
uv_with = None
|
|
82
168
|
else:
|
|
83
|
-
uv_with = [
|
|
169
|
+
uv_with = [MACHINECONFIG_VERSION]
|
|
84
170
|
uv_project_dir = None
|
|
85
171
|
|
|
86
|
-
|
|
87
|
-
shell_path = Path(tempfile.mkstemp(suffix=".ps1" if platform.system() == "Windows" else ".sh")[1])
|
|
172
|
+
shell_path = get_tmp_file()
|
|
88
173
|
shell_path.write_text(script, encoding="utf-8")
|
|
89
|
-
|
|
90
|
-
command = f". {shell_path}"
|
|
91
174
|
if platform.system() == "Windows":
|
|
92
|
-
completed = subprocess.run(
|
|
175
|
+
completed = subprocess.run(
|
|
176
|
+
["powershell", "-ExecutionPolicy", "Bypass", "-File", str(shell_path)],
|
|
177
|
+
capture_output=True,
|
|
178
|
+
check=False,
|
|
179
|
+
text=True,
|
|
180
|
+
)
|
|
93
181
|
else:
|
|
94
|
-
completed = subprocess.run(
|
|
182
|
+
completed = subprocess.run(
|
|
183
|
+
["bash", str(shell_path)],
|
|
184
|
+
capture_output=True,
|
|
185
|
+
check=False,
|
|
186
|
+
text=True,
|
|
187
|
+
)
|
|
95
188
|
res = Response.from_completed_process(completed).capture().print()
|
|
96
189
|
|
|
97
190
|
if res.is_successful(strict_err=True, strict_returcode=True):
|
|
@@ -109,46 +202,64 @@ git pull originEnc master
|
|
|
109
202
|
option1 = "Delete remote copy and push local:"
|
|
110
203
|
from machineconfig.utils.meta import lambda_to_python_script
|
|
111
204
|
def func2(remote_repo: str, local_repo: str, cloud: str):
|
|
112
|
-
from machineconfig.scripts.python.helpers_repos.sync import delete_remote_repo_copy_and_push_local
|
|
205
|
+
from machineconfig.scripts.python.helpers.helpers_repos.sync import delete_remote_repo_copy_and_push_local
|
|
113
206
|
delete_remote_repo_copy_and_push_local(remote_repo=remote_repo, local_repo=local_repo, cloud=cloud)
|
|
114
|
-
program_1_py = lambda_to_python_script(lambda: func2(remote_repo=str(repo_remote_root), local_repo=str(repo_local_root), cloud=str(cloud_resolved)),
|
|
207
|
+
program_1_py = lambda_to_python_script(lambda: func2(remote_repo=str(repo_remote_root), local_repo=str(repo_local_root), cloud=str(cloud_resolved)),
|
|
208
|
+
in_global=True, import_module=False)
|
|
115
209
|
program1, _pyfile1 = get_uv_command_executing_python_script(python_script=program_1_py, uv_with=uv_with, uv_project_dir=uv_project_dir)
|
|
116
210
|
# ================================================================================
|
|
211
|
+
|
|
117
212
|
option2 = "Delete local repo and replace it with remote copy:"
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
213
|
+
if platform.system() == "Windows":
|
|
214
|
+
program_2 = f"""
|
|
215
|
+
Remove-Item -LiteralPath {_ps_single_quote(repo_local_root_str)} -Recurse -Force -ErrorAction SilentlyContinue
|
|
216
|
+
Move-Item -LiteralPath {_ps_single_quote(repo_remote_root_str)} -Destination {_ps_single_quote(repo_local_root_str)} -Force
|
|
217
|
+
"""
|
|
218
|
+
else:
|
|
219
|
+
program_2 = f"""
|
|
220
|
+
rm -rfd {_bash_single_quote(repo_local_root_str)}
|
|
221
|
+
mv {_bash_single_quote(repo_remote_root_str)} {_bash_single_quote(repo_local_root_str)}
|
|
222
|
+
"""
|
|
122
223
|
if platform.system() in ["Linux", "Darwin"]:
|
|
123
224
|
program_2 += """
|
|
124
225
|
sudo chmod 600 $HOME/.ssh/*
|
|
125
226
|
sudo chmod 700 $HOME/.ssh
|
|
126
227
|
sudo chmod +x $HOME/dotfiles/scripts/linux -R
|
|
127
228
|
"""
|
|
128
|
-
|
|
129
|
-
shell_file_2 = Path(tempfile.mkstemp(suffix=".ps1" if platform.system() == "Windows" else ".sh")[1])
|
|
229
|
+
shell_file_2 = get_tmp_file()
|
|
130
230
|
shell_file_2.write_text(program_2, encoding="utf-8")
|
|
131
231
|
|
|
132
232
|
# ================================================================================
|
|
133
233
|
option3 = "Inspect repos:"
|
|
134
234
|
def func(repo_local_root: str, repo_remote_root: str):
|
|
135
|
-
from machineconfig.scripts.python.helpers_repos.sync import inspect_repos
|
|
235
|
+
from machineconfig.scripts.python.helpers.helpers_repos.sync import inspect_repos
|
|
136
236
|
inspect_repos(repo_local_root=repo_local_root, repo_remote_root=repo_remote_root)
|
|
137
237
|
# program_3_py = function_to_script(func=func, call_with_kwargs={"repo_local_root": str(repo_local_root), "repo_remote_root": str(repo_remote_root)})
|
|
138
238
|
# shell_file_3 = get_shell_file_executing_python_script(python_script=program_3_py, ve_path=None, executable=executable)
|
|
139
|
-
program_3_py = lambda_to_python_script(lambda: func(repo_local_root=str(repo_local_root), repo_remote_root=str(repo_remote_root)),
|
|
239
|
+
program_3_py = lambda_to_python_script(lambda: func(repo_local_root=str(repo_local_root), repo_remote_root=str(repo_remote_root)),
|
|
240
|
+
in_global=True, import_module=False)
|
|
140
241
|
program3, _pyfile3 = get_uv_command_executing_python_script(python_script=program_3_py, uv_with=uv_with, uv_project_dir=uv_project_dir)
|
|
141
242
|
# ================================================================================
|
|
142
243
|
|
|
143
244
|
option4 = "Remove problematic rclone file from repo and replace with remote:"
|
|
144
|
-
|
|
245
|
+
if platform.system() == "Windows":
|
|
246
|
+
program_4 = f"""
|
|
247
|
+
Remove-Item -LiteralPath "$HOME/dotfiles/creds/rclone/rclone.conf" -Force -ErrorAction SilentlyContinue
|
|
248
|
+
New-Item -ItemType Directory -Path "$HOME/dotfiles/creds/rclone" -Force | Out-Null
|
|
249
|
+
Copy-Item -LiteralPath "$HOME/.config/machineconfig/remote/dotfiles/creds/rclone/rclone.conf" -Destination "$HOME/dotfiles/creds/rclone/rclone.conf" -Force
|
|
250
|
+
Set-Location -LiteralPath "$HOME/dotfiles"
|
|
251
|
+
git commit -am "finished merging"
|
|
252
|
+
{program1}
|
|
253
|
+
"""
|
|
254
|
+
else:
|
|
255
|
+
program_4 = f"""
|
|
145
256
|
rm $HOME/dotfiles/creds/rclone/rclone.conf
|
|
146
257
|
cp $HOME/.config/machineconfig/remote/dotfiles/creds/rclone/rclone.conf $HOME/dotfiles/creds/rclone
|
|
147
258
|
cd $HOME/dotfiles
|
|
148
259
|
git commit -am "finished merging"
|
|
149
260
|
{program1}
|
|
150
|
-
"""
|
|
151
|
-
shell_file_4 =
|
|
261
|
+
"""
|
|
262
|
+
shell_file_4 = get_tmp_file()
|
|
152
263
|
shell_file_4.write_text(program_4, encoding="utf-8")
|
|
153
264
|
# ================================================================================
|
|
154
265
|
|
|
@@ -186,6 +297,6 @@ git commit -am "finished merging"
|
|
|
186
297
|
case _:
|
|
187
298
|
raise ValueError(f"Unknown action: {on_conflict}")
|
|
188
299
|
from machineconfig.utils.code import run_shell_script
|
|
189
|
-
run_shell_script(script=program_content)
|
|
300
|
+
run_shell_script(script=program_content, display_script=True, clean_env=False)
|
|
190
301
|
return program_content
|
|
191
302
|
|
|
@@ -100,7 +100,7 @@ def install_gource_windows(version: Optional[str] = None) -> None:
|
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
def visualize(
|
|
103
|
-
repo: Annotated[str, typer.Option("--repo", "-r", help="Path to git repository to visualize")] =
|
|
103
|
+
repo: Annotated[str, typer.Option("--repo", "-r", help="Path to git repository to visualize")] = ".",
|
|
104
104
|
output_file: Annotated[Optional[Path], typer.Option("--output", "-o", help="Output video file (e.g., output.mp4). If specified, gource will render to video.")] = None,
|
|
105
105
|
resolution: Annotated[str, typer.Option("--resolution", "-res", help="Video resolution (e.g., 1920x1080, 1280x720)")] = "1920x1080",
|
|
106
106
|
seconds_per_day: Annotated[float, typer.Option("--seconds-per-day", "-spd", help="Speed of simulation (lower = faster)")] = 0.1,
|
|
@@ -169,7 +169,7 @@ def visualize(
|
|
|
169
169
|
if platform.system() == "Windows":
|
|
170
170
|
print(f"⚠️ Portable gource not found at {gource_exe}, installing...")
|
|
171
171
|
install_gource_windows()
|
|
172
|
-
#
|
|
172
|
+
gource_exe = get_gource_executable() # Re-fetch path after installation
|
|
173
173
|
if gource_exe.exists():
|
|
174
174
|
print(f"✅ Gource installed successfully at: {gource_exe}")
|
|
175
175
|
gource_cmd: str = str(gource_exe)
|
|
@@ -177,7 +177,8 @@ def visualize(
|
|
|
177
177
|
print("❌ Installation failed, falling back to system gource")
|
|
178
178
|
raise typer.Exit(1)
|
|
179
179
|
else:
|
|
180
|
-
|
|
180
|
+
print(f"❌ Error: Gource executable not found at {gource_exe}. Please install gource using your package manager.")
|
|
181
|
+
raise typer.Exit(1)
|
|
181
182
|
else:
|
|
182
183
|
gource_cmd = str(gource_exe)
|
|
183
184
|
|
|
@@ -3,7 +3,6 @@ from pathlib import Path
|
|
|
3
3
|
from machineconfig.utils.schemas.repos.repos_types import GitVersionInfo, RepoRecordDict, RepoRemote
|
|
4
4
|
|
|
5
5
|
from machineconfig.utils.schemas.repos.repos_types import RepoRecordFile
|
|
6
|
-
from machineconfig.utils.source_of_truth import CONFIG_ROOT
|
|
7
6
|
from machineconfig.utils.io import save_json
|
|
8
7
|
|
|
9
8
|
from typing import Optional
|
|
@@ -12,7 +11,7 @@ from rich import print as pprint
|
|
|
12
11
|
from rich.progress import Progress, TaskID, SpinnerColumn, TextColumn, BarColumn, TimeElapsedColumn, MofNCompleteColumn
|
|
13
12
|
|
|
14
13
|
|
|
15
|
-
def build_tree_structure(repos: list[RepoRecordDict], repos_root:
|
|
14
|
+
def build_tree_structure(repos: list[RepoRecordDict], repos_root: Path) -> str:
|
|
16
15
|
"""Build a tree structure representation of all repositories."""
|
|
17
16
|
if not repos:
|
|
18
17
|
return "No repositories found."
|
|
@@ -186,10 +185,18 @@ def record_repos_recursively(repos_root: str, r: bool, progress: Progress | None
|
|
|
186
185
|
return res
|
|
187
186
|
|
|
188
187
|
|
|
189
|
-
def
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
def _resolve_directory(directory: Optional[str]) -> Path:
|
|
189
|
+
import typer
|
|
190
|
+
if directory is None:
|
|
191
|
+
directory = Path.cwd().as_posix()
|
|
192
|
+
typer.echo(f"📁 Using directory: {directory}")
|
|
193
|
+
return Path(directory).expanduser().absolute().resolve()
|
|
194
|
+
|
|
192
195
|
|
|
196
|
+
def main_record(repos_root_str: Optional[str]) -> Path:
|
|
197
|
+
print("\n📝 Recording repositories...")
|
|
198
|
+
repos_root = _resolve_directory(directory=repos_root_str)
|
|
199
|
+
|
|
193
200
|
# Count total directories and repositories for accurate progress tracking
|
|
194
201
|
print("🔍 Analyzing directory structure...")
|
|
195
202
|
total_dirs = count_total_directories(str(repos_root), r=True)
|
|
@@ -222,7 +229,7 @@ def main_record(repos_root: Path):
|
|
|
222
229
|
if repos_with_no_remotes:
|
|
223
230
|
print(f"\n⚠️ WARNING: {len(repos_with_no_remotes)} repositories have no remotes configured:")
|
|
224
231
|
for repo in repos_with_no_remotes:
|
|
225
|
-
repo_path =
|
|
232
|
+
repo_path = Path(repo["parentDir"]).joinpath(repo["name"])
|
|
226
233
|
print(f" • {repo['name']} ({repo_path})")
|
|
227
234
|
print(" These repositories may be local-only or have configuration issues.")
|
|
228
235
|
else:
|
|
@@ -231,7 +238,7 @@ def main_record(repos_root: Path):
|
|
|
231
238
|
if dirty_repos:
|
|
232
239
|
print(f"\n⚠️ WARNING: {len(dirty_repos)} repositories have uncommitted changes:")
|
|
233
240
|
for repo in dirty_repos:
|
|
234
|
-
repo_path =
|
|
241
|
+
repo_path = Path(repo["parentDir"]).joinpath(repo["name"])
|
|
235
242
|
print(f" • {repo['name']} ({repo_path}) [branch: {repo['currentBranch']}]")
|
|
236
243
|
print(" These repositories have uncommitted changes that may need attention.")
|
|
237
244
|
else:
|
|
@@ -239,11 +246,25 @@ def main_record(repos_root: Path):
|
|
|
239
246
|
|
|
240
247
|
# Display repository tree structure
|
|
241
248
|
print("\n🌳 Repository Tree Structure:")
|
|
242
|
-
tree_structure = build_tree_structure(repo_records, repos_root)
|
|
249
|
+
tree_structure = build_tree_structure(repos=repo_records, repos_root=repos_root)
|
|
243
250
|
print(tree_structure)
|
|
244
251
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
252
|
+
spec_path_default = Path(repos_root).expanduser().absolute().joinpath("repos.json")
|
|
253
|
+
from machineconfig.scripts.python.helpers.helpers_devops.cli_config_dotfile import get_backup_path, record_mapping
|
|
254
|
+
spec_path_self_managed = get_backup_path(
|
|
255
|
+
orig_path=spec_path_default,
|
|
256
|
+
sensitivity="private",
|
|
257
|
+
destination=None,
|
|
258
|
+
shared=False,
|
|
259
|
+
)
|
|
260
|
+
save_json(obj=res, path=spec_path_self_managed, indent=4)
|
|
261
|
+
pprint(f"📁 Result saved at {PathExtended(spec_path_self_managed)}")
|
|
262
|
+
|
|
263
|
+
# record_mapping(
|
|
264
|
+
# orig_path=spec_path_default,
|
|
265
|
+
|
|
266
|
+
# )
|
|
267
|
+
_ = record_mapping
|
|
268
|
+
|
|
248
269
|
print(">>>>>>>>> Finished Recording")
|
|
249
|
-
return
|
|
270
|
+
return spec_path_self_managed
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
|
|
5
|
+
from git import Repo
|
|
6
|
+
from collections import defaultdict
|
|
7
|
+
from datetime import datetime, date
|
|
8
|
+
from typing import Any, Dict, List, Optional, Union
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def count_historical_line_edits(repo_path: str) -> int:
|
|
14
|
+
|
|
15
|
+
repo = Repo(repo_path)
|
|
16
|
+
last_commit = next(repo.iter_commits())
|
|
17
|
+
total_lines, total_files = count_python_lines(last_commit)
|
|
18
|
+
print(f"Total lines of Python code in latest commit ({last_commit.hexsha[:8]}): {total_lines} across {total_files} files")
|
|
19
|
+
|
|
20
|
+
gitcs_viz(repo_path=repo_path, pull_full_history=True)
|
|
21
|
+
|
|
22
|
+
file_line_counts: "Dict[str, int]" = defaultdict(int)
|
|
23
|
+
total_commits: int = sum(1 for _ in repo.iter_commits())
|
|
24
|
+
print(f"Total commits to process: {total_commits}")
|
|
25
|
+
for i, commit in enumerate(repo.iter_commits(), 1):
|
|
26
|
+
if i % 100 == 0 or i == total_commits:
|
|
27
|
+
print(f"Processing commit {i}/{total_commits} ({i / total_commits:.1%})")
|
|
28
|
+
try:
|
|
29
|
+
# Handle initial commits that have no parents
|
|
30
|
+
if not commit.parents:
|
|
31
|
+
# For initial commit, count all lines in Python files
|
|
32
|
+
for file in commit.stats.files:
|
|
33
|
+
if str(file).endswith(".py"):
|
|
34
|
+
file_line_counts[str(file)] += commit.stats.files[file]["insertions"]
|
|
35
|
+
else:
|
|
36
|
+
# For commits with parents, use stats
|
|
37
|
+
for file in commit.stats.files:
|
|
38
|
+
if str(file).endswith(".py"):
|
|
39
|
+
file_line_counts[str(file)] += commit.stats.files[file]["insertions"]
|
|
40
|
+
except Exception:
|
|
41
|
+
# If stats fail (e.g., corrupted parent), skip this commit
|
|
42
|
+
print(f"Warning: Could not get stats for commit {commit.hexsha[:8]}, skipping")
|
|
43
|
+
continue
|
|
44
|
+
|
|
45
|
+
print(f"\nProcessed files: {len(file_line_counts)}")
|
|
46
|
+
res = sum(file_line_counts.values())
|
|
47
|
+
print(f"Total historical lines of Python code: {res}")
|
|
48
|
+
return res
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def count_lines_changed_in_commit(commit: "Any") -> int:
|
|
54
|
+
_total_lines = 0
|
|
55
|
+
for _file in commit.stats.files:
|
|
56
|
+
if str(_file).endswith(".py"):
|
|
57
|
+
_blob = commit.tree / _file
|
|
58
|
+
_total_lines += len(_blob.data_stream.read().decode("utf-8").splitlines())
|
|
59
|
+
return _total_lines
|
|
60
|
+
def count_python_lines(commit: "Any") -> tuple[int, int]:
|
|
61
|
+
"""Count total lines in Python files for a specific commit"""
|
|
62
|
+
total_lines = 0
|
|
63
|
+
total_files = 0
|
|
64
|
+
try:
|
|
65
|
+
for blob in commit.tree.traverse():
|
|
66
|
+
if blob.path.endswith(".py"):
|
|
67
|
+
try:
|
|
68
|
+
content = blob.data_stream.read().decode("utf-8")
|
|
69
|
+
total_lines += len(content.splitlines())
|
|
70
|
+
total_files += 1
|
|
71
|
+
except Exception as _e:
|
|
72
|
+
continue
|
|
73
|
+
except Exception as e:
|
|
74
|
+
print(f"Error traversing commit {commit.hexsha[:8]}: {e}")
|
|
75
|
+
pass
|
|
76
|
+
return total_lines, total_files
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def get_default_branch(repo: Repo) -> str:
|
|
80
|
+
"""Get the default branch name of the repository"""
|
|
81
|
+
try:
|
|
82
|
+
_ = repo.refs["main"]
|
|
83
|
+
return "main" # First try 'main'
|
|
84
|
+
except IndexError:
|
|
85
|
+
try:
|
|
86
|
+
_ = repo.refs["master"]
|
|
87
|
+
return "master" # Then try 'master'
|
|
88
|
+
except IndexError:
|
|
89
|
+
return repo.head.reference.name # If neither exists, get the branch the HEAD is pointing to
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def gitcs_viz(repo_path: Union[str, Path], email: Optional[str] = None, pull_full_history: bool = False) -> None:
|
|
94
|
+
"""Invoke the gitcs CLI across 6-month windows covering the repo history.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
repo_path: Path to the git repository
|
|
98
|
+
email: Optional email filter for gitcs
|
|
99
|
+
pull_full_history: If True, unshallow the repo to fetch full history (useful for shallow clones)
|
|
100
|
+
"""
|
|
101
|
+
from machineconfig.utils.installer_utils.installer_cli import install_if_missing
|
|
102
|
+
install_if_missing("gitcs")
|
|
103
|
+
|
|
104
|
+
repo_path = Path(repo_path).expanduser().resolve()
|
|
105
|
+
repo = Repo(repo_path)
|
|
106
|
+
|
|
107
|
+
# Check if repo is shallow and optionally unshallow it
|
|
108
|
+
if pull_full_history:
|
|
109
|
+
shallow_file = Path(repo.git_dir) / "shallow"
|
|
110
|
+
if shallow_file.exists():
|
|
111
|
+
print("🔄 Detected shallow clone. Fetching full history...")
|
|
112
|
+
try:
|
|
113
|
+
repo.git.fetch("--unshallow")
|
|
114
|
+
print("✅ Successfully fetched full history")
|
|
115
|
+
except Exception as e:
|
|
116
|
+
print(f"⚠️ Failed to unshallow repository: {e}")
|
|
117
|
+
print("Continuing with available history...")
|
|
118
|
+
else:
|
|
119
|
+
print("ℹ️ Repository already has full history")
|
|
120
|
+
|
|
121
|
+
branch_name = get_default_branch(repo)
|
|
122
|
+
commits: "List[Any]" = list(repo.iter_commits(branch_name))
|
|
123
|
+
if not commits:
|
|
124
|
+
print("⚠️ No commits found; skipping gitcs visualization.")
|
|
125
|
+
return
|
|
126
|
+
|
|
127
|
+
from datetime import timezone
|
|
128
|
+
|
|
129
|
+
commit_dates = [datetime.fromtimestamp(commit.committed_date, tz=timezone.utc).date() for commit in commits]
|
|
130
|
+
min_year = min(commit_dates).year
|
|
131
|
+
max_year = max(commit_dates).year
|
|
132
|
+
|
|
133
|
+
print(f"📆 gitcs windows: {min_year}-01-01 → {max_year}-12-31 (fixed half-year slices)")
|
|
134
|
+
|
|
135
|
+
chunk_idx = 1
|
|
136
|
+
for year in range(min_year, max_year + 1):
|
|
137
|
+
windows = [(date(year, 1, 1), date(year, 6, 30)), (date(year, 7, 1), date(year, 12, 31))]
|
|
138
|
+
for chunk_start, chunk_end in windows:
|
|
139
|
+
cmd = ["gitcs", "--since", chunk_start.isoformat(), "--until", chunk_end.isoformat()]
|
|
140
|
+
if email:
|
|
141
|
+
cmd.extend(["--email", email])
|
|
142
|
+
|
|
143
|
+
print(f"\n===== gitcs chunk {chunk_idx}: {chunk_start.isoformat()} → {chunk_end.isoformat()} =====")
|
|
144
|
+
try:
|
|
145
|
+
completed = subprocess.run(cmd, cwd=str(repo_path), capture_output=True, text=True, input=f"{repo_path}\n")
|
|
146
|
+
except FileNotFoundError:
|
|
147
|
+
print("❌ gitcs CLI is not available on PATH; aborting visualization.")
|
|
148
|
+
return
|
|
149
|
+
|
|
150
|
+
if completed.stdout.strip():
|
|
151
|
+
print(completed.stdout.strip())
|
|
152
|
+
if completed.stderr.strip():
|
|
153
|
+
print(completed.stderr.strip())
|
|
154
|
+
if completed.returncode != 0:
|
|
155
|
+
print(f"⚠️ gitcs exited with code {completed.returncode} for this range.")
|
|
156
|
+
|
|
157
|
+
chunk_idx += 1
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|