machineconfig 8.14__py3-none-any.whl → 8.50__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 +63 -58
- 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 +274 -0
- machineconfig/scripts/python/{helpers_devops → helpers/helpers_devops}/cli_self.py +40 -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 +117 -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 +186 -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 +47 -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 +25 -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 +11 -91
- machineconfig/utils/installer_utils/github_release_scraper.py +99 -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/io.py +25 -8
- 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/copy_from_here.py +17 -12
- machineconfig/utils/ssh_utils/utils.py +21 -5
- 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.50.dist-info}/METADATA +29 -22
- {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/RECORD +251 -211
- 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.50.dist-info}/WHEEL +0 -0
- {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/entry_points.txt +0 -0
- {machineconfig-8.14.dist-info → machineconfig-8.50.dist-info}/top_level.txt +0 -0
|
@@ -4,22 +4,425 @@
|
|
|
4
4
|
# requires-python = ">=3.13"
|
|
5
5
|
# dependencies = [
|
|
6
6
|
# "rich",
|
|
7
|
-
# "
|
|
8
|
-
# "typer>=0.12",
|
|
9
|
-
# "loguru",
|
|
10
|
-
# "numpy",
|
|
7
|
+
# "psutil",
|
|
11
8
|
# ]
|
|
12
9
|
# ///
|
|
13
10
|
|
|
14
11
|
"""
|
|
15
12
|
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
import platform
|
|
15
|
+
import time
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
|
|
18
|
+
import psutil
|
|
19
|
+
from rich import box
|
|
20
|
+
from rich.align import Align
|
|
21
|
+
from rich.console import Console
|
|
22
|
+
from rich.layout import Layout
|
|
23
|
+
from rich.panel import Panel
|
|
24
|
+
from rich.progress import BarColumn, Progress, SpinnerColumn, TextColumn
|
|
25
|
+
from rich.rule import Rule
|
|
26
|
+
from rich.table import Table
|
|
27
|
+
from rich.text import Text
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
31
|
+
# Constants & Configuration
|
|
32
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
33
|
+
|
|
34
|
+
DEFAULT_FREQ_MHZ: float = 2500.0
|
|
35
|
+
OPS_PER_CYCLE_AVX2: int = 16 # AVX2: ~16 double-precision FLOPs/cycle
|
|
36
|
+
BYTES_PER_GB: int = 1024**3
|
|
37
|
+
|
|
38
|
+
# Tier thresholds and styling
|
|
39
|
+
TIER_CONFIG: list[tuple[int, str, str]] = [
|
|
40
|
+
(500, "OBSOLETE", "grey50"),
|
|
41
|
+
(1000, "CONSUMER", "green"),
|
|
42
|
+
(2000, "WORKSTATION", "blue"),
|
|
43
|
+
(4000, "HIGH-PERFORMANCE", "magenta"),
|
|
44
|
+
(999999, "SERVER GRADE", "bold red"),
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
# Visual theme
|
|
48
|
+
THEME = {
|
|
49
|
+
"primary": "cyan",
|
|
50
|
+
"secondary": "magenta",
|
|
51
|
+
"accent": "yellow",
|
|
52
|
+
"success": "green",
|
|
53
|
+
"header_bg": "blue",
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console = Console()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
60
|
+
# Data Structures
|
|
61
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class HardwareSpecs:
|
|
66
|
+
"""Container for hardware specifications."""
|
|
67
|
+
|
|
68
|
+
physical_cores: int = 0
|
|
69
|
+
logical_cores: int = 0
|
|
70
|
+
max_freq_mhz: float = 0.0
|
|
71
|
+
current_freq_mhz: float = 0.0
|
|
72
|
+
total_ram_bytes: int = 0
|
|
73
|
+
available_ram_bytes: int = 0
|
|
74
|
+
ram_percent_used: float = 0.0
|
|
75
|
+
architecture: str = ""
|
|
76
|
+
cpu_model: str = ""
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@dataclass
|
|
80
|
+
class ComputeMetrics:
|
|
81
|
+
"""Calculated compute performance metrics."""
|
|
82
|
+
|
|
83
|
+
compute_index: int = 0
|
|
84
|
+
theoretical_gflops: float = 0.0
|
|
85
|
+
tier_name: str = ""
|
|
86
|
+
tier_style: str = ""
|
|
87
|
+
core_score: float = 0.0
|
|
88
|
+
freq_multiplier: float = 0.0
|
|
89
|
+
ram_score: float = 0.0
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
93
|
+
# System Scanner
|
|
94
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@dataclass
|
|
98
|
+
class SystemScanner:
|
|
99
|
+
"""Scans and analyzes system hardware for compute capability metrics."""
|
|
100
|
+
|
|
101
|
+
specs: HardwareSpecs = field(default_factory=HardwareSpecs)
|
|
102
|
+
metrics: ComputeMetrics = field(default_factory=ComputeMetrics)
|
|
103
|
+
|
|
104
|
+
@staticmethod
|
|
105
|
+
def format_bytes(num_bytes: int | float, suffix: str = "B") -> str:
|
|
106
|
+
"""Scale bytes to human-readable format with proper unit prefix."""
|
|
107
|
+
factor = 1024.0
|
|
108
|
+
value = float(num_bytes)
|
|
109
|
+
for unit in ("", "K", "M", "G", "T", "P", "E"):
|
|
110
|
+
if abs(value) < factor:
|
|
111
|
+
return f"{value:.2f} {unit}{suffix}"
|
|
112
|
+
value /= factor
|
|
113
|
+
return f"{value:.2f} Z{suffix}"
|
|
114
|
+
|
|
115
|
+
def scan_hardware(self) -> None:
|
|
116
|
+
"""Gather hardware specs using psutil."""
|
|
117
|
+
# CPU cores - prefer physical, fallback to logical
|
|
118
|
+
physical = psutil.cpu_count(logical=False)
|
|
119
|
+
logical = psutil.cpu_count(logical=True)
|
|
120
|
+
p_cores = physical if physical else (logical if logical else 1)
|
|
121
|
+
l_cores = logical if logical else p_cores
|
|
122
|
+
|
|
123
|
+
# CPU frequency with fallback
|
|
124
|
+
max_freq = DEFAULT_FREQ_MHZ
|
|
125
|
+
current_freq = DEFAULT_FREQ_MHZ
|
|
126
|
+
try:
|
|
127
|
+
freq = psutil.cpu_freq()
|
|
128
|
+
if freq: # Can be None on some systems
|
|
129
|
+
max_freq = freq.max if freq.max > 0 else freq.current
|
|
130
|
+
current_freq = freq.current
|
|
131
|
+
except (AttributeError, FileNotFoundError, PermissionError, RuntimeError):
|
|
132
|
+
pass # Use defaults
|
|
133
|
+
|
|
134
|
+
# Memory info
|
|
135
|
+
vmem = psutil.virtual_memory()
|
|
136
|
+
|
|
137
|
+
# CPU model detection
|
|
138
|
+
cpu_model = self._detect_cpu_model()
|
|
139
|
+
|
|
140
|
+
self.specs = HardwareSpecs(
|
|
141
|
+
physical_cores=p_cores,
|
|
142
|
+
logical_cores=l_cores,
|
|
143
|
+
max_freq_mhz=max_freq,
|
|
144
|
+
current_freq_mhz=current_freq,
|
|
145
|
+
total_ram_bytes=vmem.total,
|
|
146
|
+
available_ram_bytes=vmem.available,
|
|
147
|
+
ram_percent_used=vmem.percent,
|
|
148
|
+
architecture=platform.machine() or "Unknown",
|
|
149
|
+
cpu_model=cpu_model,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
@staticmethod
|
|
153
|
+
def _detect_cpu_model() -> str:
|
|
154
|
+
"""Detect CPU model string from platform info."""
|
|
155
|
+
try:
|
|
156
|
+
return platform.processor() or "Unknown Processor"
|
|
157
|
+
except (OSError, AttributeError):
|
|
158
|
+
return "Unknown Processor"
|
|
159
|
+
|
|
160
|
+
def calculate_metrics(self) -> None:
|
|
161
|
+
"""Calculate compute power index and theoretical GFLOPS."""
|
|
162
|
+
s = self.specs
|
|
163
|
+
|
|
164
|
+
# Core score: physical cores weighted heavily, threads add bonus
|
|
165
|
+
thread_bonus = max(0, s.logical_cores - s.physical_cores)
|
|
166
|
+
core_score = (s.physical_cores * 100.0) + (thread_bonus * 30.0)
|
|
167
|
+
|
|
168
|
+
# Frequency multiplier (normalized to 2.5 GHz baseline)
|
|
169
|
+
ghz = s.max_freq_mhz / 1000.0
|
|
170
|
+
freq_multiplier = ghz / 2.5
|
|
171
|
+
|
|
172
|
+
cpu_total = core_score * freq_multiplier
|
|
173
|
+
|
|
174
|
+
# Memory bonus (5 points per GB)
|
|
175
|
+
ram_gb = s.total_ram_bytes / BYTES_PER_GB
|
|
176
|
+
ram_score = ram_gb * 5.0
|
|
177
|
+
|
|
178
|
+
compute_index = int(cpu_total + ram_score)
|
|
179
|
+
|
|
180
|
+
# Theoretical GFLOPS (Rpeak) = cores × GHz × FLOPs/cycle
|
|
181
|
+
theoretical_gflops = s.physical_cores * ghz * OPS_PER_CYCLE_AVX2
|
|
182
|
+
|
|
183
|
+
# Determine tier
|
|
184
|
+
tier_name, tier_style = "UNKNOWN", "white"
|
|
185
|
+
for threshold, name, style in TIER_CONFIG:
|
|
186
|
+
if compute_index < threshold:
|
|
187
|
+
tier_name, tier_style = name, style
|
|
188
|
+
break
|
|
189
|
+
|
|
190
|
+
self.metrics = ComputeMetrics(
|
|
191
|
+
compute_index=compute_index,
|
|
192
|
+
theoretical_gflops=theoretical_gflops,
|
|
193
|
+
tier_name=tier_name,
|
|
194
|
+
tier_style=tier_style,
|
|
195
|
+
core_score=core_score,
|
|
196
|
+
freq_multiplier=freq_multiplier,
|
|
197
|
+
ram_score=ram_score,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
def _build_header(self) -> Panel:
|
|
201
|
+
"""Build the header panel."""
|
|
202
|
+
title = Text()
|
|
203
|
+
title.append("╔══════════════════════════════════════╗\n", style="bold cyan")
|
|
204
|
+
title.append("║ ", style="bold cyan")
|
|
205
|
+
title.append("SYSTEM COMPUTE ANALYZER", style="bold white")
|
|
206
|
+
title.append(" ║\n", style="bold cyan")
|
|
207
|
+
title.append("╚══════════════════════════════════════╝", style="bold cyan")
|
|
208
|
+
|
|
209
|
+
return Panel(
|
|
210
|
+
Align.center(title),
|
|
211
|
+
box=box.DOUBLE,
|
|
212
|
+
style=THEME["header_bg"],
|
|
213
|
+
padding=(0, 2),
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
def _build_cpu_panel(self) -> Panel:
|
|
217
|
+
"""Build the CPU information panel."""
|
|
218
|
+
s = self.specs
|
|
219
|
+
table = Table(
|
|
220
|
+
show_header=True,
|
|
221
|
+
header_style=f"bold {THEME['primary']}",
|
|
222
|
+
expand=True,
|
|
223
|
+
box=box.ROUNDED,
|
|
224
|
+
border_style="dim cyan",
|
|
225
|
+
row_styles=["", "dim"],
|
|
226
|
+
)
|
|
227
|
+
table.add_column("⚡ Attribute", style="cyan", no_wrap=True)
|
|
228
|
+
table.add_column("Value", style="bold white", justify="right")
|
|
229
|
+
|
|
230
|
+
# Cores with visual indicator
|
|
231
|
+
cores_bar = "█" * min(s.physical_cores, 16) + "░" * max(0, 16 - s.physical_cores)
|
|
232
|
+
table.add_row("Physical Cores", f"{s.physical_cores} [{THEME['primary']}]{cores_bar}[/]")
|
|
233
|
+
table.add_row("Logical Threads", str(s.logical_cores))
|
|
234
|
+
table.add_row("──────────────", "────────────")
|
|
235
|
+
table.add_row("Max Frequency", f"[bold yellow]{s.max_freq_mhz:,.0f}[/] MHz")
|
|
236
|
+
table.add_row("Current Freq", f"{s.current_freq_mhz:,.0f} MHz")
|
|
237
|
+
table.add_row("Architecture", f"[bold]{s.architecture}[/]")
|
|
238
|
+
|
|
239
|
+
return Panel(
|
|
240
|
+
table,
|
|
241
|
+
title=f"[bold {THEME['primary']}]◆ CPU COMPUTE UNIT ◆[/]",
|
|
242
|
+
border_style=THEME["primary"],
|
|
243
|
+
box=box.HEAVY,
|
|
244
|
+
padding=(1, 1),
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
def _build_memory_panel(self) -> Panel:
|
|
248
|
+
"""Build the memory information panel."""
|
|
249
|
+
s = self.specs
|
|
250
|
+
table = Table(
|
|
251
|
+
show_header=True,
|
|
252
|
+
header_style=f"bold {THEME['secondary']}",
|
|
253
|
+
expand=True,
|
|
254
|
+
box=box.ROUNDED,
|
|
255
|
+
border_style="dim magenta",
|
|
256
|
+
row_styles=["", "dim"],
|
|
257
|
+
)
|
|
258
|
+
table.add_column("💾 Attribute", style="magenta", no_wrap=True)
|
|
259
|
+
table.add_column("Value", style="bold white", justify="right")
|
|
260
|
+
|
|
261
|
+
# Memory usage bar
|
|
262
|
+
used_blocks = int(s.ram_percent_used / 10)
|
|
263
|
+
free_blocks = 10 - used_blocks
|
|
264
|
+
mem_bar = f"[green]{'█' * free_blocks}[/][red]{'█' * used_blocks}[/]"
|
|
265
|
+
|
|
266
|
+
table.add_row("Total Memory", f"[bold yellow]{self.format_bytes(s.total_ram_bytes)}[/]")
|
|
267
|
+
table.add_row("Available", self.format_bytes(s.available_ram_bytes))
|
|
268
|
+
table.add_row("──────────────", "────────────")
|
|
269
|
+
table.add_row("Usage", f"{s.ram_percent_used:.1f}% {mem_bar}")
|
|
270
|
+
|
|
271
|
+
return Panel(
|
|
272
|
+
table,
|
|
273
|
+
title=f"[bold {THEME['secondary']}]◆ MEMORY MATRIX ◆[/]",
|
|
274
|
+
border_style=THEME["secondary"],
|
|
275
|
+
box=box.HEAVY,
|
|
276
|
+
padding=(1, 1),
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
def _build_metrics_panel(self) -> Panel:
|
|
280
|
+
"""Build the performance metrics panel."""
|
|
281
|
+
m = self.metrics
|
|
282
|
+
|
|
283
|
+
# Build score display with visual flair
|
|
284
|
+
content = Table.grid(padding=(0, 2), expand=True)
|
|
285
|
+
content.add_column(justify="center")
|
|
286
|
+
|
|
287
|
+
# Main score with large emphasis
|
|
288
|
+
score_text = Text()
|
|
289
|
+
score_text.append("\n┌─────────────────────────────────────────┐\n", style="dim yellow")
|
|
290
|
+
score_text.append("│ COMPUTE POWER INDEX │ ", style="dim yellow")
|
|
291
|
+
score_text.append(f"{m.compute_index:,}", style="bold yellow on black")
|
|
292
|
+
score_text.append(" │\n", style="dim yellow")
|
|
293
|
+
score_text.append("└─────────────────────────────────────────┘\n", style="dim yellow")
|
|
294
|
+
|
|
295
|
+
content.add_row(Align.center(score_text))
|
|
296
|
+
|
|
297
|
+
# Breakdown table
|
|
298
|
+
breakdown = Table(show_header=False, box=None, padding=(0, 4))
|
|
299
|
+
breakdown.add_column(style="dim")
|
|
300
|
+
breakdown.add_column(style="bold", justify="right")
|
|
301
|
+
breakdown.add_row("Core Score:", f"{m.core_score:.0f}")
|
|
302
|
+
breakdown.add_row("Freq Multiplier:", f"×{m.freq_multiplier:.2f}")
|
|
303
|
+
breakdown.add_row("RAM Bonus:", f"+{m.ram_score:.0f}")
|
|
304
|
+
|
|
305
|
+
content.add_row(Align.center(breakdown))
|
|
306
|
+
|
|
307
|
+
# Theoretical GFLOPS
|
|
308
|
+
gflops_text = Text()
|
|
309
|
+
gflops_text.append("\n⚡ Theoretical Rpeak: ", style="dim white")
|
|
310
|
+
gflops_text.append(f"{m.theoretical_gflops:.2f} GFLOPS", style="bold red underline")
|
|
311
|
+
gflops_text.append(" (AVX2)", style="dim")
|
|
312
|
+
content.add_row(Align.center(gflops_text))
|
|
313
|
+
|
|
314
|
+
# Tier with styled badge
|
|
315
|
+
tier_text = Text()
|
|
316
|
+
tier_text.append("\n\n◉ CLASSIFICATION: ", style="bold white")
|
|
317
|
+
tier_text.append(f" {m.tier_name} ", style=f"bold white on {m.tier_style}")
|
|
318
|
+
tier_text.append("\n", style="")
|
|
319
|
+
content.add_row(Align.center(tier_text))
|
|
320
|
+
|
|
321
|
+
return Panel(
|
|
322
|
+
content,
|
|
323
|
+
title=f"[bold {THEME['accent']}]★ PERFORMANCE METRICS ★[/]",
|
|
324
|
+
border_style=THEME["accent"],
|
|
325
|
+
box=box.DOUBLE,
|
|
326
|
+
padding=(1, 2),
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
def render_dashboard(self) -> Layout:
|
|
330
|
+
"""Generate the complete dashboard layout."""
|
|
331
|
+
layout = Layout()
|
|
332
|
+
|
|
333
|
+
layout.split_column(
|
|
334
|
+
Layout(self._build_header(), name="header", size=5),
|
|
335
|
+
Layout(name="body", ratio=2),
|
|
336
|
+
Layout(Rule("─", style="dim"), name="divider", size=1),
|
|
337
|
+
Layout(self._build_metrics_panel(), name="metrics", size=14),
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
layout["body"].split_row(
|
|
341
|
+
Layout(self._build_cpu_panel(), name="cpu"),
|
|
342
|
+
Layout(self._build_memory_panel(), name="memory"),
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
return layout
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
349
|
+
# Progress Animation
|
|
350
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def run_scan_animation(scanner: SystemScanner) -> None:
|
|
354
|
+
"""Run the scanning progress animation."""
|
|
355
|
+
scan_complete = False
|
|
356
|
+
|
|
357
|
+
with Progress(
|
|
358
|
+
SpinnerColumn("dots12", style="bold cyan"),
|
|
359
|
+
TextColumn("[bold]{task.description}"),
|
|
360
|
+
BarColumn(bar_width=40, complete_style="green", finished_style="bold green"),
|
|
361
|
+
TextColumn("[bold cyan]{task.percentage:>3.0f}%"),
|
|
362
|
+
console=console,
|
|
363
|
+
expand=True,
|
|
364
|
+
) as progress:
|
|
365
|
+
task1 = progress.add_task(f"[{THEME['primary']}]⚙ Probing CPU Architecture...", total=100)
|
|
366
|
+
task2 = progress.add_task(
|
|
367
|
+
f"[{THEME['secondary']}]💾 Analyzing Memory Banks...",
|
|
368
|
+
total=100,
|
|
369
|
+
start=False,
|
|
370
|
+
)
|
|
371
|
+
task3 = progress.add_task(
|
|
372
|
+
f"[{THEME['accent']}]📊 Calculating Vector Potential...",
|
|
373
|
+
total=100,
|
|
374
|
+
start=False,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
while not progress.finished:
|
|
378
|
+
# Task 1: CPU probe
|
|
379
|
+
if progress.tasks[0].completed < 100:
|
|
380
|
+
progress.update(task1, advance=2.5)
|
|
381
|
+
if progress.tasks[0].completed >= 50 and not scan_complete:
|
|
382
|
+
scanner.scan_hardware()
|
|
383
|
+
scan_complete = True
|
|
384
|
+
elif not progress.tasks[1].started:
|
|
385
|
+
progress.start_task(task2)
|
|
386
|
+
|
|
387
|
+
# Task 2: Memory analysis
|
|
388
|
+
if progress.tasks[1].started and progress.tasks[1].completed < 100:
|
|
389
|
+
progress.update(task2, advance=3.5)
|
|
390
|
+
elif progress.tasks[1].completed >= 100 and not progress.tasks[2].started:
|
|
391
|
+
progress.start_task(task3)
|
|
392
|
+
|
|
393
|
+
# Task 3: Calculation
|
|
394
|
+
if progress.tasks[2].started:
|
|
395
|
+
progress.update(task3, advance=4.5)
|
|
396
|
+
|
|
397
|
+
time.sleep(0.025)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
401
|
+
# Entry Point
|
|
402
|
+
# ══════════════════════════════════════════════════════════════════════════════
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def main() -> None:
|
|
406
|
+
"""Main entry point for the system compute analyzer."""
|
|
407
|
+
scanner = SystemScanner()
|
|
408
|
+
|
|
409
|
+
console.clear()
|
|
410
|
+
console.print()
|
|
411
|
+
|
|
412
|
+
# Phase 1: Animated scanning
|
|
413
|
+
run_scan_animation(scanner)
|
|
414
|
+
|
|
415
|
+
# Phase 2: Calculate metrics
|
|
416
|
+
scanner.calculate_metrics()
|
|
417
|
+
|
|
418
|
+
# Phase 3: Display results
|
|
419
|
+
console.print()
|
|
420
|
+
console.print(scanner.render_dashboard())
|
|
421
|
+
console.print()
|
|
22
422
|
|
|
23
423
|
|
|
24
424
|
if __name__ == "__main__":
|
|
25
|
-
|
|
425
|
+
try:
|
|
426
|
+
main()
|
|
427
|
+
except KeyboardInterrupt:
|
|
428
|
+
console.print("\n[bold red]✖ Analysis Aborted by User[/bold red]\n")
|
|
@@ -19,54 +19,111 @@ from machineconfig.utils.source_of_truth import LIBRARY_ROOT, CONFIG_ROOT
|
|
|
19
19
|
import platform
|
|
20
20
|
import subprocess
|
|
21
21
|
import tomllib
|
|
22
|
-
from typing import Optional, Any, TypedDict, Literal
|
|
22
|
+
from typing import Optional, Any, TypedDict, Literal, TypeAlias
|
|
23
|
+
from pathlib import Path
|
|
23
24
|
|
|
24
25
|
|
|
26
|
+
LIBRARY_MAPPER_PATH = LIBRARY_ROOT.joinpath("profile/mapper_dotfiles.toml")
|
|
27
|
+
USER_MAPPER_PATH = Path.home().joinpath("dotfiles/machineconfig/mapper_dotfiles.toml")
|
|
28
|
+
|
|
25
29
|
system = platform.system() # Linux or Windows
|
|
26
30
|
ERROR_LIST: list[Any] = [] # append to this after every exception captured.
|
|
27
31
|
SYSTEM = system.lower()
|
|
28
32
|
|
|
29
33
|
console = Console()
|
|
30
34
|
|
|
35
|
+
OS_ALIASES = {
|
|
36
|
+
"mac": "darwin",
|
|
37
|
+
"macos": "darwin",
|
|
38
|
+
"osx": "darwin",
|
|
39
|
+
}
|
|
40
|
+
REPO_ALIASES = {
|
|
41
|
+
"l": "library",
|
|
42
|
+
"i": "user",
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _normalize_os_name(value: str) -> str:
|
|
47
|
+
return OS_ALIASES.get(value.strip().lower(), value.strip().lower())
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _normalize_repo_name(value: str) -> str:
|
|
51
|
+
return REPO_ALIASES.get(value.strip().lower(), value.strip().lower())
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _parse_os_field(os_field: Any) -> set[str]:
|
|
55
|
+
if not os_field:
|
|
56
|
+
return {"any"}
|
|
57
|
+
if isinstance(os_field, list):
|
|
58
|
+
raw_values = [str(item) for item in os_field]
|
|
59
|
+
else:
|
|
60
|
+
raw_values = str(os_field).split(",")
|
|
61
|
+
values: set[str] = set()
|
|
62
|
+
for raw in raw_values:
|
|
63
|
+
token = _normalize_os_name(raw)
|
|
64
|
+
if not token:
|
|
65
|
+
continue
|
|
66
|
+
if token in {"any", "all", "*"}:
|
|
67
|
+
return {"any"}
|
|
68
|
+
values.add(token)
|
|
69
|
+
return values or {"any"}
|
|
70
|
+
|
|
31
71
|
|
|
32
72
|
class Base(TypedDict):
|
|
33
|
-
|
|
34
|
-
|
|
73
|
+
original: str
|
|
74
|
+
self_managed: str
|
|
35
75
|
contents: Optional[bool]
|
|
36
76
|
copy: Optional[bool]
|
|
77
|
+
os: Optional[str]
|
|
37
78
|
class ConfigMapper(TypedDict):
|
|
38
79
|
file_name: str
|
|
39
80
|
config_file_default_path: str
|
|
40
81
|
self_managed_config_file_path: str
|
|
41
82
|
contents: Optional[bool]
|
|
42
83
|
copy: Optional[bool]
|
|
84
|
+
os: Optional[str]
|
|
43
85
|
class MapperFileData(TypedDict):
|
|
44
86
|
public: dict[str, list[ConfigMapper]]
|
|
45
87
|
private: dict[str, list[ConfigMapper]]
|
|
46
|
-
|
|
47
|
-
|
|
88
|
+
|
|
89
|
+
RepoLoose: TypeAlias = Literal["user", "library", "all"]
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def read_mapper(repo: RepoLoose) -> MapperFileData:
|
|
93
|
+
repo_key = _normalize_repo_name(repo)
|
|
94
|
+
match repo_key:
|
|
95
|
+
case "user":
|
|
96
|
+
mapper_path = USER_MAPPER_PATH
|
|
97
|
+
case "library":
|
|
98
|
+
mapper_path = LIBRARY_MAPPER_PATH
|
|
99
|
+
case "all":
|
|
100
|
+
# Merge both mappers
|
|
101
|
+
if not USER_MAPPER_PATH.exists():
|
|
102
|
+
user_mapper = {"public": {}, "private": {}}
|
|
103
|
+
else:
|
|
104
|
+
user_mapper = read_mapper(repo="user")
|
|
105
|
+
library_mapper = read_mapper(repo="library")
|
|
106
|
+
merged_public: dict[str, list[ConfigMapper]] = {**library_mapper["public"], **user_mapper["public"]}
|
|
107
|
+
merged_private: dict[str, list[ConfigMapper]] = {**library_mapper["private"], **user_mapper["private"]}
|
|
108
|
+
return {"public": merged_public, "private": merged_private}
|
|
109
|
+
case _:
|
|
110
|
+
raise ValueError(f"Unsupported repo value: {repo}")
|
|
111
|
+
mapper_data: dict[str, dict[str, Base]] = tomllib.loads(mapper_path.read_text(encoding="utf-8"))
|
|
48
112
|
public: dict[str, list[ConfigMapper]] = {}
|
|
49
113
|
private: dict[str, list[ConfigMapper]] = {}
|
|
50
|
-
|
|
51
|
-
# all_systems = ["linux", "windows", "darwin"]
|
|
52
|
-
# return [s for s in all_systems if s != current_system.lower()]
|
|
53
|
-
# OTHER_SYSTEMS = get_other_systems(SYSTEM)
|
|
114
|
+
normalized_system = _normalize_os_name(SYSTEM)
|
|
54
115
|
for program_key, program_map in mapper_data.items():
|
|
55
|
-
parts = program_key.split("_")
|
|
56
|
-
if len(parts) > 1:
|
|
57
|
-
if parts[-1].lower() == "windows" and SYSTEM != "windows":
|
|
58
|
-
# console.print(f"Skipping Windows-only program mapping: {program_key}")
|
|
59
|
-
continue
|
|
60
|
-
elif parts[-1].lower() == "linux" and SYSTEM == "windows":
|
|
61
|
-
# console.print(f"Skipping Linux-only program mapping: {program_key}")
|
|
62
|
-
continue
|
|
63
116
|
for file_name, file_base in program_map.items():
|
|
117
|
+
os_values = _parse_os_field(file_base.get("os"))
|
|
118
|
+
if "any" not in os_values and normalized_system not in os_values:
|
|
119
|
+
continue
|
|
64
120
|
file_map: ConfigMapper = {
|
|
65
121
|
"file_name": file_name,
|
|
66
|
-
"config_file_default_path": file_base["
|
|
67
|
-
"self_managed_config_file_path": file_base["
|
|
122
|
+
"config_file_default_path": file_base["original"],
|
|
123
|
+
"self_managed_config_file_path": file_base["self_managed"],
|
|
68
124
|
"contents": file_base.get("contents"),
|
|
69
125
|
"copy": file_base.get("copy"),
|
|
126
|
+
"os": file_base.get("os"),
|
|
70
127
|
}
|
|
71
128
|
if "CONFIG_ROOT" in file_map["self_managed_config_file_path"]:
|
|
72
129
|
if program_key not in public:
|
|
@@ -117,7 +174,7 @@ def apply_mapper(mapper_data: dict[str, list[ConfigMapper]],
|
|
|
117
174
|
# Determine whether to use copy or symlink
|
|
118
175
|
use_copy = method == "copy" or a_mapper.get("copy", False)
|
|
119
176
|
if "contents" in a_mapper and a_mapper["contents"]:
|
|
120
|
-
targets = list(self_managed_config_file_path.expanduser().
|
|
177
|
+
targets = list(self_managed_config_file_path.expanduser().glob("*"))
|
|
121
178
|
for a_target in targets:
|
|
122
179
|
operation_type = "contents_copy" if use_copy else "contents_symlink"
|
|
123
180
|
try:
|