machineconfig 3.97__py3-none-any.whl → 3.99__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.

@@ -1,7 +1,7 @@
1
1
 
2
2
 
3
3
  from pathlib import Path
4
- from typing import Optional
4
+ from typing import Optional, Annotated
5
5
  import typer
6
6
  from rich.console import Console
7
7
  from rich.panel import Panel
@@ -43,12 +43,33 @@ def display_terminal_url(local_ip_v4: str, port: int) -> None:
43
43
  )
44
44
 
45
45
  # Print with extra spacing and attention-grabbing elements
46
- console.print("\n" + "🔥" * 60 + "\n", style="bright_red bold")
46
+ # console.print("\n" + "🔥" * 60 + "\n", style="bright_red bold")
47
47
  console.print(panel)
48
- console.print("🔥" * 60 + "\n", style="bright_red bold")
49
-
50
-
51
- def main(port: Optional[int]=None, password: Optional[str]=None) -> None:
48
+ # console.print("🔥" * 60 + "\n", style="bright_red bold")
49
+
50
+
51
+ def install_ttyd():
52
+ # uv run --python 3.13 --with machineconfig devops install ttyd
53
+ from machineconfig.utils.installer_utils.installer_abc import check_tool_exists
54
+ exists = check_tool_exists("ttyd")
55
+ if exists:
56
+ print("✅ ttyd is already installed.")
57
+ return
58
+ print("⏳ ttyd not found. Installing...")
59
+ from machineconfig.scripts.python.devops_devapps_install import main
60
+ main(which="ttyd")
61
+
62
+
63
+
64
+ def main(
65
+ port: Annotated[Optional[int], typer.Option("--port", "-p", help="Port to run the terminal server on (default: 7681)")] = None,
66
+ username: Annotated[Optional[str], typer.Option("--username", "-u", help="Username for terminal access (default: current user)")] = None,
67
+ password: Annotated[Optional[str], typer.Option("--password", "-w", help="Password for terminal access (default: from ~/dotfiles/creds/passwords/quick_password)")] = None
68
+ ) -> None:
69
+ install_ttyd()
70
+ if username is None:
71
+ import getpass
72
+ username = getpass.getuser()
52
73
  if password is None:
53
74
  pwd_path = Path.home().joinpath("dotfiles/creds/passwords/quick_password")
54
75
  if pwd_path.exists():
@@ -67,11 +88,9 @@ def main(port: Optional[int]=None, password: Optional[str]=None) -> None:
67
88
 
68
89
  # Display the flashy terminal announcement
69
90
  display_terminal_url(local_ip_v4, port)
70
-
71
- code = f"""
72
- #!/bin/bash
73
- uv run --python 3.13 --with machineconfig install -ttyd
74
- ttyd --writable -t enableSixel=true --port {port} --credential "$USER:{password}" -t 'theme={"background": "black"}' bash
91
+
92
+ code = f"""#!/bin/bash
93
+ ttyd --writable -t enableSixel=true --port {port} --credential "{username}:{password}" -t 'theme={{"background": "black"}}' bash
75
94
  """
76
95
  import subprocess
77
96
  subprocess.run(code, shell=True, check=True)
File without changes
@@ -2,57 +2,8 @@
2
2
 
3
3
  echo """
4
4
  =======================================================================
