machineconfig 6.23__py3-none-any.whl → 8.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/remote/cloud_manager.py +1 -1
- machineconfig/cluster/remote/distribute.py +0 -1
- machineconfig/cluster/remote/file_manager.py +0 -2
- machineconfig/cluster/sessions_managers/{utils → helpers}/enhanced_command_runner.py +4 -6
- machineconfig/cluster/sessions_managers/utils/load_balancer.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +69 -0
- machineconfig/cluster/sessions_managers/wt_local.py +16 -221
- machineconfig/cluster/sessions_managers/wt_local_manager.py +55 -193
- 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 +3 -3
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +5 -3
- machineconfig/cluster/sessions_managers/zellij_remote.py +2 -2
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +3 -2
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +2 -2
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +3 -7
- machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_helper_with_panes.py +1 -1
- machineconfig/jobs/installer/check_installations.py +0 -1
- machineconfig/jobs/installer/installer_data.json +1408 -201
- machineconfig/jobs/installer/linux_scripts/q.sh +10 -7
- machineconfig/jobs/installer/linux_scripts/redis.sh +1 -0
- machineconfig/jobs/installer/package_groups.py +63 -92
- machineconfig/jobs/installer/powershell_scripts/install_fonts.ps1 +129 -34
- machineconfig/jobs/installer/python_scripts/boxes.py +61 -0
- 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 +4 -1
- machineconfig/jobs/installer/{custom_dev → python_scripts}/dubdb_adbc.py +1 -1
- machineconfig/jobs/installer/{custom → python_scripts}/hx.py +75 -18
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerdfont.py +2 -2
- machineconfig/jobs/installer/{custom_dev → python_scripts}/nerfont_windows_helper.py +27 -22
- machineconfig/jobs/installer/python_scripts/sysabc.py +139 -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 +121 -0
- machineconfig/{scripts/python/nw → jobs/scripts/bash_scripts}/mount_nfs +0 -1
- 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 +25 -0
- machineconfig/logger.py +0 -1
- machineconfig/profile/create_helper.py +56 -18
- machineconfig/profile/create_links.py +2 -1
- machineconfig/profile/create_links_export.py +64 -18
- machineconfig/profile/create_shell_profile.py +90 -132
- machineconfig/profile/mapper.toml +18 -8
- 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 +82 -60
- machineconfig/scripts/python/ai/initai.py +1 -19
- 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.sh +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 +5 -5
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +4 -0
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/watch_exec.prompt.md +20 -0
- machineconfig/scripts/python/ai/solutions/generic.py +1 -1
- machineconfig/scripts/python/ai/{generate_files.py → utils/generate_files.py} +2 -2
- machineconfig/scripts/python/ai/{vscode_tasks.py → utils/vscode_tasks.py} +7 -2
- machineconfig/scripts/python/cloud.py +14 -9
- machineconfig/scripts/python/croshell.py +135 -117
- machineconfig/scripts/python/devops.py +48 -25
- machineconfig/scripts/python/devops_navigator.py +1 -5
- machineconfig/scripts/python/env_manager/env_manager_tui.py +204 -0
- machineconfig/scripts/python/env_manager/path_manager_tui.py +18 -9
- machineconfig/scripts/python/fire_jobs.py +127 -118
- machineconfig/scripts/python/ftpx.py +44 -17
- machineconfig/scripts/python/helpers/ast_search.py +74 -0
- machineconfig/scripts/python/helpers/qr_code.py +166 -0
- machineconfig/scripts/python/helpers/repo_rag.py +325 -0
- machineconfig/scripts/python/helpers/symantic_search.py +25 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents}/agentic_frameworks/fire_crush.json +1 -1
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_crush.py +39 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents}/agentic_frameworks/fire_cursor_agents.py +3 -4
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_gemini.py +55 -0
- machineconfig/scripts/python/helpers_agents/agentic_frameworks/fire_qwen.py +30 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_help_launch.py +37 -15
- machineconfig/scripts/python/helpers_agents/fire_agents_helper_types.py +41 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/aichat/config.yaml +5 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/aider/.aider.conf.yml +2 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/copilot/config.yml +1 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/crush/crush.json +10 -0
- machineconfig/scripts/python/helpers_agents/privacy/configs/gemini/settings.json +12 -0
- machineconfig/scripts/python/helpers_agents/privacy/privacy.py +109 -0
- machineconfig/scripts/python/helpers_agents/templates/prompt.txt +10 -0
- machineconfig/scripts/python/helpers_agents/templates/template.sh +34 -0
- machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_copy.py +28 -21
- machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_mount.py +19 -17
- machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_sync.py +12 -11
- machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/helpers2.py +1 -1
- machineconfig/scripts/python/helpers_croshell/crosh.py +39 -0
- machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/start_slidev.py +6 -7
- machineconfig/scripts/python/helpers_devops/cli_config.py +105 -0
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +89 -0
- machineconfig/scripts/python/helpers_devops/cli_data.py +25 -0
- machineconfig/scripts/python/helpers_devops/cli_nw.py +221 -0
- machineconfig/scripts/python/{devops_helpers → helpers_devops}/cli_repos.py +60 -36
- machineconfig/scripts/python/helpers_devops/cli_self.py +172 -0
- machineconfig/scripts/python/helpers_devops/cli_share_file.py +137 -0
- machineconfig/scripts/python/helpers_devops/cli_share_server.py +142 -0
- machineconfig/scripts/python/{devops_helpers/cli_terminal.py → helpers_devops/cli_share_terminal.py} +15 -17
- machineconfig/scripts/python/{devops_helpers → helpers_devops}/devops_backup_retrieve.py +7 -10
- machineconfig/scripts/python/{devops_helpers → helpers_devops}/devops_status.py +7 -19
- machineconfig/scripts/python/{devops_helpers → helpers_devops}/devops_update_repos.py +1 -1
- machineconfig/scripts/python/helpers_devops/run_script.py +168 -0
- machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +3 -0
- machineconfig/scripts/python/{devops_helpers → helpers_devops}/themes/choose_wezterm_theme.py +1 -1
- machineconfig/scripts/python/{helpers_fire/helpers4.py → helpers_fire_command/file_wrangler.py} +57 -20
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_args_helper.py +2 -0
- machineconfig/scripts/python/helpers_fire_command/fire_jobs_route_helper.py +26 -16
- machineconfig/scripts/python/helpers_msearch/__init__.py +5 -0
- machineconfig/scripts/{linux → python/helpers_msearch/scripts_linux}/fzfg +3 -3
- machineconfig/scripts/python/helpers_msearch/scripts_windows/fzfg.ps1 +59 -0
- machineconfig/scripts/python/helpers_navigator/__init__.py +20 -0
- machineconfig/scripts/python/{helper_navigator → helpers_navigator}/command_builder.py +1 -1
- machineconfig/scripts/python/{helper_navigator → helpers_navigator}/command_detail.py +1 -1
- machineconfig/scripts/python/{helper_navigator → helpers_navigator}/command_tree.py +160 -23
- machineconfig/scripts/python/{helper_navigator → helpers_navigator}/main_app.py +5 -5
- machineconfig/scripts/python/helpers_network/address.py +176 -0
- machineconfig/scripts/python/helpers_network/address_switch.py +78 -0
- machineconfig/scripts/python/{nw → helpers_network}/mount_nfs.py +2 -2
- machineconfig/scripts/python/{nw → helpers_network}/mount_ssh.py +1 -1
- machineconfig/scripts/python/{nw/devops_add_identity.py → helpers_network/ssh_add_identity.py} +35 -1
- machineconfig/scripts/python/{nw/devops_add_ssh_key.py → helpers_network/ssh_add_ssh_key.py} +26 -7
- machineconfig/scripts/python/{nw → helpers_network}/ssh_debug_linux.py +7 -7
- machineconfig/scripts/python/{nw → helpers_network}/ssh_debug_windows.py +4 -4
- machineconfig/scripts/python/{nw → helpers_network}/wifi_conn.py +1 -53
- machineconfig/scripts/python/helpers_repos/action.py +209 -0
- machineconfig/scripts/python/helpers_repos/action_helper.py +150 -0
- machineconfig/scripts/python/{repos_helpers → helpers_repos}/clone.py +0 -1
- machineconfig/scripts/python/helpers_repos/cloud_repo_sync.py +80 -37
- machineconfig/scripts/python/{repos_helpers → helpers_repos}/entrypoint.py +5 -5
- machineconfig/scripts/python/helpers_repos/grource.py +2 -2
- machineconfig/scripts/python/{repos_helpers → helpers_repos}/record.py +3 -2
- machineconfig/scripts/python/helpers_repos/repo_analyzer_1.py +160 -0
- machineconfig/scripts/python/{repos_helpers/count_lines.py → helpers_repos/repo_analyzer_2.py} +113 -192
- machineconfig/scripts/python/{repos_helpers → helpers_repos}/sync.py +5 -5
- machineconfig/scripts/python/{sessions_helpers → helpers_sessions}/sessions_multiprocess.py +19 -13
- machineconfig/scripts/python/helpers_utils/download.py +150 -0
- machineconfig/scripts/python/helpers_utils/pdf.py +96 -0
- machineconfig/scripts/python/helpers_utils/python.py +187 -0
- machineconfig/scripts/python/interactive.py +26 -35
- machineconfig/scripts/python/{entry.py → mcfg_entry.py} +24 -10
- machineconfig/scripts/python/msearch.py +72 -0
- machineconfig/scripts/python/sessions.py +101 -38
- machineconfig/scripts/python/terminal.py +136 -0
- machineconfig/scripts/python/utils.py +62 -0
- machineconfig/scripts/windows/wrap_mcfg.ps1 +63 -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/linux/lfrc +10 -11
- machineconfig/settings/lf/windows/lfcd.ps1 +1 -1
- machineconfig/settings/lf/windows/lfrc +15 -17
- machineconfig/settings/lf/windows/mkfile.ps1 +1 -1
- machineconfig/settings/linters/.ruff.toml +1 -1
- machineconfig/settings/marimo/marimo.toml +80 -0
- machineconfig/settings/marimo/snippets/globalize.py +34 -0
- machineconfig/settings/shells/bash/init.sh +57 -10
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +1 -1
- machineconfig/settings/shells/nushell/config.nu +2 -35
- machineconfig/settings/shells/nushell/env.nu +45 -6
- machineconfig/settings/shells/nushell/init.nu +314 -0
- machineconfig/settings/shells/pwsh/init.ps1 +59 -23
- machineconfig/settings/shells/starship/starship.toml +16 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +2 -0
- machineconfig/settings/shells/wt/settings.json +32 -17
- machineconfig/settings/shells/zsh/init.sh +89 -0
- machineconfig/settings/television/cable_unix/alias.toml +8 -0
- machineconfig/settings/television/cable_unix/aws-buckets.toml +14 -0
- machineconfig/settings/television/cable_unix/aws-instances.toml +13 -0
- machineconfig/settings/television/cable_unix/bash-history.toml +8 -0
- machineconfig/settings/television/cable_unix/channels.toml +19 -0
- machineconfig/settings/television/cable_unix/dirs.toml +13 -0
- machineconfig/settings/television/cable_unix/distrobox-list.toml +42 -0
- machineconfig/settings/television/cable_unix/docker-images.toml +13 -0
- machineconfig/settings/television/cable_unix/dotfiles.toml +11 -0
- machineconfig/settings/television/cable_unix/env.toml +17 -0
- machineconfig/settings/television/cable_unix/files.toml +11 -0
- machineconfig/settings/television/cable_unix/fish-history.toml +8 -0
- machineconfig/settings/television/cable_unix/git-branch.toml +11 -0
- machineconfig/settings/television/cable_unix/git-diff.toml +10 -0
- machineconfig/settings/television/cable_unix/git-log.toml +12 -0
- machineconfig/settings/television/cable_unix/git-reflog.toml +12 -0
- machineconfig/settings/television/cable_unix/git-repos.toml +16 -0
- machineconfig/settings/television/cable_unix/guix.toml +20 -0
- machineconfig/settings/television/cable_unix/just-recipes.toml +18 -0
- machineconfig/settings/television/cable_unix/k8s-deployments.toml +36 -0
- machineconfig/settings/television/cable_unix/k8s-pods.toml +50 -0
- machineconfig/settings/television/cable_unix/k8s-services.toml +36 -0
- machineconfig/settings/television/cable_unix/man-pages.toml +24 -0
- machineconfig/settings/television/cable_unix/nu-history.toml +7 -0
- machineconfig/settings/television/cable_unix/procs.toml +20 -0
- machineconfig/settings/television/cable_unix/text.toml +17 -0
- machineconfig/settings/television/cable_unix/tldr.toml +18 -0
- machineconfig/settings/television/cable_unix/zsh-history.toml +9 -0
- machineconfig/settings/television/cable_windows/alias.toml +7 -0
- machineconfig/settings/television/cable_windows/dirs.toml +13 -0
- machineconfig/settings/television/cable_windows/docker-images.toml +13 -0
- machineconfig/settings/television/cable_windows/dotfiles.toml +11 -0
- machineconfig/settings/television/cable_windows/env.toml +17 -0
- machineconfig/settings/television/cable_windows/files.toml +14 -0
- machineconfig/settings/television/cable_windows/git-branch.toml +11 -0
- machineconfig/settings/television/cable_windows/git-diff.toml +10 -0
- machineconfig/settings/television/cable_windows/git-log.toml +11 -0
- machineconfig/settings/television/cable_windows/git-reflog.toml +11 -0
- machineconfig/settings/television/cable_windows/git-repos.toml +15 -0
- machineconfig/settings/television/cable_windows/nu-history.toml +7 -0
- machineconfig/settings/television/cable_windows/pwsh-history.toml +6 -0
- machineconfig/settings/television/cable_windows/text.toml +17 -0
- machineconfig/settings/yazi/init.lua +61 -0
- machineconfig/settings/yazi/keymap_linux.toml +94 -0
- machineconfig/settings/yazi/keymap_windows.toml +78 -0
- machineconfig/settings/yazi/shell/yazi_cd.ps1 +33 -0
- machineconfig/settings/yazi/shell/yazi_cd.sh +8 -0
- machineconfig/settings/yazi/theme.toml +4 -0
- machineconfig/settings/yazi/yazi_linux.toml +84 -0
- machineconfig/settings/yazi/yazi_windows.toml +58 -0
- machineconfig/settings/zellij/layouts/st.kdl +39 -8
- machineconfig/setup_linux/__init__.py +2 -2
- machineconfig/setup_linux/apps_desktop.sh +8 -27
- machineconfig/setup_linux/web_shortcuts/interactive.sh +27 -11
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +31 -0
- machineconfig/setup_mac/__init__.py +16 -0
- machineconfig/setup_mac/apps_gui.sh +248 -0
- machineconfig/setup_mac/ssh/openssh_setup.sh +114 -0
- machineconfig/setup_mac/uv.sh +36 -0
- machineconfig/setup_windows/__init__.py +3 -5
- machineconfig/setup_windows/ssh/openssh-server.ps1 +1 -1
- machineconfig/setup_windows/uv.ps1 +8 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +26 -10
- machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +30 -0
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +17 -0
- machineconfig/utils/accessories.py +7 -5
- machineconfig/utils/code.py +143 -167
- machineconfig/utils/files/art/fat_croco.txt +10 -0
- machineconfig/utils/files/art/halfwit_croco.txt +9 -0
- machineconfig/utils/files/art/happy_croco.txt +22 -0
- machineconfig/utils/files/art/water_croco.txt +11 -0
- machineconfig/utils/files/ascii_art.py +1 -1
- machineconfig/utils/files/headers.py +6 -11
- machineconfig/utils/files/read.py +3 -9
- machineconfig/utils/installer_utils/github_release_bulk.py +156 -119
- machineconfig/utils/installer_utils/install_from_url.py +183 -0
- machineconfig/utils/installer_utils/installer_class.py +44 -101
- machineconfig/utils/installer_utils/installer_cli.py +175 -0
- machineconfig/utils/installer_utils/installer_helper.py +129 -0
- machineconfig/utils/installer_utils/{installer_abc.py → installer_locator_utils.py} +39 -87
- machineconfig/utils/{installer.py → installer_utils/installer_runner.py} +17 -63
- machineconfig/utils/io.py +77 -4
- machineconfig/utils/links.py +56 -38
- machineconfig/utils/meta.py +235 -145
- machineconfig/utils/options.py +46 -18
- machineconfig/utils/options_tv.py +119 -0
- machineconfig/utils/path_extended.py +46 -97
- machineconfig/utils/path_helper.py +76 -23
- machineconfig/utils/procs.py +10 -23
- machineconfig/utils/scheduler.py +84 -115
- machineconfig/utils/scheduling.py +0 -3
- machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
- machineconfig/utils/schemas/layouts/layout_types.py +1 -1
- machineconfig/utils/ssh.py +214 -476
- machineconfig/utils/ssh_utils/abc.py +5 -0
- machineconfig/utils/ssh_utils/copy_from_here.py +111 -0
- machineconfig/utils/ssh_utils/copy_to_here.py +303 -0
- machineconfig/utils/ssh_utils/utils.py +142 -0
- machineconfig/utils/ssh_utils/wsl.py +210 -0
- machineconfig/utils/terminal.py +3 -113
- machineconfig/utils/upgrade_packages.py +114 -28
- machineconfig/utils/ve.py +12 -4
- machineconfig-8.12.dist-info/METADATA +132 -0
- machineconfig-8.12.dist-info/RECORD +504 -0
- {machineconfig-6.23.dist-info → machineconfig-8.12.dist-info}/entry_points.txt +5 -1
- machineconfig/jobs/installer/linux_scripts/pgsql.sh +0 -41
- machineconfig/jobs/installer/linux_scripts/timescaledb.sh +0 -71
- machineconfig/jobs/linux/msc/cli_agents.sh +0 -16
- machineconfig/jobs/python/python_ve_symlink.py +0 -37
- machineconfig/jobs/python/vscode/api.py +0 -57
- machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +0 -12
- machineconfig/jobs/windows/archive/openssh-server_add_key.ps1 +0 -7
- machineconfig/jobs/windows/archive/openssh-server_copy-ssh-id.ps1 +0 -14
- 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/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/devops_helpers/cli_config.py +0 -81
- machineconfig/scripts/python/devops_helpers/cli_config_dotfile.py +0 -84
- machineconfig/scripts/python/devops_helpers/cli_data.py +0 -18
- machineconfig/scripts/python/devops_helpers/cli_nw.py +0 -73
- machineconfig/scripts/python/devops_helpers/cli_self.py +0 -117
- machineconfig/scripts/python/devops_helpers/cli_share_server.py +0 -104
- machineconfig/scripts/python/helper_navigator/__init__.py +0 -20
- 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/fire_agents_helper_types.py +0 -30
- machineconfig/scripts/python/helpers_fire/prompt.txt +0 -2
- machineconfig/scripts/python/helpers_fire/template.sh +0 -15
- machineconfig/scripts/python/helpers_repos/secure_repo.py +0 -15
- machineconfig/scripts/python/nw/add_ssh_key.py +0 -148
- machineconfig/scripts/python/nw/wsl_windows_transfer.py +0 -66
- machineconfig/scripts/python/repos_helpers/action.py +0 -378
- machineconfig/scripts/python/repos_helpers/count_lines_frontend.py +0 -17
- machineconfig/scripts/windows/fzfb.ps1 +0 -3
- machineconfig/scripts/windows/fzfg.ps1 +0 -2
- machineconfig/scripts/windows/fzfrga.bat +0 -20
- 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/shells/pwsh/profile.ps1 +0 -0
- machineconfig/settings/yazi/keymap.toml +0 -0
- machineconfig/settings/yazi/yazi.toml +0 -4
- machineconfig/setup_linux/apps.sh +0 -66
- machineconfig/setup_linux/nix/cli_installation.sh +0 -137
- machineconfig/setup_linux/ssh/openssh_all.sh +0 -25
- machineconfig/setup_linux/ssh/openssh_wsl.sh +0 -38
- machineconfig/setup_windows/apps.ps1 +0 -62
- machineconfig/setup_windows/others/obs.ps1 +0 -4
- machineconfig/setup_windows/ssh/add_identity.ps1 +0 -11
- machineconfig/setup_windows/wt_and_pwsh/__init__.py +0 -0
- machineconfig/utils/installer_utils/installer.py +0 -225
- machineconfig-6.23.dist-info/METADATA +0 -84
- machineconfig-6.23.dist-info/RECORD +0 -428
- machineconfig/cluster/sessions_managers/{utils → helpers}/load_balancer_helper.py +0 -0
- machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_helper.py +0 -0
- machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_helper_restart.py +0 -0
- machineconfig/cluster/sessions_managers/{helpers → zellij_utils}/zellij_local_manager_helper.py +0 -0
- machineconfig/jobs/installer/linux_scripts/{warp-cli.sh → cloudflare_warp_cli.sh} +0 -0
- machineconfig/jobs/{linux/msc → installer/linux_scripts}/network.sh +0 -0
- machineconfig/jobs/installer/{custom_dev → 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/web_shortcuts → jobs/scripts/bash_scripts}/android.sh +0 -0
- machineconfig/jobs/{linux/msc → scripts/bash_scripts}/lid.sh +0 -0
- machineconfig/{setup_linux/others → jobs/scripts/bash_scripts}/mint_keyboard_shortcuts.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/{jobs/python → scripts/python/ai/utils}/__init__.py +0 -0
- machineconfig/scripts/python/{cloud_helpers → helpers_agents}/__init__.py +0 -0
- machineconfig/scripts/python/{croshell_helpers → helpers_agents/agentic_frameworks}/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_help_search.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents}/fire_agents_load_balancer.py +0 -0
- machineconfig/scripts/python/{helpers_fire → helpers_agents/templates}/template.ps1 +0 -0
- machineconfig/scripts/python/{devops_helpers → helpers_cloud}/__init__.py +0 -0
- machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/cloud_helpers.py +1 -1
- /machineconfig/scripts/python/{cloud_helpers → helpers_cloud}/helpers5.py +0 -0
- /machineconfig/scripts/python/{devops_helpers/themes → helpers_croshell}/__init__.py +0 -0
- /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/pomodoro.py +0 -0
- /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/scheduler.py +0 -0
- /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/viewer.py +0 -0
- /machineconfig/scripts/python/{croshell_helpers → helpers_croshell}/viewer_template.py +0 -0
- /machineconfig/scripts/python/{helpers_fire → helpers_devops}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_fire/agentic_frameworks → helpers_devops/themes}/__init__.py +0 -0
- /machineconfig/scripts/python/{devops_helpers → helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
- /machineconfig/{jobs/windows/msc/cli_agents.bat → scripts/python/helpers_devops/themes/choose_starship_theme.ps1} +0 -0
- /machineconfig/{jobs/windows/msc/cli_agents.ps1 → scripts/python/helpers_fire_command/f.py} +0 -0
- /machineconfig/scripts/python/{helper_navigator → helpers_navigator}/data_models.py +0 -0
- /machineconfig/scripts/python/{helper_navigator → helpers_navigator}/search_bar.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers_network}/__init__.py +0 -0
- /machineconfig/scripts/python/{nw → helpers_network}/mount_nw_drive.py +0 -0
- /machineconfig/scripts/python/{nw → helpers_network}/onetimeshare.py +0 -0
- /machineconfig/scripts/python/{repos_helpers → helpers_repos}/update.py +0 -0
- /machineconfig/scripts/python/{nw → helpers_sessions}/__init__.py +0 -0
- /machineconfig/{scripts/python/sessions_helpers → settings/wt}/__init__.py +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → settings/wt}/set_wt_settings.py +0 -0
- {machineconfig-6.23.dist-info → machineconfig-8.12.dist-info}/WHEEL +0 -0
- {machineconfig-6.23.dist-info → machineconfig-8.12.dist-info}/top_level.txt +0 -0
machineconfig/scripts/python/{repos_helpers/count_lines.py → helpers_repos/repo_analyzer_2.py}
RENAMED
|
@@ -1,189 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
from typing import TYPE_CHECKING, Annotated
|
|
3
1
|
from git import Repo
|
|
4
|
-
from
|
|
2
|
+
from machineconfig.scripts.python.helpers_repos.repo_analyzer_1 import count_python_lines, get_default_branch
|
|
5
3
|
from datetime import datetime
|
|
6
|
-
|
|
4
|
+
import polars as pl
|
|
7
5
|
from pathlib import Path
|
|
8
|
-
from
|
|
9
|
-
import typer
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if TYPE_CHECKING:
|
|
13
|
-
from typing import Any, Dict, List, Optional, Union
|
|
14
|
-
import polars as pl
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
app = typer.Typer()
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def count_lines_in_commit(commit: "Any") -> int:
|
|
21
|
-
_total_lines = 0
|
|
22
|
-
for _file in commit.stats.files:
|
|
23
|
-
if str(_file).endswith(".py"):
|
|
24
|
-
_blob = commit.tree / _file
|
|
25
|
-
_total_lines += len(_blob.data_stream.read().decode("utf-8").splitlines())
|
|
26
|
-
return _total_lines
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def count_historical_loc(repo_path: str) -> int:
|
|
30
|
-
repo = Repo(repo_path)
|
|
31
|
-
file_line_counts: "Dict[str, int]" = defaultdict(int)
|
|
32
|
-
total_commits: int = sum(1 for _ in repo.iter_commits())
|
|
33
|
-
print(f"Total commits to process: {total_commits}")
|
|
34
|
-
for i, commit in enumerate(repo.iter_commits(), 1):
|
|
35
|
-
if i % 100 == 0 or i == total_commits:
|
|
36
|
-
print(f"Processing commit {i}/{total_commits} ({i / total_commits:.1%})")
|
|
37
|
-
try:
|
|
38
|
-
# Handle initial commits that have no parents
|
|
39
|
-
if not commit.parents:
|
|
40
|
-
# For initial commit, count all lines in Python files
|
|
41
|
-
for file in commit.stats.files:
|
|
42
|
-
if str(file).endswith(".py"):
|
|
43
|
-
file_line_counts[str(file)] += commit.stats.files[file]["insertions"]
|
|
44
|
-
else:
|
|
45
|
-
# For commits with parents, use stats
|
|
46
|
-
for file in commit.stats.files:
|
|
47
|
-
if str(file).endswith(".py"):
|
|
48
|
-
file_line_counts[str(file)] += commit.stats.files[file]["insertions"]
|
|
49
|
-
except Exception:
|
|
50
|
-
# If stats fail (e.g., corrupted parent), skip this commit
|
|
51
|
-
print(f"Warning: Could not get stats for commit {commit.hexsha[:8]}, skipping")
|
|
52
|
-
continue
|
|
53
|
-
|
|
54
|
-
print(f"\nProcessed files: {len(file_line_counts)}")
|
|
55
|
-
return sum(file_line_counts.values())
|
|
56
|
-
|
|
57
|
-
def count_python_lines(commit: "Any") -> int:
|
|
58
|
-
"""Count total lines in Python files for a specific commit"""
|
|
59
|
-
total_lines = 0
|
|
60
|
-
try:
|
|
61
|
-
for blob in commit.tree.traverse():
|
|
62
|
-
if blob.path.endswith(".py"):
|
|
63
|
-
try:
|
|
64
|
-
content = blob.data_stream.read().decode("utf-8")
|
|
65
|
-
total_lines += len(content.splitlines())
|
|
66
|
-
except Exception as _e:
|
|
67
|
-
continue
|
|
68
|
-
except Exception as _e:
|
|
69
|
-
return 0
|
|
70
|
-
return total_lines
|
|
71
|
-
def get_default_branch(repo: Repo) -> str:
|
|
72
|
-
"""Get the default branch name of the repository"""
|
|
73
|
-
try:
|
|
74
|
-
_ = repo.refs["main"]
|
|
75
|
-
return "main" # First try 'main'
|
|
76
|
-
except IndexError:
|
|
77
|
-
try:
|
|
78
|
-
_ = repo.refs["master"]
|
|
79
|
-
return "master" # Then try 'master'
|
|
80
|
-
except IndexError:
|
|
81
|
-
return repo.head.reference.name # If neither exists, get the branch the HEAD is pointing to
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
@app.command()
|
|
85
|
-
def count_historical(repo_path: Annotated[str, typer.Argument(..., help="Path to the git repository")]):
|
|
86
|
-
"""Count total historical lines of Python code in the repository."""
|
|
87
|
-
print(f"Analyzing repository: {repo_path}")
|
|
88
|
-
total_loc: int = count_historical_loc(repo_path)
|
|
89
|
-
print(f"\nTotal historical lines of Python code: {total_loc}")
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
@app.command()
|
|
93
|
-
def analyze_over_time(repo_path: Annotated[str, typer.Argument(..., help="Path to the git repository")]):
|
|
94
|
-
"""Analyze a git repository to track Python code size over time with visualization."""
|
|
95
|
-
repo: Repo = Repo(repo_path)
|
|
96
|
-
branch_name: str = get_default_branch(repo)
|
|
97
|
-
print(f"🔍 Using branch: {branch_name}")
|
|
98
|
-
commit_data: "List[Dict[str, Any]]" = []
|
|
99
|
-
print("⏳ Analyzing commits...")
|
|
100
|
-
try:
|
|
101
|
-
commits = list(repo.iter_commits(branch_name))
|
|
102
|
-
from datetime import timezone
|
|
103
|
-
|
|
104
|
-
for commit in track(commits, description="Processing commits..."):
|
|
105
|
-
commit_data.append({"hash": commit.hexsha, "dtmExit": datetime.fromtimestamp(commit.committed_date, tz=timezone.utc), "lines": count_python_lines(commit)})
|
|
106
|
-
except Exception as e:
|
|
107
|
-
print(f"❌ Error analyzing commits: {str(e)}")
|
|
108
|
-
return
|
|
109
|
-
|
|
110
|
-
import polars as pl
|
|
111
|
-
import plotly.graph_objects as go
|
|
112
|
-
|
|
113
|
-
df = pl.DataFrame(commit_data)
|
|
114
|
-
df = df.sort("dtmExit")
|
|
115
|
-
# Create interactive plotly figure with dark theme and all bells and whistles
|
|
116
|
-
fig = go.Figure()
|
|
117
|
-
# Add line chart with gradient fill and sparkle effect
|
|
118
|
-
fig.add_trace(go.Scatter(x=df["dtmExit"], y=df["lines"], mode="lines", line={"width": 3, "color": "#00b4ff"}, fill="tozeroy", fillcolor="rgba(0, 180, 255, 0.2)", name="Lines of Code", hovertemplate="<b>Date:</b> %{x}<br><b>Lines:</b> %{y:,}<extra></extra>"))
|
|
119
|
-
# Add markers for significant points (min, max, last)
|
|
120
|
-
min_idx = df["lines"].arg_min()
|
|
121
|
-
max_idx = df["lines"].arg_max()
|
|
122
|
-
min_point = df.slice(min_idx, 1).to_dicts()[0] if min_idx is not None else {}
|
|
123
|
-
max_point = df.slice(max_idx, 1).to_dicts()[0] if max_idx is not None else {}
|
|
124
|
-
last_point = df.slice(-1, 1).to_dicts()[0]
|
|
125
|
-
|
|
126
|
-
# Add markers for significant points
|
|
127
|
-
fig.add_trace(
|
|
128
|
-
go.Scatter(
|
|
129
|
-
x=[min_point["dtmExit"], max_point["dtmExit"], last_point["dtmExit"]],
|
|
130
|
-
y=[min_point["lines"], max_point["lines"], last_point["lines"]],
|
|
131
|
-
mode="markers",
|
|
132
|
-
marker={"size": [10, 14, 12], "color": ["#ff4f4f", "#4fff4f", "#4f4fff"], "line": {"width": 2, "color": "white"}, "symbol": ["circle", "star", "diamond"]},
|
|
133
|
-
name="Key Points",
|
|
134
|
-
hovertemplate="<b>%{text}</b><br>Date: %{x}<br>Lines: %{y:,}<extra></extra>",
|
|
135
|
-
text=[f"🔽 Min: {min_point['lines']:,} lines", f"🔼 Max: {max_point['lines']:,} lines", f"📊 Current: {last_point['lines']:,} lines"],
|
|
136
|
-
)
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
# Add annotation only for current point
|
|
140
|
-
# annotations = [
|
|
141
|
-
# {"x": last_point['date'], "y": last_point['lines'], "text": f"📊 Current: {last_point['lines']:,} lines", "showarrow": True, "arrowhead": 2, "arrowsize": 1,
|
|
142
|
-
# "arrowwidth": 2, "arrowcolor": "#ffffff", "font": {"size": 14, "color": "#ffffff"}, "bgcolor": "#00b4ff", "bordercolor": "#ffffff",
|
|
143
|
-
# "borderwidth": 1, "borderpad": 4, "ax": 40, "ay": -40}
|
|
144
|
-
# ]
|
|
145
|
-
|
|
146
|
-
# Update layout with dark theme and customizations
|
|
147
|
-
fig.update_layout(
|
|
148
|
-
title={"text": "✨ Python Code Base Size Over Time ✨", "y": 0.95, "x": 0.5, "xanchor": "center", "yanchor": "top", "font": {"size": 24, "color": "white"}},
|
|
149
|
-
xaxis_title="Date 📅",
|
|
150
|
-
yaxis_title="Lines of Code 📝",
|
|
151
|
-
hovermode="closest",
|
|
152
|
-
template="plotly_dark",
|
|
153
|
-
plot_bgcolor="rgba(25, 25, 35, 1)",
|
|
154
|
-
paper_bgcolor="rgba(15, 15, 25, 1)",
|
|
155
|
-
font={"family": "Arial, sans-serif", "size": 14, "color": "white"}, # annotations=annotations,
|
|
156
|
-
autosize=True,
|
|
157
|
-
height=700,
|
|
158
|
-
margin={"l": 80, "r": 80, "t": 100, "b": 80},
|
|
159
|
-
xaxis={"showgrid": True, "gridcolor": "rgba(80, 80, 100, 0.2)", "showline": True, "linecolor": "rgba(200, 200, 255, 0.2)", "tickfont": {"size": 12}},
|
|
160
|
-
yaxis={"showgrid": True, "gridcolor": "rgba(80, 80, 100, 0.2)", "showline": True, "linecolor": "rgba(200, 200, 255, 0.2)", "tickformat": ",", "tickfont": {"size": 12}},
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
# Add range slider for date selection
|
|
164
|
-
fig.update_xaxes(rangeslider_visible=True, rangeslider_thickness=0.05)
|
|
165
|
-
|
|
166
|
-
# Save as interactive HTML and static image
|
|
167
|
-
plot_dir = Path.home().joinpath("tmp_results", "tmp_images", Path(repo_path).name)
|
|
168
|
-
plot_dir.mkdir(parents=True, exist_ok=True)
|
|
169
|
-
|
|
170
|
-
html_path = plot_dir.joinpath("code_size_evolution.html")
|
|
171
|
-
png_path = plot_dir.joinpath("code_size_evolution.png")
|
|
172
|
-
|
|
173
|
-
fig.write_html(html_path, include_plotlyjs="cdn")
|
|
174
|
-
fig.write_image(png_path, width=1200, height=700, scale=2)
|
|
175
|
-
|
|
176
|
-
print(f"🖼️ Interactive plot saved as {html_path}")
|
|
177
|
-
print(f"🖼️ Static image saved as {png_path}")
|
|
178
|
-
# Print statistics
|
|
179
|
-
print("\n📊 Repository Statistics:")
|
|
180
|
-
print(f"📚 Total commits analyzed: {len(df)}")
|
|
181
|
-
print(f"🔙 Initial line count: {df['lines'][-1]:,}")
|
|
182
|
-
print(f"🔜 Final line count: {df['lines'][0]:,}")
|
|
183
|
-
print(f"📈 Net change: {df['lines'][0] - df['lines'][-1]:,} lines")
|
|
6
|
+
from typing import Any, Dict, List, Union, Optional
|
|
184
7
|
|
|
185
8
|
|
|
186
|
-
def
|
|
9
|
+
def print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exception]":
|
|
187
10
|
import polars as pl
|
|
188
11
|
import plotly.graph_objects as go
|
|
189
12
|
import plotly.express as px
|
|
@@ -227,13 +50,25 @@ def _print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exc
|
|
|
227
50
|
df = df.sort("lines", descending=True)
|
|
228
51
|
df = df.filter(pl.col("lines") > 0) # Filter out empty files
|
|
229
52
|
|
|
53
|
+
from rich.console import Console
|
|
54
|
+
from rich.table import Table
|
|
55
|
+
|
|
230
56
|
# Add total count
|
|
231
57
|
total_lines = int(df["lines"].sum())
|
|
232
58
|
file_count: int = len(df)
|
|
233
|
-
|
|
59
|
+
console = Console()
|
|
234
60
|
# Print the DataFrame
|
|
235
|
-
print("\n📊 Python Files Line Count (sorted max to min):")
|
|
236
|
-
|
|
61
|
+
console.print("\n📊 Python Files Line Count (sorted max to min):")
|
|
62
|
+
|
|
63
|
+
table = Table(show_header=True, header_style="bold cyan")
|
|
64
|
+
table.add_column("#", justify="right")
|
|
65
|
+
table.add_column("File", overflow="fold")
|
|
66
|
+
table.add_column("Lines", justify="right")
|
|
67
|
+
|
|
68
|
+
for idx, row in enumerate(df.iter_rows(named=True), 1):
|
|
69
|
+
table.add_row(str(idx), row["filename"], f"{row['lines']:,}")
|
|
70
|
+
|
|
71
|
+
console.print(table)
|
|
237
72
|
print(f"\n📁 Total Python files: {file_count}")
|
|
238
73
|
print(f"📝 Total lines of Python code: {total_lines:,}")
|
|
239
74
|
|
|
@@ -335,14 +170,100 @@ def _print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exc
|
|
|
335
170
|
return Exception(f"❌ Error analyzing repository: {str(e)}")
|
|
336
171
|
|
|
337
172
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
173
|
+
def analyze_over_time(repo_path: str):
|
|
174
|
+
"""Analyze a git repository to track Python code size over time with visualization."""
|
|
175
|
+
repo: Repo = Repo(repo_path)
|
|
176
|
+
branch_name: str = get_default_branch(repo)
|
|
177
|
+
print(f"🔍 Using branch: {branch_name}")
|
|
178
|
+
commit_data: "List[Dict[str, Any]]" = []
|
|
179
|
+
print("⏳ Analyzing commits...")
|
|
180
|
+
try:
|
|
181
|
+
commits = list(repo.iter_commits(branch_name))
|
|
182
|
+
from datetime import timezone
|
|
183
|
+
from rich.progress import track
|
|
184
|
+
for commit in track(commits, description="Processing commits..."):
|
|
185
|
+
commit_data.append({"hash": commit.hexsha, "dtmExit": datetime.fromtimestamp(commit.committed_date, tz=timezone.utc), "lines": count_python_lines(commit)})
|
|
186
|
+
except Exception as e:
|
|
187
|
+
print(f"❌ Error analyzing commits: {str(e)}")
|
|
344
188
|
return
|
|
345
189
|
|
|
190
|
+
import polars as pl
|
|
191
|
+
import plotly.graph_objects as go
|
|
192
|
+
|
|
193
|
+
df = pl.DataFrame(commit_data)
|
|
194
|
+
df = df.sort("dtmExit")
|
|
195
|
+
# Create interactive plotly figure with dark theme and all bells and whistles
|
|
196
|
+
fig = go.Figure()
|
|
197
|
+
# Add line chart with gradient fill and sparkle effect
|
|
198
|
+
fig.add_trace(go.Scatter(x=df["dtmExit"], y=df["lines"], mode="lines", line={"width": 3, "color": "#00b4ff"}, fill="tozeroy", fillcolor="rgba(0, 180, 255, 0.2)", name="Lines of Code", hovertemplate="<b>Date:</b> %{x}<br><b>Lines:</b> %{y:,}<extra></extra>"))
|
|
199
|
+
# Add markers for significant points (min, max, last)
|
|
200
|
+
min_idx = df["lines"].arg_min()
|
|
201
|
+
max_idx = df["lines"].arg_max()
|
|
202
|
+
min_point = df.slice(min_idx, 1).to_dicts()[0] if min_idx is not None else {}
|
|
203
|
+
max_point = df.slice(max_idx, 1).to_dicts()[0] if max_idx is not None else {}
|
|
204
|
+
last_point = df.slice(-1, 1).to_dicts()[0]
|
|
205
|
+
|
|
206
|
+
# Add markers for significant points
|
|
207
|
+
fig.add_trace(
|
|
208
|
+
go.Scatter(
|
|
209
|
+
x=[min_point["dtmExit"], max_point["dtmExit"], last_point["dtmExit"]],
|
|
210
|
+
y=[min_point["lines"], max_point["lines"], last_point["lines"]],
|
|
211
|
+
mode="markers",
|
|
212
|
+
marker={"size": [10, 14, 12], "color": ["#ff4f4f", "#4fff4f", "#4f4fff"], "line": {"width": 2, "color": "white"}, "symbol": ["circle", "star", "diamond"]},
|
|
213
|
+
name="Key Points",
|
|
214
|
+
hovertemplate="<b>%{text}</b><br>Date: %{x}<br>Lines: %{y:,}<extra></extra>",
|
|
215
|
+
text=[f"🔽 Min: {min_point['lines']:,} lines", f"🔼 Max: {max_point['lines']:,} lines", f"📊 Current: {last_point['lines']:,} lines"],
|
|
216
|
+
)
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# Add annotation only for current point
|
|
220
|
+
# annotations = [
|
|
221
|
+
# {"x": last_point['date'], "y": last_point['lines'], "text": f"📊 Current: {last_point['lines']:,} lines", "showarrow": True, "arrowhead": 2, "arrowsize": 1,
|
|
222
|
+
# "arrowwidth": 2, "arrowcolor": "#ffffff", "font": {"size": 14, "color": "#ffffff"}, "bgcolor": "#00b4ff", "bordercolor": "#ffffff",
|
|
223
|
+
# "borderwidth": 1, "borderpad": 4, "ax": 40, "ay": -40}
|
|
224
|
+
# ]
|
|
346
225
|
|
|
347
|
-
|
|
348
|
-
|
|
226
|
+
# Update layout with dark theme and customizations
|
|
227
|
+
fig.update_layout(
|
|
228
|
+
title={"text": "✨ Python Code Base Size Over Time ✨", "y": 0.95, "x": 0.5, "xanchor": "center", "yanchor": "top", "font": {"size": 24, "color": "white"}},
|
|
229
|
+
xaxis_title="Date 📅",
|
|
230
|
+
yaxis_title="Lines of Code 📝",
|
|
231
|
+
hovermode="closest",
|
|
232
|
+
template="plotly_dark",
|
|
233
|
+
plot_bgcolor="rgba(25, 25, 35, 1)",
|
|
234
|
+
paper_bgcolor="rgba(15, 15, 25, 1)",
|
|
235
|
+
font={"family": "Arial, sans-serif", "size": 14, "color": "white"}, # annotations=annotations,
|
|
236
|
+
autosize=True,
|
|
237
|
+
height=700,
|
|
238
|
+
margin={"l": 80, "r": 80, "t": 100, "b": 80},
|
|
239
|
+
xaxis={"showgrid": True, "gridcolor": "rgba(80, 80, 100, 0.2)", "showline": True, "linecolor": "rgba(200, 200, 255, 0.2)", "tickfont": {"size": 12}},
|
|
240
|
+
yaxis={"showgrid": True, "gridcolor": "rgba(80, 80, 100, 0.2)", "showline": True, "linecolor": "rgba(200, 200, 255, 0.2)", "tickformat": ",", "tickfont": {"size": 12}},
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
# Add range slider for date selection
|
|
244
|
+
fig.update_xaxes(rangeslider_visible=True, rangeslider_thickness=0.05)
|
|
245
|
+
|
|
246
|
+
# Save as interactive HTML and static image
|
|
247
|
+
plot_dir = Path.home().joinpath("tmp_results", "tmp_images", Path(repo_path).name)
|
|
248
|
+
plot_dir.mkdir(parents=True, exist_ok=True)
|
|
249
|
+
|
|
250
|
+
html_path = plot_dir.joinpath("code_size_evolution.html")
|
|
251
|
+
png_path = plot_dir.joinpath("code_size_evolution.png")
|
|
252
|
+
|
|
253
|
+
try:
|
|
254
|
+
fig.write_html(html_path, include_plotlyjs="cdn")
|
|
255
|
+
except Exception as e:
|
|
256
|
+
print(f"❌ Error saving HTML plot: {str(e)}")
|
|
257
|
+
try:
|
|
258
|
+
fig.write_image(png_path, width=1200, height=700, scale=2)
|
|
259
|
+
except Exception as e:
|
|
260
|
+
print(f"❌ Error saving PNG plot: {str(e)}")
|
|
261
|
+
|
|
262
|
+
print(f"🖼️ Interactive plot saved as {html_path}")
|
|
263
|
+
print(f"🖼️ Static image saved as {png_path}")
|
|
264
|
+
# Print statistics
|
|
265
|
+
print("\n📊 Repository Statistics:")
|
|
266
|
+
print(f"📚 Total commits analyzed: {len(df)}")
|
|
267
|
+
print(f"🔙 Initial line count: {df['lines'][-1]:,}")
|
|
268
|
+
print(f"🔜 Final line count: {df['lines'][0]:,}")
|
|
269
|
+
print(f"📈 Net change: {df['lines'][0] - df['lines'][-1]:,} lines")
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from machineconfig.utils.path_extended import PathExtended
|
|
2
|
-
from machineconfig.utils.code import write_shell_script_to_file
|
|
3
2
|
import platform
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
from rich.console import Console
|
|
@@ -56,11 +55,12 @@ def inspect_repos(repo_local_root: str, repo_remote_root: str):
|
|
|
56
55
|
|
|
57
56
|
if platform.system() == "Windows":
|
|
58
57
|
program = get_wt_cmd(wd1=PathExtended(repo_local_root), wd2=PathExtended(repo_local_root))
|
|
59
|
-
write_shell_script_to_file(shell_script=program)
|
|
60
|
-
return None
|
|
61
58
|
elif platform.system() in ["Linux", "Darwin"]:
|
|
62
59
|
program = get_zellij_cmd(wd1=PathExtended(repo_local_root), wd2=PathExtended(repo_remote_root))
|
|
63
|
-
write_shell_script_to_file(shell_script=program)
|
|
64
|
-
return None
|
|
65
60
|
else:
|
|
66
61
|
raise NotImplementedError(f"Platform {platform.system()} not implemented.")
|
|
62
|
+
import tempfile
|
|
63
|
+
with tempfile.NamedTemporaryFile(mode='w', suffix=".sh" if platform.system() != "Windows" else ".ps1", delete=False, encoding='utf-8') as temp_file:
|
|
64
|
+
temp_file.write(program)
|
|
65
|
+
temp_script_path = PathExtended(temp_file.name)
|
|
66
|
+
console.print(Panel(f"🚀 Launching repo inspection tool...\n\n[blue]{temp_script_path}[/blue]", border_style="blue"))
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
3
|
from typing import Optional, Annotated
|
|
4
|
-
from pathlib import Path
|
|
5
4
|
import typer
|
|
6
5
|
|
|
7
6
|
|
|
@@ -10,23 +9,23 @@ def create_from_function(
|
|
|
10
9
|
path: Annotated[str, typer.Option(..., "--path", "-p", help="Path to a Python or Shell script file or a directory containing such files")] = ".",
|
|
11
10
|
function: Annotated[Optional[str], typer.Option(..., "--function", "-f", help="Function to run from the Python file. If not provided, you will be prompted to choose.")] = None,
|
|
12
11
|
):
|
|
13
|
-
from machineconfig.utils.ve import
|
|
12
|
+
from machineconfig.utils.ve import get_ve_path_and_ipython_profile
|
|
14
13
|
from machineconfig.utils.options import choose_from_options
|
|
15
14
|
from machineconfig.utils.path_helper import match_file_name, sanitize_path
|
|
16
|
-
from machineconfig.utils.path_extended import PathExtended
|
|
17
15
|
from machineconfig.utils.accessories import get_repo_root
|
|
16
|
+
from pathlib import Path
|
|
18
17
|
|
|
19
18
|
path_obj = sanitize_path(path)
|
|
20
19
|
if not path_obj.exists():
|
|
21
20
|
suffixes = {".py"}
|
|
22
|
-
choice_file = match_file_name(sub_string=path, search_root=
|
|
21
|
+
choice_file = match_file_name(sub_string=path, search_root=Path.cwd(), suffixes=suffixes)
|
|
23
22
|
elif path_obj.is_dir():
|
|
24
|
-
from machineconfig.
|
|
23
|
+
from machineconfig.utils.path_helper import search_for_files_of_interest
|
|
25
24
|
print(f"🔍 Searching recursively for Python, PowerShell and Shell scripts in directory `{path_obj}`")
|
|
26
|
-
files = search_for_files_of_interest(path_obj)
|
|
25
|
+
files = search_for_files_of_interest(path_obj, suffixes={".py", ".sh", ".ps1"})
|
|
27
26
|
print(f"🔍 Got #{len(files)} results.")
|
|
28
|
-
choice_file = choose_from_options(multi=False, options=files,
|
|
29
|
-
choice_file =
|
|
27
|
+
choice_file = choose_from_options(multi=False, options=files, tv=True, msg="Choose one option")
|
|
28
|
+
choice_file = Path(choice_file)
|
|
30
29
|
else:
|
|
31
30
|
choice_file = path_obj
|
|
32
31
|
|
|
@@ -36,10 +35,13 @@ def create_from_function(
|
|
|
36
35
|
ve_root_from_file, ipy_profile = get_ve_path_and_ipython_profile(choice_file)
|
|
37
36
|
if ipy_profile is None:
|
|
38
37
|
ipy_profile = "default"
|
|
39
|
-
if ve_root_from_file is None:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
# if ve_root_from_file is None:
|
|
39
|
+
# raise ValueError(f"Could not determine virtual environment for file {choice_file}. Please ensure it is within a recognized project structure.")
|
|
40
|
+
# _activate_ve_line = get_ve_activate_line(ve_root=ve_root_from_file)
|
|
41
|
+
if ve_root_from_file is not None:
|
|
42
|
+
start_dir = Path(ve_root_from_file).parent
|
|
43
|
+
else:
|
|
44
|
+
start_dir = Path.cwd()
|
|
43
45
|
|
|
44
46
|
# ========================= choosing function to run
|
|
45
47
|
if function is None or function.strip() == "":
|
|
@@ -52,7 +54,11 @@ def create_from_function(
|
|
|
52
54
|
from machineconfig.utils.schemas.layouts.layout_types import LayoutConfig
|
|
53
55
|
layout: LayoutConfig = {"layoutName": "fireNprocess", "layoutTabs": []}
|
|
54
56
|
for an_arg in range(num_process):
|
|
55
|
-
layout["layoutTabs"].append({
|
|
57
|
+
layout["layoutTabs"].append({
|
|
58
|
+
"tabName": f"tab{an_arg}",
|
|
59
|
+
"startDir": str(start_dir),
|
|
60
|
+
"command": f"uv run python -m fire {choice_file} {choice_function} --idx={an_arg} --idx_max={num_process}"
|
|
61
|
+
})
|
|
56
62
|
print(layout)
|
|
57
63
|
run_zellij_layout(layout_config=layout)
|
|
58
64
|
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
from typing import Annotated, Optional
|
|
4
|
+
import typer
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def download(
|
|
9
|
+
url: Annotated[Optional[str], typer.Argument(..., help="The URL to download the file from.")] = None,
|
|
10
|
+
decompress: Annotated[bool, typer.Option(..., "--decompress", "-d", help="Decompress the file if it's an archive.")] = False,
|
|
11
|
+
output: Annotated[Optional[str], typer.Option("--output", "-o", help="The output file path.")] = None,
|
|
12
|
+
output_dir: Annotated[Optional[str], typer.Option("--output-dir", help="Directory to place the downloaded file in.")] = None,
|
|
13
|
+
) -> Optional["Path"]:
|
|
14
|
+
import subprocess
|
|
15
|
+
from urllib.parse import parse_qs, unquote, urlparse
|
|
16
|
+
from requests import Response
|
|
17
|
+
import requests
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
if url is None:
|
|
20
|
+
typer.echo("❌ Error: URL is required.", err=True)
|
|
21
|
+
return None
|
|
22
|
+
if output is not None and output_dir is not None:
|
|
23
|
+
typer.echo("❌ Error: --output and --output-dir cannot be used together.", err=True)
|
|
24
|
+
return None
|
|
25
|
+
typer.echo(f"📥 Downloading from: {url}")
|
|
26
|
+
|
|
27
|
+
def _sanitize_candidate_filename(name: str) -> Optional[str]:
|
|
28
|
+
candidate = Path(name).name.strip()
|
|
29
|
+
if not candidate or candidate in {".", ".."}:
|
|
30
|
+
return None
|
|
31
|
+
return candidate
|
|
32
|
+
|
|
33
|
+
def _filename_from_content_disposition(header_value: Optional[str]) -> Optional[str]:
|
|
34
|
+
if header_value is None:
|
|
35
|
+
return None
|
|
36
|
+
parts = [segment.strip() for segment in header_value.split(";")]
|
|
37
|
+
for part in parts:
|
|
38
|
+
lower = part.lower()
|
|
39
|
+
if lower.startswith("filename*="):
|
|
40
|
+
value = part.split("=", 1)[1]
|
|
41
|
+
value = value.strip().strip('"')
|
|
42
|
+
if "''" in value:
|
|
43
|
+
value = value.split("''", 1)[1]
|
|
44
|
+
decoded = unquote(value)
|
|
45
|
+
sanitized = _sanitize_candidate_filename(decoded)
|
|
46
|
+
if sanitized is not None:
|
|
47
|
+
return sanitized
|
|
48
|
+
if lower.startswith("filename="):
|
|
49
|
+
value = part.split("=", 1)[1].strip().strip('"')
|
|
50
|
+
decoded = unquote(value)
|
|
51
|
+
sanitized = _sanitize_candidate_filename(decoded)
|
|
52
|
+
if sanitized is not None:
|
|
53
|
+
return sanitized
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
def _filename_from_url(source_url: str) -> Optional[str]:
|
|
57
|
+
parsed = urlparse(source_url)
|
|
58
|
+
url_candidate = _sanitize_candidate_filename(unquote(Path(parsed.path).name))
|
|
59
|
+
if url_candidate is not None:
|
|
60
|
+
return url_candidate
|
|
61
|
+
query_params = parse_qs(parsed.query, keep_blank_values=True)
|
|
62
|
+
for key, values in query_params.items():
|
|
63
|
+
lower_key = key.lower()
|
|
64
|
+
if "name" in lower_key or "file" in lower_key:
|
|
65
|
+
for value in values:
|
|
66
|
+
sanitized = _sanitize_candidate_filename(unquote(value))
|
|
67
|
+
if sanitized is not None:
|
|
68
|
+
return sanitized
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
def _resolve_download_path(request_url: str, response: Response, requested_output: Optional[str], requested_output_dir: Optional[str]) -> Path:
|
|
72
|
+
if requested_output is not None:
|
|
73
|
+
return Path(requested_output)
|
|
74
|
+
header_candidate = _filename_from_content_disposition(response.headers.get("content-disposition"))
|
|
75
|
+
if header_candidate is None:
|
|
76
|
+
header_candidate = _filename_from_url(response.url)
|
|
77
|
+
if header_candidate is None:
|
|
78
|
+
header_candidate = _filename_from_url(request_url)
|
|
79
|
+
if header_candidate is None:
|
|
80
|
+
header_candidate = "downloaded_file"
|
|
81
|
+
if requested_output_dir is not None:
|
|
82
|
+
return Path(requested_output_dir) / header_candidate
|
|
83
|
+
return Path(header_candidate)
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
with requests.get(url, allow_redirects=True, stream=True, timeout=60) as response:
|
|
87
|
+
response.raise_for_status()
|
|
88
|
+
download_path = _resolve_download_path(url, response, output, output_dir)
|
|
89
|
+
download_path.parent.mkdir(parents=True, exist_ok=True)
|
|
90
|
+
total_size_header = response.headers.get("content-length", "0")
|
|
91
|
+
try:
|
|
92
|
+
total_size = int(total_size_header)
|
|
93
|
+
except (TypeError, ValueError):
|
|
94
|
+
total_size = 0
|
|
95
|
+
if total_size <= 0:
|
|
96
|
+
with open(download_path, "wb") as file_handle:
|
|
97
|
+
file_handle.write(response.content)
|
|
98
|
+
else:
|
|
99
|
+
downloaded = 0
|
|
100
|
+
chunk_size = 8192 * 40
|
|
101
|
+
with open(download_path, "wb") as file_handle:
|
|
102
|
+
for chunk in response.iter_content(chunk_size=chunk_size):
|
|
103
|
+
if not chunk:
|
|
104
|
+
continue
|
|
105
|
+
file_handle.write(chunk)
|
|
106
|
+
downloaded += len(chunk)
|
|
107
|
+
progress = (downloaded / total_size) * 100
|
|
108
|
+
typer.echo(f"\r⏬ Progress: {progress:.1f}% ({downloaded}/{total_size} bytes)", nl=False)
|
|
109
|
+
typer.echo()
|
|
110
|
+
except requests.exceptions.RequestException as exception:
|
|
111
|
+
typer.echo(f"❌ Download failed: {exception}", err=True)
|
|
112
|
+
return None
|
|
113
|
+
except OSError as exception:
|
|
114
|
+
typer.echo(f"❌ File write error: {exception}", err=True)
|
|
115
|
+
return None
|
|
116
|
+
|
|
117
|
+
typer.echo(f"✅ Downloaded to: {download_path}")
|
|
118
|
+
result_path: Path = download_path
|
|
119
|
+
if decompress:
|
|
120
|
+
typer.echo(f"📦 Decompressing: {download_path}")
|
|
121
|
+
base_name = download_path.name.split(".", maxsplit=1)[0] # ouch decompresses all (e.g. .tar.gz) in one go.
|
|
122
|
+
if base_name in {"", ".", ".."}:
|
|
123
|
+
base_name = "extracted"
|
|
124
|
+
extract_dir = download_path.parent / base_name
|
|
125
|
+
extract_dir.mkdir(parents=True, exist_ok=True)
|
|
126
|
+
try:
|
|
127
|
+
subprocess.run(
|
|
128
|
+
["ouch", "decompress", str(download_path), "--dir", str(extract_dir)],
|
|
129
|
+
check=True,
|
|
130
|
+
capture_output=True,
|
|
131
|
+
text=True,
|
|
132
|
+
)
|
|
133
|
+
typer.echo(f"✅ Decompressed to: {extract_dir}")
|
|
134
|
+
if download_path.exists():
|
|
135
|
+
download_path.unlink()
|
|
136
|
+
typer.echo(f"🗑️ Removed archive: {download_path}")
|
|
137
|
+
result_path = extract_dir
|
|
138
|
+
except subprocess.CalledProcessError as exception:
|
|
139
|
+
typer.echo(f"❌ Decompression failed: {exception.stderr}", err=True)
|
|
140
|
+
return None
|
|
141
|
+
except FileNotFoundError:
|
|
142
|
+
typer.echo("❌ Error: ouch command not found. Please install ouch.", err=True)
|
|
143
|
+
typer.echo("💡 Install with: cargo install ouch", err=True)
|
|
144
|
+
return None
|
|
145
|
+
|
|
146
|
+
return result_path.resolve()
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
if __name__ == "__main__":
|
|
150
|
+
pass
|