machineconfig 8.14__py3-none-any.whl → 8.45__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/remote/run_cluster.py +1 -1
- machineconfig/cluster/remote/run_remote.py +1 -1
- machineconfig/cluster/sessions_managers/utils/maker.py +10 -8
- machineconfig/cluster/sessions_managers/wt_local.py +1 -1
- machineconfig/cluster/sessions_managers/wt_local_manager.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_local.py +1 -1
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +1 -1
- machineconfig/jobs/installer/checks/check_installations.py +133 -0
- machineconfig/jobs/installer/checks/install_utils.py +132 -0
- machineconfig/jobs/installer/checks/report_utils.py +39 -0
- machineconfig/jobs/installer/checks/vt_utils.py +89 -0
- machineconfig/jobs/installer/installer_data.json +225 -140
- machineconfig/jobs/installer/linux_scripts/docker.sh +6 -9
- machineconfig/jobs/installer/package_groups.py +10 -9
- machineconfig/jobs/installer/python_scripts/boxes.py +1 -2
- machineconfig/jobs/installer/python_scripts/code.py +10 -8
- machineconfig/jobs/installer/python_scripts/hx.py +30 -13
- machineconfig/jobs/installer/python_scripts/nerfont_windows_helper.py +6 -5
- machineconfig/jobs/installer/python_scripts/sysabc.py +25 -19
- machineconfig/jobs/installer/python_scripts/yazi.py +33 -17
- machineconfig/jobs/scripts/powershell_scripts/cmatrix.ps1 +52 -0
- machineconfig/jobs/scripts/powershell_scripts/mount_ssh.ps1 +1 -1
- machineconfig/jobs/scripts_dynamic/a.py +413 -10
- machineconfig/profile/create_links.py +77 -20
- machineconfig/profile/create_links_export.py +40 -51
- machineconfig/profile/mapper_data.toml +30 -0
- machineconfig/profile/mapper_dotfiles.toml +253 -0
- machineconfig/scripts/python/agents.py +70 -172
- machineconfig/scripts/python/ai/initai.py +3 -1
- machineconfig/scripts/python/ai/scripts/__init__.py +1 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.ps1 +2 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +7 -5
- machineconfig/scripts/python/ai/solutions/claude/claude.py +1 -1
- machineconfig/scripts/python/ai/solutions/cline/cline.py +1 -1
- machineconfig/scripts/python/ai/solutions/copilot/github_copilot.py +1 -1
- machineconfig/scripts/python/ai/solutions/copilot/instructions/python/dev.instructions.md +29 -0
- machineconfig/scripts/python/ai/solutions/crush/crush.py +1 -1
- machineconfig/scripts/python/ai/solutions/cursor/cursors.py +1 -1
- machineconfig/scripts/python/ai/solutions/gemini/gemini.py +1 -1
- machineconfig/scripts/python/ai/solutions/gemini/settings.json +3 -0
- machineconfig/scripts/python/ai/{solutions → utils}/generic.py +2 -15
- machineconfig/scripts/python/ai/utils/vscode_tasks.py +6 -3
- machineconfig/scripts/python/cloud.py +58 -11
- machineconfig/scripts/python/croshell.py +4 -156
- machineconfig/scripts/python/devops.py +57 -40
- machineconfig/scripts/python/devops_navigator.py +17 -3
- machineconfig/scripts/python/fire_jobs.py +8 -207
- machineconfig/scripts/python/ftpx.py +5 -225
- machineconfig/scripts/python/graph/cli_graph.json +8743 -0
- machineconfig/scripts/python/{env_manager → helper_env}/path_manager_tui.py +2 -2
- machineconfig/scripts/python/{env_manager → helpers/helper_env}/env_manager_tui.py +1 -1
- machineconfig/scripts/python/helpers/helper_env/path_manager_tui.py +228 -0
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_cursor_agents.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_gemini.py +1 -1
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_qwen.py +1 -1
- machineconfig/scripts/python/helpers/helpers_agents/agents_impl.py +168 -0
- machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_launch.py +5 -5
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_copy.py +6 -6
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_mount.py +10 -5
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_sync.py +3 -3
- machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers2.py +1 -1
- machineconfig/scripts/python/helpers/helpers_croshell/croshell_impl.py +225 -0
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/scheduler.py +4 -4
- machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/start_slidev.py +7 -6
- machineconfig/scripts/python/helpers/helpers_devops/backup_config.py +149 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_backup_retrieve.py +267 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_config.py +98 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_config_dotfile.py +274 -0
- machineconfig/scripts/python/helpers/helpers_devops/cli_data.py +76 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_nw.py +52 -72
- machineconfig/scripts/python/helpers/helpers_devops/cli_repos.py +265 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_self.py +39 -23
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_file.py +44 -30
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_server.py +26 -43
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_share_terminal.py +12 -6
- machineconfig/scripts/python/helpers/helpers_devops/cli_ssh.py +167 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_status.py +12 -6
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/devops_update_repos.py +1 -1
- machineconfig/scripts/python/{interactive.py → helpers/helpers_devops/interactive.py} +68 -52
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/run_script.py +75 -58
- machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.ps1 +41 -0
- machineconfig/scripts/python/helpers/helpers_devops/themes/choose_starship_theme.sh +48 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_wezterm_theme.py +3 -3
- machineconfig/scripts/python/helpers/helpers_fire_command/fire_jobs_impl.py +233 -0
- machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_route_helper.py +3 -3
- machineconfig/scripts/python/helpers/helpers_msearch/msearch_impl.py +248 -0
- machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_linux/fzfg +4 -3
- machineconfig/scripts/python/helpers/helpers_msearch/scripts_linux/search_with_context.sh +48 -0
- machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/scripts_windows/fzfg.ps1 +1 -1
- machineconfig/scripts/python/helpers/helpers_navigator/__init__.py +20 -0
- machineconfig/scripts/python/helpers/helpers_navigator/cli_graph_loader.py +234 -0
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/command_builder.py +61 -13
- machineconfig/scripts/python/helpers/helpers_navigator/command_detail.py +153 -0
- machineconfig/scripts/python/helpers/helpers_navigator/command_tree.py +45 -0
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/data_models.py +18 -11
- machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/main_app.py +5 -5
- machineconfig/scripts/python/helpers/helpers_network/__init__.py +0 -0
- machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/address.py +15 -17
- machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/address_switch.py +1 -1
- machineconfig/scripts/python/helpers/helpers_network/ftpx_impl.py +276 -0
- machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_ssh.py +2 -2
- machineconfig/scripts/python/helpers/helpers_network/ssh_add_identity.py +73 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_add_ssh_key.py +175 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_debug_linux.py +319 -0
- machineconfig/scripts/python/helpers/helpers_network/ssh_debug_windows.py +275 -0
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action.py +3 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/action_helper.py +3 -3
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/cloud_repo_sync.py +116 -33
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/grource.py +3 -2
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/record.py +33 -13
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_2.py +63 -19
- machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/update.py +0 -6
- machineconfig/scripts/python/helpers/helpers_search/script_help.py +81 -0
- machineconfig/scripts/python/helpers/helpers_sessions/__init__.py +0 -0
- machineconfig/scripts/python/helpers/helpers_sessions/sessions_impl.py +177 -0
- machineconfig/scripts/python/{helpers_sessions → helpers/helpers_sessions}/sessions_multiprocess.py +1 -1
- machineconfig/scripts/python/helpers/helpers_terminal/__init__.py +0 -0
- machineconfig/scripts/python/helpers/helpers_terminal/terminal_impl.py +96 -0
- machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/download.py +1 -1
- machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/python.py +46 -26
- machineconfig/scripts/python/helpers/helpers_utils/specs.py +246 -0
- machineconfig/scripts/python/mcfg_entry.py +133 -48
- machineconfig/scripts/python/msearch.py +15 -61
- machineconfig/scripts/python/sessions.py +59 -194
- machineconfig/scripts/python/terminal.py +18 -96
- machineconfig/scripts/python/utils.py +101 -20
- machineconfig/settings/atuin/config.toml +294 -0
- machineconfig/settings/atuin/themes/catppuccin-mocha-mauve.toml +12 -0
- machineconfig/settings/linters/.ruff.toml +1 -0
- machineconfig/settings/mprocs/windows/mprocs.yaml +2 -2
- machineconfig/settings/shells/bash/init.sh +6 -3
- machineconfig/settings/shells/pwsh/init.ps1 +69 -1
- machineconfig/settings/shells/pwsh/search_pwsh_history.ps1 +99 -0
- machineconfig/settings/shells/wezterm/wezterm.lua +4 -1
- machineconfig/settings/shells/wt/settings.json +20 -7
- machineconfig/settings/shells/zsh/init.sh +34 -4
- machineconfig/settings/television/cable_unix/bash-history.toml +1 -1
- machineconfig/settings/television/cable_windows/pwsh-history.toml +1 -1
- machineconfig/settings/tv/config.toml +234 -0
- machineconfig/settings/tv/themes/catppuccin-mocha-sky.toml +22 -0
- machineconfig/settings/wsl/.wslconfig +5 -30
- machineconfig/settings/yazi/yazi_linux.toml +18 -8
- machineconfig/settings/zellij/layouts/st.kdl +2 -2
- machineconfig/settings/zellij/layouts/st2.kdl +1 -1
- machineconfig/setup_linux/web_shortcuts/interactive.sh +10 -10
- machineconfig/setup_linux/web_shortcuts/live_from_github.sh +3 -0
- machineconfig/setup_mac/__init__.py +0 -2
- machineconfig/setup_windows/__init__.py +0 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +14 -13
- machineconfig/setup_windows/web_shortcuts/live_from_github.ps1 +4 -3
- machineconfig/setup_windows/web_shortcuts/quick_init.ps1 +3 -3
- machineconfig/type_hinting/sql/__init__.py +1 -0
- machineconfig/type_hinting/sql/base.py +216 -0
- machineconfig/type_hinting/sql/core_schema.py +64 -0
- machineconfig/type_hinting/sql/core_schema_typeddict.py +41 -0
- machineconfig/type_hinting/sql/typeddict_codegen.py +222 -0
- machineconfig/type_hinting/typedict/__init__.py +1 -0
- machineconfig/type_hinting/typedict/ast_utils.py +130 -0
- machineconfig/type_hinting/typedict/generator_helpers.py +319 -0
- machineconfig/type_hinting/typedict/generators.py +231 -0
- machineconfig/type_hinting/typedict/polars_schema.py +24 -0
- machineconfig/type_hinting/typedict/polars_schema_typeddict.py +63 -0
- machineconfig/utils/accessories.py +24 -0
- machineconfig/utils/code.py +41 -13
- machineconfig/utils/files/ascii_art.py +10 -14
- machineconfig/utils/files/headers.py +3 -5
- machineconfig/utils/files/read.py +8 -1
- machineconfig/utils/installer_utils/github_release_bulk.py +1 -0
- machineconfig/utils/installer_utils/install_from_url.py +1 -1
- machineconfig/utils/installer_utils/installer_class.py +12 -4
- machineconfig/utils/installer_utils/installer_cli.py +1 -15
- machineconfig/utils/installer_utils/installer_helper.py +2 -2
- machineconfig/utils/installer_utils/installer_locator_utils.py +13 -13
- machineconfig/utils/installer_utils/installer_runner.py +4 -4
- machineconfig/utils/meta.py +6 -4
- machineconfig/utils/options.py +49 -19
- machineconfig/utils/options_utils/__init__.py +0 -0
- machineconfig/utils/options_utils/options_tv_linux.py +211 -0
- machineconfig/utils/options_utils/options_tv_windows.py +88 -0
- machineconfig/utils/options_utils/tv_options.py +37 -0
- machineconfig/utils/path_extended.py +6 -6
- machineconfig/utils/scheduler.py +8 -2
- machineconfig/utils/schemas/fire_agents/fire_agents_input.py +1 -1
- machineconfig/utils/source_of_truth.py +6 -1
- machineconfig/utils/ssh.py +69 -18
- machineconfig/utils/ssh_utils/abc.py +1 -1
- machineconfig/utils/ssh_utils/wsl.py +107 -170
- machineconfig/utils/ssh_utils/wsl_helper.py +217 -0
- machineconfig/utils/upgrade_packages.py +4 -8
- {machineconfig-8.14.dist-info → machineconfig-8.45.dist-info}/METADATA +29 -22
- {machineconfig-8.14.dist-info → machineconfig-8.45.dist-info}/RECORD +247 -208
- machineconfig/jobs/installer/check_installations.py +0 -248
- machineconfig/profile/backup.toml +0 -49
- machineconfig/profile/mapper.toml +0 -263
- machineconfig/scripts/python/helpers_devops/cli_config.py +0 -105
- machineconfig/scripts/python/helpers_devops/cli_config_dotfile.py +0 -89
- machineconfig/scripts/python/helpers_devops/cli_data.py +0 -25
- machineconfig/scripts/python/helpers_devops/cli_repos.py +0 -208
- machineconfig/scripts/python/helpers_devops/devops_backup_retrieve.py +0 -80
- machineconfig/scripts/python/helpers_devops/themes/choose_starship_theme.bash +0 -3
- machineconfig/scripts/python/helpers_navigator/__init__.py +0 -20
- machineconfig/scripts/python/helpers_navigator/command_detail.py +0 -44
- machineconfig/scripts/python/helpers_navigator/command_tree.py +0 -620
- machineconfig/scripts/python/helpers_network/ssh_add_identity.py +0 -116
- machineconfig/scripts/python/helpers_network/ssh_add_ssh_key.py +0 -153
- machineconfig/scripts/python/helpers_network/ssh_debug_linux.py +0 -391
- machineconfig/scripts/python/helpers_network/ssh_debug_windows.py +0 -338
- machineconfig/scripts/python/helpers_repos/entrypoint.py +0 -77
- machineconfig/setup_mac/ssh/openssh_setup.sh +0 -114
- machineconfig/setup_windows/ssh/add-sshkey.ps1 +0 -29
- machineconfig/setup_windows/ssh/openssh-server.ps1 +0 -37
- machineconfig/utils/options_tv.py +0 -119
- machineconfig/utils/tst.py +0 -20
- /machineconfig/{scripts/python/helpers_agents → jobs/installer/checks}/__init__.py +0 -0
- /machineconfig/scripts/python/ai/{solutions/_shared.py → utils/shared.py} +0 -0
- /machineconfig/scripts/python/{helpers_agents/agentic_frameworks → graph}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers}/__init__.py +0 -0
- /machineconfig/scripts/python/{env_manager → helpers/helper_env}/__init__.py +0 -0
- /machineconfig/scripts/python/{env_manager → helpers/helper_env}/path_manager_backend.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_agents}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_devops → helpers/helpers_agents/agentic_frameworks}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/agentic_frameworks/fire_crush.json +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_help_search.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_helper_types.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/fire_agents_load_balancer.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/aichat/config.yaml +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/aider/.aider.conf.yml +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/copilot/config.yml +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/crush/crush.json +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/configs/gemini/settings.json +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/privacy/privacy.py +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/prompt.txt +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.ps1 +0 -0
- /machineconfig/scripts/python/{helpers_agents → helpers/helpers_agents}/templates/template.sh +0 -0
- /machineconfig/scripts/python/{helpers_devops/themes → helpers/helpers_cloud}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/cloud_helpers.py +0 -0
- /machineconfig/scripts/python/{helpers_cloud → helpers/helpers_cloud}/helpers5.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_croshell}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/crosh.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/pomodoro.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer.py +0 -0
- /machineconfig/scripts/python/{helpers_croshell → helpers/helpers_croshell}/viewer_template.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_devops}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_sessions → helpers/helpers_devops/themes}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/themes/choose_pwsh_theme.ps1 +0 -0
- /machineconfig/scripts/python/{helpers_devops/themes/choose_starship_theme.ps1 → helpers/helpers_fire_command/__init__.py} +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/cloud_manager.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/f.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/file_wrangler.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_args_helper.py +0 -0
- /machineconfig/scripts/python/{helpers_fire_command → helpers/helpers_fire_command}/fire_jobs_streamlit_helper.py +0 -0
- /machineconfig/scripts/python/{helpers_msearch → helpers/helpers_msearch}/__init__.py +0 -0
- /machineconfig/scripts/python/{helpers_navigator → helpers/helpers_navigator}/search_bar.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nfs.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/mount_nw_drive.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/onetimeshare.py +0 -0
- /machineconfig/scripts/python/{helpers_network → helpers/helpers_network}/wifi_conn.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/clone.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/repo_analyzer_1.py +0 -0
- /machineconfig/scripts/python/{helpers_repos → helpers/helpers_repos}/sync.py +0 -0
- /machineconfig/scripts/python/helpers/{ast_search.py → helpers_search/ast_search.py} +0 -0
- /machineconfig/scripts/python/helpers/{qr_code.py → helpers_search/qr_code.py} +0 -0
- /machineconfig/scripts/python/helpers/{repo_rag.py → helpers_search/repo_rag.py} +0 -0
- /machineconfig/scripts/python/helpers/{symantic_search.py → helpers_search/symantic_search.py} +0 -0
- /machineconfig/scripts/python/{helpers_utils → helpers/helpers_utils}/pdf.py +0 -0
- {machineconfig-8.14.dist-info → machineconfig-8.45.dist-info}/WHEEL +0 -0
- {machineconfig-8.14.dist-info → machineconfig-8.45.dist-info}/entry_points.txt +0 -0
- {machineconfig-8.14.dist-info → machineconfig-8.45.dist-info}/top_level.txt +0 -0
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
from typing import Optional, Literal, Annotated
|
|
3
2
|
|
|
3
|
+
from typing import Optional, Literal, Annotated
|
|
4
4
|
import typer
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
def get_tmp_file():
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import platform
|
|
10
|
+
from machineconfig.utils.accessories import randstr
|
|
11
|
+
name = randstr(8)
|
|
12
|
+
if platform.system() == "Windows":
|
|
13
|
+
suffix = "ps1"
|
|
14
|
+
else:
|
|
15
|
+
suffix = "sh"
|
|
16
|
+
tmp_file = Path.home().joinpath(f"tmp_results/tmp_files/{name}.{suffix}")
|
|
17
|
+
tmp_file.parent.mkdir(parents=True, exist_ok=True)
|
|
18
|
+
return tmp_file
|
|
19
|
+
|
|
20
|
+
|
|
7
21
|
def main(
|
|
8
22
|
cloud: Annotated[Optional[str], typer.Option(..., "--cloud", "-c", help="Cloud storage profile name. If not provided, uses default from config.")] = None,
|
|
9
23
|
repo: Annotated[Optional[str], typer.Option(..., "--repo", "-r", help="Path to the local repository. Defaults to current working directory.")] = None,
|
|
@@ -29,6 +43,7 @@ def main(
|
|
|
29
43
|
"remove-rclone-conflict": "remove-rclone-conflict",
|
|
30
44
|
}
|
|
31
45
|
on_conflict = on_conflict_mapper[on_conflict]
|
|
46
|
+
import platform
|
|
32
47
|
import git
|
|
33
48
|
from rich.console import Console
|
|
34
49
|
from rich.panel import Panel
|
|
@@ -38,10 +53,15 @@ def main(
|
|
|
38
53
|
from machineconfig.utils.source_of_truth import CONFIG_ROOT, DEFAULTS_PATH
|
|
39
54
|
from machineconfig.utils.code import get_uv_command_executing_python_script
|
|
40
55
|
from pathlib import Path
|
|
41
|
-
import platform
|
|
42
56
|
import subprocess
|
|
43
57
|
console = Console()
|
|
44
58
|
|
|
59
|
+
def _bash_single_quote(val: str) -> str:
|
|
60
|
+
return "'" + val.replace("'", "'\"'\"'") + "'"
|
|
61
|
+
|
|
62
|
+
def _ps_single_quote(val: str) -> str:
|
|
63
|
+
return "'" + val.replace("'", "''") + "'"
|
|
64
|
+
|
|
45
65
|
if cloud is None:
|
|
46
66
|
try:
|
|
47
67
|
from machineconfig.utils.io import read_ini
|
|
@@ -57,7 +77,8 @@ def main(
|
|
|
57
77
|
try:
|
|
58
78
|
repo_local_obj = git.Repo(repo_local_root, search_parent_directories=True)
|
|
59
79
|
except git.InvalidGitRepositoryError:
|
|
60
|
-
typer.
|
|
80
|
+
msg = typer.style("Error: ", fg=typer.colors.RED) + f"The specified path '{repo_local_root}' is not a valid git repository."
|
|
81
|
+
typer.echo(msg)
|
|
61
82
|
typer.Exit(code=1)
|
|
62
83
|
return ""
|
|
63
84
|
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.
|
|
@@ -80,43 +101,89 @@ def main(
|
|
|
80
101
|
if repo_remote_obj.is_dirty():
|
|
81
102
|
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"))
|
|
82
103
|
|
|
83
|
-
|
|
104
|
+
message_resolved = "sync" if message is None or message.strip() == "" else message
|
|
105
|
+
|
|
106
|
+
repo_local_root_str = str(repo_local_root)
|
|
107
|
+
repo_remote_root_str = str(repo_remote_root)
|
|
108
|
+
|
|
109
|
+
script_bash = f"""
|
|
84
110
|
echo ""
|
|
85
|
-
echo
|
|
86
|
-
cd {
|
|
111
|
+
echo -e "\\033[1;34m═════ COMMITTING LOCAL CHANGES ═════\\033[0m"
|
|
112
|
+
cd {_bash_single_quote(repo_local_root_str)}
|
|
87
113
|
git status
|
|
88
|
-
git add
|
|
89
|
-
git
|
|
114
|
+
git add -A
|
|
115
|
+
if git diff --cached --quiet; then
|
|
116
|
+
echo "-> No staged changes to commit."
|
|
117
|
+
else
|
|
118
|
+
git commit -m {_bash_single_quote(message_resolved)} || true
|
|
119
|
+
fi
|
|
90
120
|
echo ""
|
|
91
121
|
echo ""
|
|
92
|
-
echo
|
|
93
|
-
cd {
|
|
94
|
-
echo
|
|
95
|
-
# git remote remove originEnc
|
|
122
|
+
echo -e "\\033[1;34m═════ PULLING LATEST FROM REMOTE ═════\\033[0m"
|
|
123
|
+
cd {_bash_single_quote(repo_local_root_str)}
|
|
124
|
+
echo "-> Trying to removing originEnc remote from local repo if it exists."
|
|
96
125
|
git remote remove originEnc 2>/dev/null || true
|
|
97
|
-
echo
|
|
98
|
-
git remote add originEnc {
|
|
99
|
-
echo
|
|
126
|
+
echo "-> Adding originEnc remote to local repo"
|
|
127
|
+
git remote add originEnc {_bash_single_quote(repo_remote_root_str)}
|
|
128
|
+
echo "-> Fetching originEnc remote."
|
|
100
129
|
git pull originEnc master
|
|
101
130
|
|
|
102
131
|
"""
|
|
103
132
|
|
|
133
|
+
script_powershell = f"""
|
|
134
|
+
Write-Host ""
|
|
135
|
+
Write-Host "═════ COMMITTING LOCAL CHANGES ═════" -ForegroundColor Blue
|
|
136
|
+
Set-Location -LiteralPath {_ps_single_quote(repo_local_root_str)}
|
|
137
|
+
git status
|
|
138
|
+
git add -A
|
|
139
|
+
git diff --cached --quiet
|
|
140
|
+
if ($LASTEXITCODE -eq 0) {{
|
|
141
|
+
Write-Host "-> No staged changes to commit."
|
|
142
|
+
}} else {{
|
|
143
|
+
git commit -m {_ps_single_quote(message_resolved)}
|
|
144
|
+
if ($LASTEXITCODE -ne 0) {{
|
|
145
|
+
Write-Host "-> Commit skipped/failed (continuing)."
|
|
146
|
+
}}
|
|
147
|
+
}}
|
|
148
|
+
|
|
149
|
+
Write-Host ""
|
|
150
|
+
Write-Host ""
|
|
151
|
+
Write-Host "═════ PULLING LATEST FROM REMOTE ═════" -ForegroundColor Blue
|
|
152
|
+
Set-Location -LiteralPath {_ps_single_quote(repo_local_root_str)}
|
|
153
|
+
Write-Host "-> Trying to remove originEnc remote from local repo if it exists."
|
|
154
|
+
git remote remove originEnc 2>$null
|
|
155
|
+
Write-Host "-> Adding originEnc remote to local repo"
|
|
156
|
+
git remote add originEnc {_ps_single_quote(repo_remote_root_str)}
|
|
157
|
+
Write-Host "-> Fetching originEnc remote."
|
|
158
|
+
git pull originEnc master
|
|
159
|
+
exit $LASTEXITCODE
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
script = script_powershell if platform.system() == "Windows" else script_bash
|
|
163
|
+
|
|
104
164
|
if Path.home().joinpath("code/machineconfig").exists():
|
|
105
165
|
uv_project_dir = f"""{str(Path.home().joinpath("code/machineconfig"))}"""
|
|
106
166
|
uv_with = None
|
|
107
167
|
else:
|
|
108
|
-
uv_with = ["machineconfig>=8.
|
|
168
|
+
uv_with = ["machineconfig>=8.45"]
|
|
109
169
|
uv_project_dir = None
|
|
110
170
|
|
|
111
|
-
|
|
112
|
-
shell_path = Path(tempfile.mkstemp(suffix=".ps1" if platform.system() == "Windows" else ".sh")[1])
|
|
171
|
+
shell_path = get_tmp_file()
|
|
113
172
|
shell_path.write_text(script, encoding="utf-8")
|
|
114
|
-
|
|
115
|
-
command = f". {shell_path}"
|
|
116
173
|
if platform.system() == "Windows":
|
|
117
|
-
completed = subprocess.run(
|
|
174
|
+
completed = subprocess.run(
|
|
175
|
+
["powershell", "-ExecutionPolicy", "Bypass", "-File", str(shell_path)],
|
|
176
|
+
capture_output=True,
|
|
177
|
+
check=False,
|
|
178
|
+
text=True,
|
|
179
|
+
)
|
|
118
180
|
else:
|
|
119
|
-
completed = subprocess.run(
|
|
181
|
+
completed = subprocess.run(
|
|
182
|
+
["bash", str(shell_path)],
|
|
183
|
+
capture_output=True,
|
|
184
|
+
check=False,
|
|
185
|
+
text=True,
|
|
186
|
+
)
|
|
120
187
|
res = Response.from_completed_process(completed).capture().print()
|
|
121
188
|
|
|
122
189
|
if res.is_successful(strict_err=True, strict_returcode=True):
|
|
@@ -134,31 +201,37 @@ git pull originEnc master
|
|
|
134
201
|
option1 = "Delete remote copy and push local:"
|
|
135
202
|
from machineconfig.utils.meta import lambda_to_python_script
|
|
136
203
|
def func2(remote_repo: str, local_repo: str, cloud: str):
|
|
137
|
-
from machineconfig.scripts.python.helpers_repos.sync import delete_remote_repo_copy_and_push_local
|
|
204
|
+
from machineconfig.scripts.python.helpers.helpers_repos.sync import delete_remote_repo_copy_and_push_local
|
|
138
205
|
delete_remote_repo_copy_and_push_local(remote_repo=remote_repo, local_repo=local_repo, cloud=cloud)
|
|
139
206
|
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)),
|
|
140
207
|
in_global=True, import_module=False)
|
|
141
208
|
program1, _pyfile1 = get_uv_command_executing_python_script(python_script=program_1_py, uv_with=uv_with, uv_project_dir=uv_project_dir)
|
|
142
209
|
# ================================================================================
|
|
210
|
+
|
|
143
211
|
option2 = "Delete local repo and replace it with remote copy:"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
212
|
+
if platform.system() == "Windows":
|
|
213
|
+
program_2 = f"""
|
|
214
|
+
Remove-Item -LiteralPath {_ps_single_quote(repo_local_root_str)} -Recurse -Force -ErrorAction SilentlyContinue
|
|
215
|
+
Move-Item -LiteralPath {_ps_single_quote(repo_remote_root_str)} -Destination {_ps_single_quote(repo_local_root_str)} -Force
|
|
216
|
+
"""
|
|
217
|
+
else:
|
|
218
|
+
program_2 = f"""
|
|
219
|
+
rm -rfd {_bash_single_quote(repo_local_root_str)}
|
|
220
|
+
mv {_bash_single_quote(repo_remote_root_str)} {_bash_single_quote(repo_local_root_str)}
|
|
221
|
+
"""
|
|
148
222
|
if platform.system() in ["Linux", "Darwin"]:
|
|
149
223
|
program_2 += """
|
|
150
224
|
sudo chmod 600 $HOME/.ssh/*
|
|
151
225
|
sudo chmod 700 $HOME/.ssh
|
|
152
226
|
sudo chmod +x $HOME/dotfiles/scripts/linux -R
|
|
153
227
|
"""
|
|
154
|
-
|
|
155
|
-
shell_file_2 = Path(tempfile.mkstemp(suffix=".ps1" if platform.system() == "Windows" else ".sh")[1])
|
|
228
|
+
shell_file_2 = get_tmp_file()
|
|
156
229
|
shell_file_2.write_text(program_2, encoding="utf-8")
|
|
157
230
|
|
|
158
231
|
# ================================================================================
|
|
159
232
|
option3 = "Inspect repos:"
|
|
160
233
|
def func(repo_local_root: str, repo_remote_root: str):
|
|
161
|
-
from machineconfig.scripts.python.helpers_repos.sync import inspect_repos
|
|
234
|
+
from machineconfig.scripts.python.helpers.helpers_repos.sync import inspect_repos
|
|
162
235
|
inspect_repos(repo_local_root=repo_local_root, repo_remote_root=repo_remote_root)
|
|
163
236
|
# 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)})
|
|
164
237
|
# shell_file_3 = get_shell_file_executing_python_script(python_script=program_3_py, ve_path=None, executable=executable)
|
|
@@ -168,14 +241,24 @@ sudo chmod +x $HOME/dotfiles/scripts/linux -R
|
|
|
168
241
|
# ================================================================================
|
|
169
242
|
|
|
170
243
|
option4 = "Remove problematic rclone file from repo and replace with remote:"
|
|
171
|
-
|
|
244
|
+
if platform.system() == "Windows":
|
|
245
|
+
program_4 = f"""
|
|
246
|
+
Remove-Item -LiteralPath "$HOME/dotfiles/creds/rclone/rclone.conf" -Force -ErrorAction SilentlyContinue
|
|
247
|
+
New-Item -ItemType Directory -Path "$HOME/dotfiles/creds/rclone" -Force | Out-Null
|
|
248
|
+
Copy-Item -LiteralPath "$HOME/.config/machineconfig/remote/dotfiles/creds/rclone/rclone.conf" -Destination "$HOME/dotfiles/creds/rclone/rclone.conf" -Force
|
|
249
|
+
Set-Location -LiteralPath "$HOME/dotfiles"
|
|
250
|
+
git commit -am "finished merging"
|
|
251
|
+
{program1}
|
|
252
|
+
"""
|
|
253
|
+
else:
|
|
254
|
+
program_4 = f"""
|
|
172
255
|
rm $HOME/dotfiles/creds/rclone/rclone.conf
|
|
173
256
|
cp $HOME/.config/machineconfig/remote/dotfiles/creds/rclone/rclone.conf $HOME/dotfiles/creds/rclone
|
|
174
257
|
cd $HOME/dotfiles
|
|
175
258
|
git commit -am "finished merging"
|
|
176
259
|
{program1}
|
|
177
|
-
"""
|
|
178
|
-
shell_file_4 =
|
|
260
|
+
"""
|
|
261
|
+
shell_file_4 = get_tmp_file()
|
|
179
262
|
shell_file_4.write_text(program_4, encoding="utf-8")
|
|
180
263
|
# ================================================================================
|
|
181
264
|
|
|
@@ -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,12 +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
|
-
|
|
248
|
-
|
|
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
|
+
|
|
249
269
|
print(">>>>>>>>> Finished Recording")
|
|
250
|
-
return
|
|
270
|
+
return spec_path_self_managed
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
from git import Repo
|
|
2
|
-
from machineconfig.scripts.python.helpers_repos.repo_analyzer_1 import count_python_lines, get_default_branch
|
|
2
|
+
from machineconfig.scripts.python.helpers.helpers_repos.repo_analyzer_1 import count_python_lines, get_default_branch
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
import polars as pl
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from typing import
|
|
6
|
+
from typing import cast, TypedDict
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
class FileDataRow(TypedDict):
|
|
10
|
+
filename: str
|
|
11
|
+
lines: int
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CommitDataRow(TypedDict):
|
|
15
|
+
hash: str
|
|
16
|
+
dtmExit: datetime
|
|
17
|
+
lines: int
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def print_python_files_by_size_impl(repo_path: str) -> pl.DataFrame | Exception:
|
|
11
21
|
import plotly.graph_objects as go
|
|
12
22
|
import plotly.express as px
|
|
13
23
|
|
|
@@ -16,7 +26,7 @@ def print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exce
|
|
|
16
26
|
if not os.path.exists(repo_path):
|
|
17
27
|
return ValueError(f"Repository path does not exist: {repo_path}")
|
|
18
28
|
# Initialize data storage
|
|
19
|
-
file_data:
|
|
29
|
+
file_data: list[FileDataRow] = []
|
|
20
30
|
|
|
21
31
|
# Walk through the repository
|
|
22
32
|
for root, _, files in os.walk(repo_path):
|
|
@@ -66,7 +76,8 @@ def print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exce
|
|
|
66
76
|
table.add_column("Lines", justify="right")
|
|
67
77
|
|
|
68
78
|
for idx, row in enumerate(df.iter_rows(named=True), 1):
|
|
69
|
-
|
|
79
|
+
typed_row = cast(FileDataRow, row)
|
|
80
|
+
table.add_row(str(idx), typed_row["filename"], f"{typed_row['lines']:,}")
|
|
70
81
|
|
|
71
82
|
console.print(table)
|
|
72
83
|
print(f"\n📁 Total Python files: {file_count}")
|
|
@@ -118,7 +129,7 @@ def print_python_files_by_size_impl(repo_path: str) -> "Union[pl.DataFrame, Exce
|
|
|
118
129
|
)
|
|
119
130
|
|
|
120
131
|
# Define pie chart figure before conditionally using it
|
|
121
|
-
fig2:
|
|
132
|
+
fig2: go.Figure | None = None
|
|
122
133
|
|
|
123
134
|
# Add pie chart showing distribution
|
|
124
135
|
if len(df) > top_n:
|
|
@@ -175,14 +186,15 @@ def analyze_over_time(repo_path: str):
|
|
|
175
186
|
repo: Repo = Repo(repo_path)
|
|
176
187
|
branch_name: str = get_default_branch(repo)
|
|
177
188
|
print(f"🔍 Using branch: {branch_name}")
|
|
178
|
-
commit_data:
|
|
189
|
+
commit_data: list[CommitDataRow] = []
|
|
179
190
|
print("⏳ Analyzing commits...")
|
|
180
191
|
try:
|
|
181
192
|
commits = list(repo.iter_commits(branch_name))
|
|
182
193
|
from datetime import timezone
|
|
183
194
|
from rich.progress import track
|
|
184
195
|
for commit in track(commits, description="Processing commits..."):
|
|
185
|
-
|
|
196
|
+
lines, _files = count_python_lines(commit)
|
|
197
|
+
commit_data.append({"hash": commit.hexsha, "dtmExit": datetime.fromtimestamp(commit.committed_date, tz=timezone.utc), "lines": lines})
|
|
186
198
|
except Exception as e:
|
|
187
199
|
print(f"❌ Error analyzing commits: {str(e)}")
|
|
188
200
|
return
|
|
@@ -199,20 +211,50 @@ def analyze_over_time(repo_path: str):
|
|
|
199
211
|
# Add markers for significant points (min, max, last)
|
|
200
212
|
min_idx = df["lines"].arg_min()
|
|
201
213
|
max_idx = df["lines"].arg_max()
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
214
|
+
last_point = cast(CommitDataRow, df.slice(-1, 1).to_dicts()[0])
|
|
215
|
+
|
|
216
|
+
marker_x: list[datetime] = []
|
|
217
|
+
marker_y: list[int] = []
|
|
218
|
+
marker_sizes: list[int] = []
|
|
219
|
+
marker_colors: list[str] = []
|
|
220
|
+
marker_symbols: list[str] = []
|
|
221
|
+
marker_texts: list[str] = []
|
|
222
|
+
|
|
223
|
+
if min_idx is not None:
|
|
224
|
+
min_point = cast(CommitDataRow, df.slice(min_idx, 1).to_dicts()[0])
|
|
225
|
+
marker_x.append(min_point["dtmExit"])
|
|
226
|
+
marker_y.append(min_point["lines"])
|
|
227
|
+
marker_sizes.append(10)
|
|
228
|
+
marker_colors.append("#ff4f4f")
|
|
229
|
+
marker_symbols.append("circle")
|
|
230
|
+
marker_texts.append(f"🔽 Min: {min_point['lines']:,} lines")
|
|
231
|
+
|
|
232
|
+
if max_idx is not None:
|
|
233
|
+
max_point = cast(CommitDataRow, df.slice(max_idx, 1).to_dicts()[0])
|
|
234
|
+
marker_x.append(max_point["dtmExit"])
|
|
235
|
+
marker_y.append(max_point["lines"])
|
|
236
|
+
marker_sizes.append(14)
|
|
237
|
+
marker_colors.append("#4fff4f")
|
|
238
|
+
marker_symbols.append("star")
|
|
239
|
+
marker_texts.append(f"🔼 Max: {max_point['lines']:,} lines")
|
|
240
|
+
|
|
241
|
+
marker_x.append(last_point["dtmExit"])
|
|
242
|
+
marker_y.append(last_point["lines"])
|
|
243
|
+
marker_sizes.append(12)
|
|
244
|
+
marker_colors.append("#4f4fff")
|
|
245
|
+
marker_symbols.append("diamond")
|
|
246
|
+
marker_texts.append(f"📊 Current: {last_point['lines']:,} lines")
|
|
205
247
|
|
|
206
248
|
# Add markers for significant points
|
|
207
249
|
fig.add_trace(
|
|
208
250
|
go.Scatter(
|
|
209
|
-
x=
|
|
210
|
-
y=
|
|
251
|
+
x=marker_x,
|
|
252
|
+
y=marker_y,
|
|
211
253
|
mode="markers",
|
|
212
|
-
marker={"size":
|
|
254
|
+
marker={"size": marker_sizes, "color": marker_colors, "line": {"width": 2, "color": "white"}, "symbol": marker_symbols},
|
|
213
255
|
name="Key Points",
|
|
214
256
|
hovertemplate="<b>%{text}</b><br>Date: %{x}<br>Lines: %{y:,}<extra></extra>",
|
|
215
|
-
text=
|
|
257
|
+
text=marker_texts,
|
|
216
258
|
)
|
|
217
259
|
)
|
|
218
260
|
|
|
@@ -264,6 +306,8 @@ def analyze_over_time(repo_path: str):
|
|
|
264
306
|
# Print statistics
|
|
265
307
|
print("\n📊 Repository Statistics:")
|
|
266
308
|
print(f"📚 Total commits analyzed: {len(df)}")
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
print(f"
|
|
309
|
+
initial_lines = int(df['lines'][-1])
|
|
310
|
+
final_lines = int(df['lines'][0])
|
|
311
|
+
print(f"🔙 Initial line count: {initial_lines:,}")
|
|
312
|
+
print(f"🔜 Final line count: {final_lines:,}")
|
|
313
|
+
print(f"📈 Net change: {final_lines - initial_lines:,} lines")
|
|
@@ -246,12 +246,6 @@ def update_repository(repo: git.Repo, auto_uv_sync: bool, allow_password_prompt:
|
|
|
246
246
|
result["permissions_updated"] = True
|
|
247
247
|
print(f"✅ Set permissions for {linux_jobs_path}")
|
|
248
248
|
|
|
249
|
-
lf_exe_path = repo_path / "src" / "machineconfig" / "settings" / "lf" / "linux" / "exe"
|
|
250
|
-
if lf_exe_path.exists():
|
|
251
|
-
set_permissions_recursive(lf_exe_path)
|
|
252
|
-
result["permissions_updated"] = True
|
|
253
|
-
print(f"✅ Set permissions for {lf_exe_path}")
|
|
254
|
-
|
|
255
249
|
# Run uv sync if dependencies changed and auto_sync is enabled
|
|
256
250
|
if result["dependencies_changed"] and auto_uv_sync:
|
|
257
251
|
result["uv_sync_ran"] = True
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def list_available_scripts(where: Literal["all", "a", "private", "p", "public", "b", "library", "l", "dynamic", "d", "custom", "c"]) -> None:
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from machineconfig.utils.source_of_truth import CONFIG_ROOT, LIBRARY_ROOT, DEFAULTS_PATH
|
|
8
|
+
|
|
9
|
+
private_root = Path.home().joinpath("dotfiles/scripts")
|
|
10
|
+
public_root = CONFIG_ROOT.joinpath("scripts")
|
|
11
|
+
library_root = LIBRARY_ROOT.joinpath("jobs", "scripts")
|
|
12
|
+
|
|
13
|
+
def get_custom_roots() -> list[Path]:
|
|
14
|
+
custom_roots: list[Path] = []
|
|
15
|
+
if DEFAULTS_PATH.is_file():
|
|
16
|
+
from configparser import ConfigParser
|
|
17
|
+
config = ConfigParser()
|
|
18
|
+
config.read(DEFAULTS_PATH)
|
|
19
|
+
if config.has_section("general") and config.has_option("general", "scripts"):
|
|
20
|
+
custom_dirs = config.get("general", "scripts").split(",")
|
|
21
|
+
for custom_dir in custom_dirs:
|
|
22
|
+
custom_path = Path(custom_dir.strip()).expanduser().resolve()
|
|
23
|
+
if custom_path.is_dir():
|
|
24
|
+
custom_roots.append(custom_path)
|
|
25
|
+
return custom_roots
|
|
26
|
+
|
|
27
|
+
locations: dict[str, Path | str] = {}
|
|
28
|
+
match where:
|
|
29
|
+
case "all" | "a":
|
|
30
|
+
locations = {"private": private_root, "public": public_root, "library": library_root}
|
|
31
|
+
for idx, custom in enumerate(get_custom_roots()): locations[f"custom_{idx}"] = custom
|
|
32
|
+
locations["dynamic"] = "https://github.com/thisismygitrepo/machineconfig/tree/main/src/machineconfig/jobs/scripts_dynamic"
|
|
33
|
+
case "private" | "p":
|
|
34
|
+
locations = {"private": private_root}
|
|
35
|
+
case "public" | "b":
|
|
36
|
+
locations = {"public": public_root}
|
|
37
|
+
case "library" | "l":
|
|
38
|
+
locations = {"library": library_root}
|
|
39
|
+
case "dynamic" | "d":
|
|
40
|
+
locations = {"dynamic": "https://github.com/thisismygitrepo/machineconfig/tree/main/src/machineconfig/jobs/scripts_dynamic"}
|
|
41
|
+
case "custom" | "c":
|
|
42
|
+
for idx, custom in enumerate(get_custom_roots()): locations[f"custom_{idx}"] = custom
|
|
43
|
+
|
|
44
|
+
def _print_files_by_type(files: list[str]) -> None:
|
|
45
|
+
categories: dict[str, list[str]] = {".py": [], ".sh": [], ".ps1": [], ".cmd": [], ".bat": [], "other": []}
|
|
46
|
+
for f in files:
|
|
47
|
+
ext = Path(f).suffix.lower() if "." in str(f) else ""
|
|
48
|
+
if ext in categories: categories[ext].append(str(f))
|
|
49
|
+
else: categories["other"].append(str(f))
|
|
50
|
+
for ext, cat_files in categories.items():
|
|
51
|
+
if cat_files:
|
|
52
|
+
label = ext if ext else "other"
|
|
53
|
+
print(f" [{label}]")
|
|
54
|
+
for cf in sorted(cat_files): print(f" • {cf}")
|
|
55
|
+
|
|
56
|
+
for loc_name, loc_path in locations.items():
|
|
57
|
+
print(f"\n📁 {loc_name.upper()} ({loc_path}):")
|
|
58
|
+
print("-" * 60)
|
|
59
|
+
if isinstance(loc_path, Path):
|
|
60
|
+
if loc_path.is_dir():
|
|
61
|
+
files = [f for f in loc_path.rglob("*") if f.is_file() and f.suffix in (".py", ".sh", ".ps1", ".bat", ".cmd", "")]
|
|
62
|
+
if files:
|
|
63
|
+
relative_files = [str(f.relative_to(loc_path)) for f in files]
|
|
64
|
+
_print_files_by_type(relative_files)
|
|
65
|
+
else:
|
|
66
|
+
print(" (empty)")
|
|
67
|
+
else:
|
|
68
|
+
print(" ⚠️ Directory does not exist")
|
|
69
|
+
else:
|
|
70
|
+
api_url = "https://api.github.com/repos/thisismygitrepo/machineconfig/contents/src/machineconfig/jobs/scripts_dynamic"
|
|
71
|
+
try:
|
|
72
|
+
import requests
|
|
73
|
+
response = requests.get(api_url, timeout=10)
|
|
74
|
+
if response.status_code == 200:
|
|
75
|
+
items = response.json()
|
|
76
|
+
files = [item["name"] for item in items if item["type"] == "file"]
|
|
77
|
+
_print_files_by_type(files)
|
|
78
|
+
else:
|
|
79
|
+
print(f" ⚠️ Could not fetch from GitHub (status: {response.status_code})")
|
|
80
|
+
except Exception as e:
|
|
81
|
+
print(f" ⚠️ Could not fetch from GitHub: {e}")
|
|
File without changes
|