5
- 📦 MACHINE CONFIGURATION | Interactive Installation Script
5
+ 📦 MACHINE CONFIGURATION | Interactive Installation Script. Installing uv then getting started.
6
6
  ======================================================================="""
7
7
 
8
8
  curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/ve.sh | bash
9
- $HOME/.local/bin/uv run --python 3.13 --with machineconfig ia
10
-
11
-
12
-
13
-
14
- echo """#=======================================================================
15
- 📂 DOTFILES MIGRATION | Configuration transfer options
16
- #=======================================================================
17
-
18
- 🖱️ Method 1: USING MOUSE WITHOUT KB OR BROWSER SHARE
19
- On original machine, run:
20
- cd ~/dotfiles/creds/msc
21
- easy-sharing . --password rew --username al
22
- Then open brave on new machine to get MouseWithoutBorders password
23
-
24
- 🔐 Method 2: USING SSH
25
- FROM REMOTE, RUN:
26
- fptx ~/dotfiles $USER@$(hostname):^ -z
27
- # OR, using IP address if router has not yet found the hostname:
28
- fptx ~/dotfiles $USER@$(hostname -I | awk '{print $1}'):^ -z
29
-
30
- ☁️ Method 3: USING INTERNET SECURE SHARE
31
- cd ~
32
- cloud_copy SHARE_URL . --config ss
33
- (requires symlinks to be created first)
34
- """
35
-
36
- echo """#=======================================================================
37
- 📂 DOTFILES STATUS | Configuration files check
38
- #=======================================================================
39
- """
40
- read -p "📂 Have you finished copying dotfiles? [y]/n? " choice
41
-
42
- echo """#=======================================================================
43
- 🔗 SYMLINK CREATION | Configuration setup
44
- #=======================================================================
45
- """
46
- read -p "🔗 Create Symlinks (finish dotfiles transfer first) [y]/n? " choice
47
- choice=${choice:-y}
48
- if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
49
- echo """ 🔧 Creating symlinks and setting permissions...
50
- """
51
- uv run --python 3.13 --with machineconfig python -m fire machineconfig.profile.create main_symlinks --choice=all
52
- sudo chmod 600 $HOME/.ssh/*
53
- sudo chmod 700 $HOME/.ssh
54
- else
55
- echo """ ⏭️ Skipping symlink creation
56
- """
57
- fi
58
-
9
+ $HOME/.local/bin/uv run --python 3.13 --with machineconfig devops ia
@@ -3,189 +3,10 @@ Write-Host "
3
3
  📦 Machine Configuration Installation Script
4
4
  ============================================="
5
5
 
6
- Write-Host "ℹ️ If you have execution policy issues, run:
7
- Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser"
8
- Write-Host "💡 To accept all prompts automatically, run: `$yesAll = `$true`n"
6
+ Write-Host "ℹ️ If you have execution policy issues, run: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser"
9
7
 
10
-
11
- Write-Host "🔄 Setting up Python environment..."
12
8
  Invoke-WebRequest -Uri "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_windows/ve.ps1" -OutFile "ve.ps1"
13
9
  .\ve.ps1
14
10
  rm ve.ps1
15
11
 
16
- Write-Host "`n🔄 Setting up repositories..."
17
- Invoke-WebRequest -Uri "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_windows/repos.ps1" -OutFile "repos.ps1"
18
- .\repos.ps1
19
- rm repos.ps1
20
-
21
- Write-Host "`n📂 ============================================
22
- 🔄 DOTFILES MIGRATION OPTIONS
23
- ============================================="
24
-
25
- Write-Host "🖱️ Method 1: USING MOUSE WITHOUT KB OR BROWSER SHARE
26
- On original machine, run:
27
- cd ~/dotfiles/creds/msc
28
- easy-sharing . --password rew
29
- Then open browser on new machine to get MouseWithoutBorders password"
30
-
31
- Write-Host "`n🔐 Method 2: USING SSH
32
- FROM REMOTE, RUN:
33
- ftpx ~/dotfiles `$(hostname):^ -z"
34
-
35
- Write-Host "`n💻 For WSL:
36
- wsl_server.ps1
37
- ftpx ~/dotfiles `$env:USERNAME@localhost:2222 -z
38
- # OR:
39
- New-Item -ItemType SymbolicLink -Path `$env:USERPROFILE\dotfiles -Target \\wsl`$\Ubuntu\home\`$env:USERNAME\dotfiles"
40
-
41
- Write-Host "`n☁️ Method 3: USING INTERNET SECURE SHARE
42
- cd ~
43
- cloud_copy SHARE_URL . --config ss
44
- (requires symlinks to be created first)"
45
-
46
- Write-Host "`n----------------------------------------"
47
- if (-not $yesAll) {
48
- $choice = Read-Host "🔒 Install SSH Server [y]/n"
49
- } else {
50
- $choice = "y"
51
- }
52
- if ([string]::IsNullOrEmpty($choice)) { $choice = "y" }
53
- if ($choice -eq "y" -or $choice -eq "Y") {
54
- Write-Host "`n🔧 Installing and configuring SSH server..."
55
- Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
56
- Start-Service sshd
57
- Set-Service -Name sshd -StartupType 'Automatic'
58
- Write-Host "✅ SSH Server installed and configured successfully!"
59
- } else {
60
- Write-Host "⏭️ Skipping SSH server installation"
61
- }
62
-
63
- Write-Host "`n✨ ===========================================
64
- 🎉 Installation Complete!
65
- ============================================="
66
-
67
- # Confirm copying finished
68
- if (-not $yesAll) {
69
- $choice = Read-Host "Did you finish copying [y]/n ? "
70
- } else {
71
- $choice = "y"
72
- }
73
- if ([string]::IsNullOrEmpty($choice)) { $choice = "y" }
74
- if ($choice -eq "y" -or $choice -eq "Y") {
75
- Write-Host "Proceeding..."
76
- } else {
77
- Write-Host "Installation aborted."
78
- }
79
-
80
- # Create Symlinks
81
- if (-not $yesAll) {
82
- $createLinksChoice = Read-Host "Create (Sym/Hard)links (finish dotfiles transfer first) [y]/n ? "
83
- } else {
84
- $createLinksChoice = "y"
85
- }
86
- if ([string]::IsNullOrEmpty($createLinksChoice)) { $createLinksChoice = "y" }
87
-
88
- if ($createLinksChoice -eq "y" -or $createLinksChoice -eq "Y") {
89
- if (-not $yesAll) {
90
- $linkTypeChoice = Read-Host "Create Symlinks (s) or Hardlinks (h) [s]/h ? "
91
- } else {
92
- $linkTypeChoice = "h"
93
- }
94
-
95
- . ~\code\machineconfig\.venv\Scripts\Activate.ps1
96
-
97
- if ($linkTypeChoice -eq "s" -or $linkTypeChoice -eq "S") {
98
- python -m fire machineconfig.profile.create main --choice=all
99
- } elseif ($linkTypeChoice -eq "h" -or $linkTypeChoice -eq "H") {
100
- # python -m fire machineconfig.profile.create_hardlinks main --choice=all
101
- python -m fire machineconfig.profile.create main --choice=all
102
- } else {
103
- Write-Host "Invalid choice for link type. Installation aborted."
104
- }
105
-
106
- # icacls "~\.ssh\*" /inheritance:r /grant:r "$($env:USERNAME):(F)"
107
- # icacls "~\.ssh" /inheritance:r /grant:r "$($env:USERNAME):(F)"
108
- } else {
109
- Write-Host "Installation aborted."
110
- }
111
-
112
- # Install CLI Apps
113
- if (-not $yesAll) {
114
- $choice = Read-Host "Install CLI Apps [y]/n ? "
115
- if ([string]::IsNullOrEmpty($choice)) { $choice = "y" }
116
- if ($choice -eq "y" -or $choice -eq "Y") {
117
- . ~\code\machineconfig\src\machineconfig\setup_windows\devapps.ps1
118
- } else {
119
- Write-Host "Installation aborted."
120
- }
121
-
122
- } else {
123
- uv run --python 3.13 --with machineconfig python -m fire machineconfig.scripts.python.devops_devapps_install main --which=essentials
124
- }
125
-
126
-
127
- # Retrieve Repos
128
- if (-not $yesAll) {
129
- $choice = Read-Host "Retrieve Repos at ~/code [y]/n ? "
130
- } else {
131
- $choice = "y"
132
- }
133
- if ([string]::IsNullOrEmpty($choice)) { $choice = "y" }
134
- if ($choice -eq "y" -or $choice -eq "Y") {
135
- repos ~\code --clone --cloud odg1
136
- } else {
137
- Write-Host "Installation aborted."
138
- }
139
-
140
- # Retrieve Data
141
- if (-not $yesAll) {
142
- $choice = Read-Host "Retrieve data [y]/n ? "
143
- } else {
144
- $choice = "y"
145
- }
146
- if ([string]::IsNullOrEmpty($choice)) { $choice = "y" }
147
- if ($choice -eq "y" -or $choice -eq "Y") {
148
- uv run --python 3.13 --with machineconfig python -m fire machineconfig.scripts.python.devops_backup_retrieve main --direction=RETRIEVE
149
- } else {
150
- Write-Host "Installation aborted."
151
- }
152
-
153
-
154
- # Install Brave, WezTerm, and VSCode
155
- if (-not $yesAll) {
156
- $choice = Read-Host "Install Brave+WindowsTerminal+WezTerm+VSCode [y]/n ? "
157
- } else {
158
- $choice = "y"
159
- }
160
- if ([string]::IsNullOrEmpty($choice)) { $choice = "y" }
161
- if ($choice -eq "y" -or $choice -eq "Y") {
162
- winget install --no-upgrade --name "Windows Terminal" --Id "Microsoft.WindowsTerminal" --source winget --scope user --accept-package-agreements --accept-source-agreements # Terminal is is installed by default on W 11
163
- winget install --no-upgrade --name "Powershell" --Id "Microsoft.PowerShell" --source winget --scope user --accept-package-agreements --accept-source-agreements # powershell require admin
164
- winget install --no-upgrade --name "Brave" --Id "Brave.Brave" --source winget --scope user --accept-package-agreements --accept-source-agreements
165
- winget install --no-upgrade --name "Microsoft Visual Studio Code" --Id "Microsoft.VisualStudioCode" --source winget --scope user --accept-package-agreements --accept-source-agreements
166
- uv run --python 3.13 --with machineconfig python -m fire machineconfig.setup_windows.wt_and_pwsh.install_nerd_fonts main
167
- uv run --python 3.13 --with machineconfig python -m fire machineconfig.setup_windows.wt_and_pwsh.set_wt_settings main
168
- } else {
169
- Write-Host "Installation aborted."
170
- }
171
-
172
-
173
- # Install Apps
174
- if (-not $yesAll) {
175
- $choice = Read-Host "Install Windows Apps [y]/n ? "
176
- } else {
177
- $choice = "y"
178
- }
179
- if ($choice -eq "y" -or $choice -eq "Y") {
180
- Invoke-WebRequest -Uri "https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_windows/apps.ps1" -OutFile "apps.ps1"
181
- .\apps.ps1
182
- } else {
183
- Write-Host "Installation aborted."
184
- }
185
-
186
- # Instructions for Thunderbird profile restoration
187
- # Run this after installing Thunderbird and starting it and shutting it down but before downloading backup
188
- # cd ~/AppData/Roaming/ThunderBird/Profiles
189
- # $res = Get-ChildItem
190
- # $name = $res[0].Name
191
- # Move-Item $backup_folder $name
12
+ uv run --python 3.13 --with machineconfig devops ia
@@ -1,13 +1,13 @@
1
1
  """package manager"""
2
2
 
3
- from machineconfig.utils.installer_utils.installer_abc import LINUX_INSTALL_PATH
3
+ from machineconfig.utils.installer_utils.installer_abc import check_if_installed_already
4
4
  from machineconfig.utils.installer_utils.installer_class import Installer
5
5
  from machineconfig.utils.schemas.installer.installer_types import APP_INSTALLER_CATEGORY, InstallerData, InstallerDataFiles, get_normalized_arch, get_os_name, OPERATING_SYSTEMS, CPU_ARCHITECTURES
6
6
  from rich.console import Console
7
- from rich.panel import Panel # Added import
7
+ from rich.panel import Panel
8
8
 
9
9
  from machineconfig.utils.path_extended import PathExtended as PathExtended
10
- from machineconfig.utils.source_of_truth import INSTALL_VERSION_ROOT
10
+ from machineconfig.utils.source_of_truth import INSTALL_VERSION_ROOT, LINUX_INSTALL_PATH
11
11
  from machineconfig.utils.io import read_json
12
12
 
13
13
  from typing import Any
@@ -38,7 +38,7 @@ def check_latest():
38
38
  repo_url = inst.installer_data.get("repoURL", "")
39
39
  print(f"🔎 Checking {exe_name}...")
40
40
  _release_url, version_to_be_installed = inst.get_github_release(repo_url=repo_url, version=None)
41
- verdict, current_ver, new_ver = inst.check_if_installed_already(exe_name=exe_name, version=version_to_be_installed, use_cache=False)
41
+ verdict, current_ver, new_ver = check_if_installed_already(exe_name=exe_name, version=version_to_be_installed, use_cache=False)
42
42
  return exe_name, verdict, current_ver, new_ver
43
43
 
44
44
  print("\n⏳ Processing installers...\n")
@@ -188,5 +188,4 @@ def install_all(installers: list[Installer], safe: bool = False, jobs: int = 10,
188
188
  print("\n" * 2)
189
189
 
190
190
 
191
- if __name__ == "__main__":
192
- pass
191
+
@@ -1,7 +1,11 @@
1
+
1
2
  from machineconfig.utils.path_extended import PathExtended as PathExtended
2
- from machineconfig.utils.source_of_truth import WINDOWS_INSTALL_PATH, LINUX_INSTALL_PATH
3
- from typing import Optional
3
+ from machineconfig.utils.source_of_truth import WINDOWS_INSTALL_PATH, LINUX_INSTALL_PATH, INSTALL_VERSION_ROOT
4
+
5
+ from pathlib import Path
6
+ from typing import Any, Optional
4
7
  import subprocess
8
+ import platform
5
9
 
6
10
 
7
11
  def find_move_delete_windows(downloaded_file_path: PathExtended, exe_name: Optional[str] = None, delete: bool = True, rename_to: Optional[str] = None):
@@ -106,3 +110,131 @@ def find_move_delete_linux(downloaded: PathExtended, tool_name: str, delete: Opt
106
110
  exe_new_location = PathExtended(LINUX_INSTALL_PATH).joinpath(exe.name)
107
111
  print(f"✅ Executable installed at: {exe_new_location}\n{'=' * 80}")
108
112
  return exe_new_location
113
+
114
+
115
+ def check_tool_exists(tool_name: str) -> bool:
116
+ if platform.system() == "Windows":
117
+ tool_name = tool_name.replace(".exe", "") + ".exe"
118
+ res1 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name).is_file()])
119
+ tool_name = tool_name.replace(".exe", "") + ".exe"
120
+ res2 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name).is_file()])
121
+ return res1 or res2
122
+ elif platform.system() in ["Linux", "Darwin"]:
123
+ root_path = Path(LINUX_INSTALL_PATH)
124
+ return any([Path("/usr/local/bin").joinpath(tool_name).is_file(), Path("/usr/bin").joinpath(tool_name).is_file(), root_path.joinpath(tool_name).is_file()])
125
+ else:
126
+ raise NotImplementedError(f"platform {platform.system()} not implemented")
127
+
128
+
129
+ def check_if_installed_already(exe_name: str, version: Optional[str], use_cache: bool) -> tuple[str, str, str]:
130
+ print(f"\n{'=' * 80}\n🔍 CHECKING INSTALLATION STATUS: {exe_name} 🔍\n{'=' * 80}")
131
+ INSTALL_VERSION_ROOT.joinpath(exe_name).parent.mkdir(parents=True, exist_ok=True)
132
+ tmp_path = INSTALL_VERSION_ROOT.joinpath(exe_name)
133
+
134
+ if use_cache:
135
+ print("🗂️ Using cached version information...")
136
+ if tmp_path.exists():
137
+ existing_version = tmp_path.read_text(encoding="utf-8").rstrip()
138
+ print(f"📄 Found cached version: {existing_version}")
139
+ else:
140
+ existing_version = None
141
+ print("ℹ️ No cached version information found")
142
+ else:
143
+ print("🔍 Checking installed version directly...")
144
+ result = subprocess.run([exe_name, "--version"], check=False, capture_output=True, text=True)
145
+ if result.stdout.strip() == "":
146
+ existing_version = None
147
+ print("ℹ️ Could not detect installed version")
148
+ else:
149
+ existing_version = result.stdout.strip()
150
+ print(f"📄 Detected installed version: {existing_version}")
151
+
152
+ if existing_version is not None and version is not None:
153
+ if existing_version == version:
154
+ print(f"✅ {exe_name} is up to date (version {version})")
155
+ print(f"📂 Version information stored at: {INSTALL_VERSION_ROOT}")
156
+ return ("✅ Up to date", version.strip(), version.strip())
157
+ else:
158
+ print(f"🔄 {exe_name} needs update: {existing_version.rstrip()} → {version}")
159
+ tmp_path.write_text(version, encoding="utf-8")
160
+ return ("❌ Outdated", existing_version.strip(), version.strip())
161
+ else:
162
+ print(f"📦 {exe_name} is not installed. Will install version: {version}")
163
+ # tmp_path.write_text(version, encoding="utf-8")
164
+
165
+ print(f"{'=' * 80}")
166
+ return ("⚠️ NotInstalled", "None", version or "unknown")
167
+
168
+
169
+ def parse_apps_installer_linux(txt: str) -> dict[str, Any]:
170
+ """Parse Linux shell installation scripts into logical chunks.
171
+
172
+ Supports two formats:
173
+ 1. Legacy format with 'yes '' | sed 3q; echo "----------------------------- installing' delimiter
174
+ 2. New format with # --BLOCK:<name>-- comment signatures
175
+
176
+ Returns:
177
+ dict[str, str]: Dictionary mapping block/section names to their installation scripts
178
+ """
179
+ # Try new block format first
180
+ if "# --BLOCK:" in txt:
181
+ import re
182
+ # Split by block signatures: # --BLOCK:<name>--
183
+ blocks = re.split(r'# --BLOCK:([^-]+)--', txt)
184
+ res: dict[str, str] = {}
185
+
186
+ # Process blocks in pairs (block_name, block_content)
187
+ for i in range(1, len(blocks), 2):
188
+ if i + 1 < len(blocks):
189
+ block_name = blocks[i].strip()
190
+ block_content = blocks[i + 1].strip()
191
+ if block_content:
192
+ res[block_name] = block_content
193
+
194
+ return res
195
+
196
+ # Legacy format fallback
197
+ txts = txt.split("""yes '' | sed 3q; echo "----------------------------- installing """)
198
+ res = {}
199
+ for chunk in txts[1:]:
200
+ try:
201
+ k = chunk.split("----")[0].rstrip().lstrip()
202
+ v = "\n".join(chunk.split("\n")[1:])
203
+ res[k] = v
204
+ except IndexError as e:
205
+ print(f"""
206
+ ❌ Error parsing chunk:
207
+ {"-" * 50}
208
+ {chunk}
209
+ {"-" * 50}""")
210
+ raise e
211
+ return res
212
+
213
+
214
+ def parse_apps_installer_windows(txt: str) -> dict[str, Any]:
215
+ chunks: list[str] = []
216
+ for idx, item in enumerate(txt.split(sep="winget install")):
217
+ if idx == 0:
218
+ continue
219
+ if idx == 1:
220
+ chunks.append(item)
221
+ else:
222
+ chunks.append("winget install" + item)
223
+ # progs = L(txt.splitlines()).filter(lambda x: x.startswith("winget ") or x.startswith("#winget"))
224
+ res: dict[str, str] = {}
225
+ for a_chunk in chunks:
226
+ try:
227
+ name = a_chunk.split("--name ")[1]
228
+ if "--Id" not in name:
229
+ print(f"⚠️ Warning: {name} does not have an Id, skipping")
230
+ continue
231
+ name = name.split(" --Id ", maxsplit=1)[0].strip('"').strip('"')
232
+ res[name] = a_chunk
233
+ except IndexError as e:
234
+ print(f"""
235
+ ❌ Error parsing chunk:
236
+ {"-" * 50}
237
+ {a_chunk}
238
+ {"-" * 50}""")
239
+ raise e
240
+ return res
@@ -1,7 +1,7 @@
1
1
  from machineconfig.utils.path_extended import PathExtended as PathExtended
2
2
  from machineconfig.utils.installer_utils.installer_abc import find_move_delete_linux, find_move_delete_windows
3
3
  from machineconfig.utils.source_of_truth import INSTALL_TMP_DIR, INSTALL_VERSION_ROOT, LIBRARY_ROOT
4
- from machineconfig.utils.options import check_tool_exists
4
+ from machineconfig.utils.installer_utils.installer_abc import check_tool_exists
5
5
  from machineconfig.utils.io import read_json
6
6
  from machineconfig.utils.schemas.installer.installer_types import InstallerData, InstallerDataFiles, get_os_name, get_normalized_arch
7
7
 
@@ -356,43 +356,3 @@ class Installer:
356
356
  return None, None
357
357
  browser_download_url = f"{repo_url}/releases/download/{actual_version}/{filename}"
358
358
  return browser_download_url, actual_version
359
-
360
- @staticmethod
361
- def check_if_installed_already(exe_name: str, version: Optional[str], use_cache: bool) -> tuple[str, str, str]:
362
- print(f"\n{'=' * 80}\n🔍 CHECKING INSTALLATION STATUS: {exe_name} 🔍\n{'=' * 80}")
363
- INSTALL_VERSION_ROOT.joinpath(exe_name).parent.mkdir(parents=True, exist_ok=True)
364
- tmp_path = INSTALL_VERSION_ROOT.joinpath(exe_name)
365
-
366
- if use_cache:
367
- print("🗂️ Using cached version information...")
368
- if tmp_path.exists():
369
- existing_version = tmp_path.read_text(encoding="utf-8").rstrip()
370
- print(f"📄 Found cached version: {existing_version}")
371
- else:
372
- existing_version = None
373
- print("ℹ️ No cached version information found")
374
- else:
375
- print("🔍 Checking installed version directly...")
376
- result = subprocess.run([exe_name, "--version"], check=False, capture_output=True, text=True)
377
- if result.stdout.strip() == "":
378
- existing_version = None
379
- print("ℹ️ Could not detect installed version")
380
- else:
381
- existing_version = result.stdout.strip()
382
- print(f"📄 Detected installed version: {existing_version}")
383
-
384
- if existing_version is not None and version is not None:
385
- if existing_version == version:
386
- print(f"✅ {exe_name} is up to date (version {version})")
387
- print(f"📂 Version information stored at: {INSTALL_VERSION_ROOT}")
388
- return ("✅ Up to date", version.strip(), version.strip())
389
- else:
390
- print(f"🔄 {exe_name} needs update: {existing_version.rstrip()} → {version}")
391
- tmp_path.write_text(version, encoding="utf-8")
392
- return ("❌ Outdated", existing_version.strip(), version.strip())
393
- else:
394
- print(f"📦 {exe_name} is not installed. Will install version: {version}")
395
- # tmp_path.write_text(version, encoding="utf-8")
396
-
397
- print(f"{'=' * 80}")
398
- return ("⚠️ NotInstalled", "None", version or "unknown")
@@ -1,25 +1,12 @@
1
1
  from pathlib import Path
2
+ from machineconfig.utils.installer_utils.installer_abc import check_tool_exists
2
3
  from rich.text import Text
3
4
  from rich.panel import Panel
4
5
  from rich.console import Console
5
- import platform
6
6
  import subprocess
7
7
  from typing import Optional, Union, Iterable, overload, Literal
8
- from machineconfig.utils.source_of_truth import WINDOWS_INSTALL_PATH, LINUX_INSTALL_PATH
9
-
10
-
11
- def check_tool_exists(tool_name: str) -> bool:
12
- if platform.system() == "Windows":
13
- tool_name = tool_name.replace(".exe", "") + ".exe"
14
- res1 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name).is_file()])
15
- tool_name = tool_name.replace(".exe", "") + ".exe"
16
- res2 = any([Path(WINDOWS_INSTALL_PATH).joinpath(tool_name).is_file(), Path.home().joinpath("AppData/Roaming/npm").joinpath(tool_name).is_file()])
17
- return res1 or res2
18
- elif platform.system() in ["Linux", "Darwin"]:
19
- root_path = Path(LINUX_INSTALL_PATH)
20
- return any([Path("/usr/local/bin").joinpath(tool_name).is_file(), Path("/usr/bin").joinpath(tool_name).is_file(), root_path.joinpath(tool_name).is_file()])
21
- else:
22
- raise NotImplementedError(f"platform {platform.system()} not implemented")
8
+
9
+
23
10
  # _ = cmd
24
11
  # cmd = "where.exe"
25
12
  # cmd = "which"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machineconfig
3
- Version: 3.97
3
+ Version: 3.99
4
4
  Summary: Dotfiles management package
5
5
  Author-email: Alex Al-Saffar <programmer@usa.com>
6
6
  License: Apache 2.0