machineconfig 3.93__py3-none-any.whl → 3.95__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/jobs/{python_custom_installers → installer/custom}/gh.py +22 -7
- machineconfig/jobs/{python_custom_installers → installer/custom}/hx.py +13 -4
- machineconfig/jobs/{python_custom_installers/dev → installer/custom_dev}/alacritty.py +11 -5
- machineconfig/jobs/{python_custom_installers/dev → installer/custom_dev}/brave.py +17 -14
- machineconfig/jobs/{python_custom_installers/dev → installer/custom_dev}/bypass_paywall.py +7 -9
- machineconfig/jobs/{python_custom_installers/dev → installer/custom_dev}/code.py +13 -13
- machineconfig/jobs/{python_custom_installers/dev → installer/custom_dev}/cursor.py +7 -7
- machineconfig/jobs/{python_custom_installers/dev → installer/custom_dev}/espanso.py +21 -17
- machineconfig/jobs/installer/custom_dev/goes.py +63 -0
- machineconfig/jobs/{python_custom_installers/dev → installer/custom_dev}/lvim.py +10 -14
- machineconfig/jobs/installer/custom_dev/nerdfont.py +87 -0
- machineconfig/{setup_windows/wt_and_pwsh/install_nerd_fonts.py → jobs/installer/custom_dev/nerfont_windows_helper.py} +68 -25
- machineconfig/jobs/{python_custom_installers/dev → installer/custom_dev}/redis.py +13 -8
- machineconfig/jobs/{python_custom_installers/dev → installer/custom_dev}/wezterm.py +13 -7
- machineconfig/jobs/{python_custom_installers/dev → installer/custom_dev}/winget.py +1 -3
- machineconfig/jobs/installer/packages_custom_dev.json +226 -0
- machineconfig/jobs/installer/packages_custom_essential.json +39 -0
- machineconfig/jobs/installer/packages_github_dev.json +1110 -0
- machineconfig/jobs/installer/packages_github_essential.json +804 -0
- machineconfig/jobs/linux/msc/cli_agents.sh +5 -0
- machineconfig/profile/create.py +5 -1
- machineconfig/scripts/linux/devops +1 -1
- machineconfig/scripts/python/ai/solutions/gemini/settings.json +1 -1
- machineconfig/scripts/python/devops.py +126 -65
- machineconfig/scripts/python/devops_devapps_install.py +30 -19
- machineconfig/setup_linux/web_shortcuts/interactive.py +267 -0
- machineconfig/setup_linux/web_shortcuts/interactive.sh +6 -152
- machineconfig/utils/installer.py +17 -80
- machineconfig/utils/installer_utils/github_release_bulk.py +198 -0
- machineconfig/utils/installer_utils/installer_class.py +223 -210
- machineconfig/utils/schemas/installer/installer_types.py +29 -6
- {machineconfig-3.93.dist-info → machineconfig-3.95.dist-info}/METADATA +2 -1
- {machineconfig-3.93.dist-info → machineconfig-3.95.dist-info}/RECORD +50 -71
- machineconfig/jobs/python_custom_installers/archive/ngrok.py +0 -63
- machineconfig/jobs/python_custom_installers/dev/aider.py +0 -37
- machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +0 -78
- machineconfig/jobs/python_custom_installers/dev/goes.py +0 -55
- machineconfig/jobs/python_custom_installers/dev/nerdfont.py +0 -68
- machineconfig/jobs/python_custom_installers/dev/reverse_proxy.md +0 -31
- machineconfig/jobs/python_custom_installers/docker.py +0 -74
- machineconfig/jobs/python_custom_installers/warp-cli.py +0 -71
- machineconfig/jobs/python_generic_installers/config.json +0 -603
- machineconfig/jobs/python_generic_installers/config.json.bak +0 -414
- machineconfig/jobs/python_generic_installers/dev/config.archive.json +0 -18
- machineconfig/jobs/python_generic_installers/dev/config.json +0 -825
- machineconfig/jobs/python_generic_installers/dev/config.json.bak +0 -565
- machineconfig/jobs/python_linux_installers/__init__.py +0 -0
- machineconfig/jobs/python_linux_installers/archive/config.json +0 -18
- machineconfig/jobs/python_linux_installers/archive/config.json.bak +0 -10
- machineconfig/jobs/python_linux_installers/config.json +0 -145
- machineconfig/jobs/python_linux_installers/config.json.bak +0 -110
- machineconfig/jobs/python_linux_installers/dev/__init__.py +0 -0
- machineconfig/jobs/python_linux_installers/dev/config.json +0 -276
- machineconfig/jobs/python_linux_installers/dev/config.json.bak +0 -206
- machineconfig/jobs/python_windows_installers/__init__.py +0 -0
- machineconfig/jobs/python_windows_installers/archive/__init__.py +0 -0
- machineconfig/jobs/python_windows_installers/archive/file.json +0 -11
- machineconfig/jobs/python_windows_installers/config.json +0 -82
- machineconfig/jobs/python_windows_installers/config.json.bak +0 -56
- machineconfig/jobs/python_windows_installers/dev/__init__.py +0 -0
- machineconfig/jobs/python_windows_installers/dev/config.json +0 -4
- machineconfig/jobs/python_windows_installers/dev/config.json.bak +0 -3
- /machineconfig/jobs/{python_custom_installers → installer}/__init__.py +0 -0
- /machineconfig/jobs/{python_generic_installers → installer/custom_dev}/__init__.py +0 -0
- /machineconfig/jobs/{python_custom_installers/scripts/linux → installer/linux_scripts}/brave.sh +0 -0
- /machineconfig/jobs/{python_custom_installers/scripts/linux → installer/linux_scripts}/docker.sh +0 -0
- /machineconfig/jobs/{python_custom_installers/scripts/linux → installer/linux_scripts}/docker_start.sh +0 -0
- /machineconfig/jobs/{python_custom_installers/scripts/linux → installer/linux_scripts}/edge.sh +0 -0
- /machineconfig/jobs/{python_custom_installers/scripts/linux → installer/linux_scripts}/nerdfont.sh +0 -0
- /machineconfig/jobs/{python_custom_installers/scripts/linux → installer/linux_scripts}/pgsql.sh +0 -0
- /machineconfig/jobs/{python_custom_installers/scripts/linux → installer/linux_scripts}/redis.sh +0 -0
- /machineconfig/jobs/{python_custom_installers/scripts/linux → installer/linux_scripts}/timescaledb.sh +0 -0
- /machineconfig/jobs/{python_custom_installers/scripts/linux → installer/linux_scripts}/vscode.sh +0 -0
- /machineconfig/jobs/{python_custom_installers/scripts/linux → installer/linux_scripts}/warp-cli.sh +0 -0
- /machineconfig/jobs/{python_custom_installers/scripts/linux → installer/linux_scripts}/wezterm.sh +0 -0
- /machineconfig/{setup_windows/wt_and_pwsh → jobs/installer/powershell_scripts}/install_fonts.ps1 +0 -0
- {machineconfig-3.93.dist-info → machineconfig-3.95.dist-info}/WHEEL +0 -0
- {machineconfig-3.93.dist-info → machineconfig-3.95.dist-info}/entry_points.txt +0 -0
- {machineconfig-3.93.dist-info → machineconfig-3.95.dist-info}/top_level.txt +0 -0
|
@@ -1,68 +1,15 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
-
echo """
|
|
3
|
+
echo """
|
|
4
|
+
=======================================================================
|
|
4
5
|
📦 MACHINE CONFIGURATION | Interactive Installation Script
|
|
5
|
-
|
|
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
|
|
9
10
|
|
|
10
|
-
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
|
|
11
|
-
echo """ #=======================================================================
|
|
12
|
-
📦 APPLICATIONS | Installing base system applications
|
|
13
|
-
#=======================================================================
|
|
14
|
-
"""
|
|
15
|
-
curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/apps.sh | bash
|
|
16
|
-
else
|
|
17
|
-
echo """ ⏭️ Skipping applications installation
|
|
18
|
-
"""
|
|
19
|
-
fi
|
|
20
11
|
|
|
21
|
-
echo """#=======================================================================
|
|
22
|
-
🔄 SYSTEM UPDATE | Package management
|
|
23
|
-
#=======================================================================
|
|
24
|
-
"""
|
|
25
|
-
read -p "🔄 Upgrade system packages [y]/n? " choice
|
|
26
12
|
|
|
27
|
-
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
|
|
28
|
-
echo """ 📦 Upgrading system packages...
|
|
29
|
-
"""
|
|
30
|
-
sudo nala upgrade -y
|
|
31
|
-
else
|
|
32
|
-
echo """ ⏭️ Skipping system upgrade
|
|
33
|
-
"""
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
echo """#=======================================================================
|
|
37
|
-
🐍 PYTHON ENVIRONMENT | Virtual environment setup
|
|
38
|
-
#=======================================================================
|
|
39
|
-
"""
|
|
40
|
-
read -p "🐍 Install UV and repos [y]/n? " choice
|
|
41
|
-
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
|
|
42
|
-
echo """ 🔧 Setting up Python environment...
|
|
43
|
-
"""
|
|
44
|
-
curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/ve.sh | bash
|
|
45
|
-
curl https://raw.githubusercontent.com/thisismygitrepo/machineconfig/main/src/machineconfig/setup_linux/repos.sh | bash
|
|
46
|
-
else
|
|
47
|
-
echo """ ⏭️ Skipping virtual environment setup
|
|
48
|
-
"""
|
|
49
|
-
fi
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
echo """#=======================================================================
|
|
53
|
-
🔒 SSH SERVER | Remote access setup
|
|
54
|
-
#=======================================================================
|
|
55
|
-
"""
|
|
56
|
-
read -p "🔒 Install SSH Server [y]/n? " choice
|
|
57
|
-
choice=${choice:-y}
|
|
58
|
-
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
|
|
59
|
-
echo """ 🔧 Installing SSH server...
|
|
60
|
-
"""
|
|
61
|
-
sudo nala install openssh-server -y
|
|
62
|
-
else
|
|
63
|
-
echo """ ⏭️ Skipping SSH server installation
|
|
64
|
-
"""
|
|
65
|
-
fi
|
|
66
13
|
|
|
67
14
|
echo """#=======================================================================
|
|
68
15
|
📂 DOTFILES MIGRATION | Configuration transfer options
|
|
@@ -101,7 +48,7 @@ choice=${choice:-y}
|
|
|
101
48
|
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
|
|
102
49
|
echo """ 🔧 Creating symlinks and setting permissions...
|
|
103
50
|
"""
|
|
104
|
-
uv run --python 3.13 --with machineconfig python -m fire machineconfig.profile.create
|
|
51
|
+
uv run --python 3.13 --with machineconfig python -m fire machineconfig.profile.create main_symlinks --choice=all
|
|
105
52
|
sudo chmod 600 $HOME/.ssh/*
|
|
106
53
|
sudo chmod 700 $HOME/.ssh
|
|
107
54
|
else
|
|
@@ -109,96 +56,3 @@ else
|
|
|
109
56
|
"""
|
|
110
57
|
fi
|
|
111
58
|
|
|
112
|
-
echo """#=======================================================================
|
|
113
|
-
⚡ CLI APPLICATIONS | Command-line tools installation
|
|
114
|
-
#=======================================================================
|
|
115
|
-
"""
|
|
116
|
-
read -p "⚡ Install CLI Apps [y]/n? " choice
|
|
117
|
-
choice=${choice:-y}
|
|
118
|
-
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
|
|
119
|
-
echo """ 🔧 Installing CLI applications...
|
|
120
|
-
"""
|
|
121
|
-
uv run --python 3.13 --with machineconfig python -m fire machineconfig.scripts.python.devops_devapps_install main --which=essentials
|
|
122
|
-
. $HOME/.bashrc
|
|
123
|
-
else
|
|
124
|
-
echo """ ⏭️ Skipping CLI apps installation
|
|
125
|
-
"""
|
|
126
|
-
fi
|
|
127
|
-
|
|
128
|
-
echo """#=======================================================================
|
|
129
|
-
🛠️ DEVELOPMENT TOOLS | Software development packages
|
|
130
|
-
#=======================================================================
|
|
131
|
-
"""
|
|
132
|
-
read -p "🛠️ Install Development Tools (rust, libssql-dev, ffmpeg, wezterm, brave, code) [y]/n? " choice
|
|
133
|
-
choice=${choice:-y}
|
|
134
|
-
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
|
|
135
|
-
echo """ 🔧 Installing development tools... """
|
|
136
|
-
(curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh) || true
|
|
137
|
-
sudo nala install libssl-dev -y
|
|
138
|
-
sudo nala install ffmpeg -y
|
|
139
|
-
uv run --python 3.13 --with machineconfig python -m fire machineconfig.scripts.python.devops_devapps_install main --which=wezterm,brave,code
|
|
140
|
-
else
|
|
141
|
-
echo """ ⏭️ Skipping development tools installation
|
|
142
|
-
"""
|
|
143
|
-
fi
|
|
144
|
-
|
|
145
|
-
echo """#=======================================================================
|
|
146
|
-
📚 REPOSITORIES | Project code retrieval
|
|
147
|
-
#=======================================================================
|
|
148
|
-
"""
|
|
149
|
-
read -p "📚 Retrieve Repositories to ~/code [y]/n? " choice
|
|
150
|
-
choice=${choice:-y}
|
|
151
|
-
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
|
|
152
|
-
echo """ 🔄 Cloning repositories...
|
|
153
|
-
"""
|
|
154
|
-
repos ~/code --clone --cloud odg1
|
|
155
|
-
else
|
|
156
|
-
echo """ ⏭️ Skipping repository retrieval
|
|
157
|
-
"""
|
|
158
|
-
fi
|
|
159
|
-
|
|
160
|
-
echo """#=======================================================================
|
|
161
|
-
💾 DATA RETRIEVAL | Backup restoration
|
|
162
|
-
#=======================================================================
|
|
163
|
-
"""
|
|
164
|
-
read -p "💾 Retrieve Data [y]/n? " choice
|
|
165
|
-
choice=${choice:-y}
|
|
166
|
-
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
|
|
167
|
-
echo """ 🔄 Retrieving data...
|
|
168
|
-
"""
|
|
169
|
-
uv run --python 3.13 --with machineconfig python -m fire machineconfig.scripts.python.devops_backup_retrieve main --direction=RETRIEVE
|
|
170
|
-
else
|
|
171
|
-
echo """ ⏭️ Skipping data retrieval
|
|
172
|
-
"""
|
|
173
|
-
fi
|
|
174
|
-
|
|
175
|
-
echo """#=======================================================================
|
|
176
|
-
🎨 ASCII ART | Terminal visualization tools
|
|
177
|
-
#=======================================================================
|
|
178
|
-
"""
|
|
179
|
-
read -p "🎨 Install ASCII Art Libraries [y]/n? " choice
|
|
180
|
-
choice=${choice:-y}
|
|
181
|
-
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
|
|
182
|
-
echo """ 🎨 Installing ASCII art libraries...
|
|
183
|
-
"""
|
|
184
|
-
curl bit.ly/cfgasciiartlinux -L | sudo bash
|
|
185
|
-
else
|
|
186
|
-
echo """ ⏭️ Skipping ASCII art installation
|
|
187
|
-
"""
|
|
188
|
-
fi
|
|
189
|
-
|
|
190
|
-
# echo """# 📧 Thunderbird Setup Note:
|
|
191
|
-
# Run after installing Thunderbird and starting it once:
|
|
192
|
-
# cd ~/AppData/Roaming/ThunderBird/Profiles
|
|
193
|
-
# \$res = ls
|
|
194
|
-
# \$name = \$res[0].Name
|
|
195
|
-
# mv \$backup_folder \$name
|
|
196
|
-
# """
|
|
197
|
-
|
|
198
|
-
echo """#=======================================================================
|
|
199
|
-
✨ INSTALLATION COMPLETE | System setup finished successfully
|
|
200
|
-
#=======================================================================
|
|
201
|
-
|
|
202
|
-
🎉 Your system has been configured successfully!
|
|
203
|
-
🔄 You may need to reboot to apply all changes.
|
|
204
|
-
"""
|
machineconfig/utils/installer.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from machineconfig.utils.installer_utils.installer_abc import LINUX_INSTALL_PATH
|
|
4
4
|
from machineconfig.utils.installer_utils.installer_class import Installer
|
|
5
|
-
from machineconfig.utils.schemas.installer.installer_types import APP_INSTALLER_CATEGORY, InstallerData, InstallerDataFiles
|
|
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
7
|
from rich.panel import Panel # Added import
|
|
8
8
|
|
|
@@ -18,8 +18,7 @@ from joblib import Parallel, delayed
|
|
|
18
18
|
def check_latest():
|
|
19
19
|
console = Console() # Added console initialization
|
|
20
20
|
console.print(Panel("🔍 CHECKING FOR LATEST VERSIONS", title="Status", expand=False)) # Replaced print with Panel
|
|
21
|
-
installers = get_installers(
|
|
22
|
-
# installers += get_installers(system=platform.system(), dev=True)
|
|
21
|
+
installers = get_installers(os=get_os_name(), arch=get_normalized_arch(), which_cats=["GITHUB_ESSENTIAL", "CUSTOM_ESSENTIAL"])
|
|
23
22
|
installers_github = []
|
|
24
23
|
for inst__ in installers:
|
|
25
24
|
app_name = inst__.installer_data.get("appName", "unknown")
|
|
@@ -92,92 +91,30 @@ def get_installed_cli_apps():
|
|
|
92
91
|
return apps
|
|
93
92
|
|
|
94
93
|
|
|
95
|
-
def get_installers(
|
|
94
|
+
def get_installers(os: OPERATING_SYSTEMS, arch: CPU_ARCHITECTURES, which_cats: list[APP_INSTALLER_CATEGORY]) -> list[Installer]:
|
|
96
95
|
print(f"\n{'=' * 80}\n🔍 LOADING INSTALLER CONFIGURATIONS 🔍\n{'=' * 80}")
|
|
97
|
-
res_all = get_all_installer_data_files(
|
|
98
|
-
if not dev:
|
|
99
|
-
print("ℹ️ Excluding development installers...")
|
|
100
|
-
del res_all["CUSTOM_DEV"]
|
|
101
|
-
del res_all["OS_SPECIFIC_DEV"]
|
|
102
|
-
del res_all["OS_GENERIC_DEV"]
|
|
103
|
-
|
|
104
|
-
# Flatten the installer data from all categories
|
|
96
|
+
res_all = get_all_installer_data_files(which_cats=which_cats)
|
|
105
97
|
all_installers: list[InstallerData] = []
|
|
106
98
|
for _category, installer_data_files in res_all.items():
|
|
107
|
-
|
|
108
|
-
|
|
99
|
+
suitable_installers = []
|
|
100
|
+
for an_installer in installer_data_files["installers"]:
|
|
101
|
+
if an_installer["fileNamePattern"][arch][os] is None:
|
|
102
|
+
continue
|
|
103
|
+
suitable_installers.append(an_installer)
|
|
104
|
+
all_installers.extend(suitable_installers)
|
|
109
105
|
print(f"✅ Loaded {len(all_installers)} installer configurations\n{'=' * 80}")
|
|
110
106
|
return [Installer(installer_data=installer_data) for installer_data in all_installers]
|
|
111
107
|
|
|
112
108
|
|
|
113
|
-
def get_all_installer_data_files(
|
|
109
|
+
def get_all_installer_data_files(which_cats: list[APP_INSTALLER_CATEGORY]) -> dict[APP_INSTALLER_CATEGORY, InstallerDataFiles]:
|
|
114
110
|
print(f"\n{'=' * 80}\n📂 LOADING CONFIGURATION FILES 📂\n{'=' * 80}")
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if system == "Windows":
|
|
118
|
-
import machineconfig.jobs.python_windows_installers as os_specific_installer
|
|
119
|
-
else:
|
|
120
|
-
import machineconfig.jobs.python_linux_installers as os_specific_installer
|
|
121
|
-
|
|
122
|
-
print("🔍 Importing generic installers...")
|
|
123
|
-
import machineconfig.jobs.python_generic_installers as generic_installer
|
|
124
|
-
|
|
125
|
-
path_os_specific = PathExtended(os_specific_installer.__file__).parent
|
|
126
|
-
path_os_generic = PathExtended(generic_installer.__file__).parent
|
|
127
|
-
|
|
128
|
-
path_os_specific_dev = path_os_specific.joinpath("dev")
|
|
129
|
-
path_os_generic_dev = path_os_generic.joinpath("dev")
|
|
130
|
-
|
|
111
|
+
import machineconfig.jobs.installer as module
|
|
112
|
+
from pathlib import Path
|
|
131
113
|
print("📂 Loading configuration files...")
|
|
132
|
-
res_final: dict[APP_INSTALLER_CATEGORY, InstallerDataFiles] = {}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
res_final["OS_SPECIFIC"] = InstallerDataFiles(os_specific_data)
|
|
137
|
-
|
|
138
|
-
print(f"""📄 Loading OS-generic config from: {path_os_generic.joinpath("config.json")}""")
|
|
139
|
-
os_generic_data = read_json(path=path_os_generic.joinpath("config.json"))
|
|
140
|
-
res_final["OS_GENERIC"] = InstallerDataFiles(os_generic_data)
|
|
141
|
-
|
|
142
|
-
print(f"""📄 Loading OS-specific dev config from: {path_os_specific_dev.joinpath("config.json")}""")
|
|
143
|
-
os_specific_dev_data = read_json(path=path_os_specific_dev.joinpath("config.json"))
|
|
144
|
-
res_final["OS_SPECIFIC_DEV"] = InstallerDataFiles(os_specific_dev_data)
|
|
145
|
-
|
|
146
|
-
print(f"""📄 Loading OS-generic dev config from: {path_os_generic_dev.joinpath("config.json")}""")
|
|
147
|
-
os_generic_dev_data = read_json(path=path_os_generic_dev.joinpath("config.json"))
|
|
148
|
-
res_final["OS_GENERIC_DEV"] = InstallerDataFiles(os_generic_dev_data)
|
|
149
|
-
|
|
150
|
-
path_custom_installer = path_os_generic.with_name("python_custom_installers")
|
|
151
|
-
path_custom_installer_dev = path_custom_installer.joinpath("dev")
|
|
152
|
-
|
|
153
|
-
print(f"🔍 Loading custom installers from: {path_custom_installer}")
|
|
154
|
-
import runpy
|
|
155
|
-
|
|
156
|
-
res_custom_installers: list[InstallerData] = []
|
|
157
|
-
for item in path_custom_installer.search("*.py", r=False, not_in=["__init__"]):
|
|
158
|
-
try:
|
|
159
|
-
print(f"📄 Loading custom installer: {item.name}")
|
|
160
|
-
installer_data: InstallerData = runpy.run_path(str(item), run_name=None)["config_dict"]
|
|
161
|
-
res_custom_installers.append(installer_data)
|
|
162
|
-
except Exception as ex:
|
|
163
|
-
print(f"❌ Failed to load {item}: {ex}")
|
|
164
|
-
|
|
165
|
-
print(f"🔍 Loading custom dev installers from: {path_custom_installer_dev}")
|
|
166
|
-
res_custom_dev_installers: list[InstallerData] = []
|
|
167
|
-
for item in path_custom_installer_dev.search("*.py", r=False, not_in=["__init__"]):
|
|
168
|
-
try:
|
|
169
|
-
print(f"📄 Loading custom dev installer: {item.name}")
|
|
170
|
-
installer_data: InstallerData = runpy.run_path(str(item), run_name=None)["config_dict"]
|
|
171
|
-
res_custom_dev_installers.append(installer_data)
|
|
172
|
-
except Exception as ex:
|
|
173
|
-
print(f"❌ Failed to load {item}: {ex}")
|
|
174
|
-
|
|
175
|
-
res_final["CUSTOM"] = InstallerDataFiles({"version": "1", "installers": res_custom_installers})
|
|
176
|
-
res_final["CUSTOM_DEV"] = InstallerDataFiles({"version": "1", "installers": res_custom_dev_installers})
|
|
177
|
-
|
|
178
|
-
print(
|
|
179
|
-
f"✅ Configuration loading complete:\n - OS_SPECIFIC: {len(res_final['OS_SPECIFIC']['installers'])} items\n - OS_GENERIC: {len(res_final['OS_GENERIC']['installers'])} items\n - CUSTOM: {len(res_final['CUSTOM']['installers'])} items\n{'=' * 80}"
|
|
180
|
-
)
|
|
114
|
+
res_final: dict[APP_INSTALLER_CATEGORY, InstallerDataFiles] = {key: read_json(Path(module.__file__).parent.joinpath(f"packages_{key.lower()}.json")) for key in which_cats}
|
|
115
|
+
print(f"Loaded: {len(res_final)} installer categories")
|
|
116
|
+
for k, v in res_final.items():
|
|
117
|
+
print(f" - {k}: {len(v['installers'])} items")
|
|
181
118
|
return res_final
|
|
182
119
|
|
|
183
120
|
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Script to fetch GitHub release information from installer JSON files.
|
|
4
|
+
Extracts GitHub repository URLs and fetches latest release data with rate limiting.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import time
|
|
9
|
+
import subprocess
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Any, Dict, Optional, Set
|
|
12
|
+
from urllib.parse import urlparse
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def is_github_repo(url: str) -> bool:
|
|
16
|
+
"""Check if URL is a GitHub repository URL."""
|
|
17
|
+
try:
|
|
18
|
+
parsed = urlparse(url)
|
|
19
|
+
return parsed.netloc == "github.com" and len(parsed.path.split("/")) >= 3
|
|
20
|
+
except Exception:
|
|
21
|
+
return False
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def extract_github_repos_from_json(json_file_path: Path) -> Set[str]:
|
|
25
|
+
"""Extract GitHub repository URLs from installer JSON file."""
|
|
26
|
+
github_repos: Set[str] = set()
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
with open(json_file_path, 'r', encoding='utf-8') as file:
|
|
30
|
+
data = json.load(file)
|
|
31
|
+
|
|
32
|
+
for installer in data.get("installers", []):
|
|
33
|
+
repo_url = installer.get("repoURL", "")
|
|
34
|
+
if is_github_repo(repo_url):
|
|
35
|
+
github_repos.add(repo_url)
|
|
36
|
+
|
|
37
|
+
except (json.JSONDecodeError, FileNotFoundError) as e:
|
|
38
|
+
print(f"Error reading {json_file_path}: {e}")
|
|
39
|
+
|
|
40
|
+
return github_repos
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def get_repo_name_from_url(repo_url: str) -> str:
|
|
44
|
+
"""Extract owner/repo from GitHub URL."""
|
|
45
|
+
try:
|
|
46
|
+
parsed = urlparse(repo_url)
|
|
47
|
+
path_parts = parsed.path.strip("/").split("/")
|
|
48
|
+
return f"{path_parts[0]}/{path_parts[1]}"
|
|
49
|
+
except (IndexError, AttributeError):
|
|
50
|
+
return ""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def fetch_github_release_data(repo_name: str) -> Optional[Dict[str, Any]]:
|
|
54
|
+
"""Fetch latest release data from GitHub API using curl."""
|
|
55
|
+
try:
|
|
56
|
+
cmd = [
|
|
57
|
+
"curl", "-s",
|
|
58
|
+
f"https://api.github.com/repos/{repo_name}/releases/latest"
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
result = subprocess.run(
|
|
62
|
+
cmd,
|
|
63
|
+
capture_output=True,
|
|
64
|
+
text=True,
|
|
65
|
+
timeout=30
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
if result.returncode != 0:
|
|
69
|
+
print(f"❌ Failed to fetch data for {repo_name}: {result.stderr}")
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
response_data = json.loads(result.stdout)
|
|
73
|
+
|
|
74
|
+
# Check if API returned an error
|
|
75
|
+
if "message" in response_data:
|
|
76
|
+
if "API rate limit exceeded" in response_data.get("message", ""):
|
|
77
|
+
print(f"🚫 Rate limit exceeded for {repo_name}")
|
|
78
|
+
return None
|
|
79
|
+
elif "Not Found" in response_data.get("message", ""):
|
|
80
|
+
print(f"🔍 No releases found for {repo_name}")
|
|
81
|
+
return None
|
|
82
|
+
|
|
83
|
+
return response_data
|
|
84
|
+
|
|
85
|
+
except (subprocess.TimeoutExpired, json.JSONDecodeError, subprocess.SubprocessError) as e:
|
|
86
|
+
print(f"❌ Error fetching {repo_name}: {e}")
|
|
87
|
+
return None
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def extract_release_info(release_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
91
|
+
"""Extract relevant information from GitHub release data."""
|
|
92
|
+
if not release_data:
|
|
93
|
+
return {}
|
|
94
|
+
|
|
95
|
+
asset_names = [asset["name"] for asset in release_data.get("assets", [])]
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
"tag_name": release_data.get("tag_name", ""),
|
|
99
|
+
"name": release_data.get("name", ""),
|
|
100
|
+
"published_at": release_data.get("published_at", ""),
|
|
101
|
+
"assets": asset_names,
|
|
102
|
+
"assets_count": len(asset_names)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def main() -> None:
|
|
107
|
+
"""Main function to process installer JSON files and fetch GitHub release data."""
|
|
108
|
+
# Define paths
|
|
109
|
+
current_dir = Path(__file__).parent
|
|
110
|
+
installer_dir = current_dir.parent.parent / "jobs" / "installer"
|
|
111
|
+
|
|
112
|
+
standard_json = installer_dir / "packages_standard.json"
|
|
113
|
+
dev_json = installer_dir / "packages_dev.json"
|
|
114
|
+
output_json = current_dir / "github_releases.json"
|
|
115
|
+
|
|
116
|
+
print("🔍 Starting GitHub release data extraction...")
|
|
117
|
+
print(f"📁 Processing files from: {installer_dir}")
|
|
118
|
+
|
|
119
|
+
# Extract GitHub repositories from both files
|
|
120
|
+
all_github_repos: Set[str] = set()
|
|
121
|
+
|
|
122
|
+
if standard_json.exists():
|
|
123
|
+
print(f"📄 Reading {standard_json.name}...")
|
|
124
|
+
repos = extract_github_repos_from_json(standard_json)
|
|
125
|
+
all_github_repos.update(repos)
|
|
126
|
+
print(f" Found {len(repos)} GitHub repos")
|
|
127
|
+
else:
|
|
128
|
+
print(f"⚠️ File not found: {standard_json}")
|
|
129
|
+
|
|
130
|
+
if dev_json.exists():
|
|
131
|
+
print(f"📄 Reading {dev_json.name}...")
|
|
132
|
+
repos = extract_github_repos_from_json(dev_json)
|
|
133
|
+
all_github_repos.update(repos)
|
|
134
|
+
print(f" Found {len(repos)} GitHub repos")
|
|
135
|
+
else:
|
|
136
|
+
print(f"⚠️ File not found: {dev_json}")
|
|
137
|
+
|
|
138
|
+
print(f"🎯 Total unique GitHub repositories found: {len(all_github_repos)}")
|
|
139
|
+
|
|
140
|
+
if not all_github_repos:
|
|
141
|
+
print("❌ No GitHub repositories found. Exiting.")
|
|
142
|
+
return
|
|
143
|
+
|
|
144
|
+
# Fetch release data with rate limiting
|
|
145
|
+
release_mapping: Dict[str, Any] = {}
|
|
146
|
+
total_repos = len(all_github_repos)
|
|
147
|
+
|
|
148
|
+
print(f"\n🚀 Fetching release data for {total_repos} repositories...")
|
|
149
|
+
print("⏰ Rate limiting: 5 seconds between requests")
|
|
150
|
+
print("-" * 60)
|
|
151
|
+
|
|
152
|
+
for i, repo_url in enumerate(sorted(all_github_repos), 1):
|
|
153
|
+
repo_name = get_repo_name_from_url(repo_url)
|
|
154
|
+
|
|
155
|
+
if not repo_name:
|
|
156
|
+
print(f"⚠️ [{i:3d}/{total_repos}] Invalid repo URL: {repo_url}")
|
|
157
|
+
continue
|
|
158
|
+
|
|
159
|
+
print(f"📡 [{i:3d}/{total_repos}] Fetching: {repo_name}", end=" ... ")
|
|
160
|
+
|
|
161
|
+
release_data = fetch_github_release_data(repo_name)
|
|
162
|
+
|
|
163
|
+
if release_data:
|
|
164
|
+
release_info = extract_release_info(release_data)
|
|
165
|
+
release_mapping[repo_url] = release_info
|
|
166
|
+
assets_count = release_info.get("assets_count", 0)
|
|
167
|
+
tag = release_info.get("tag_name", "unknown")
|
|
168
|
+
print(f"✅ {tag} ({assets_count} assets)")
|
|
169
|
+
else:
|
|
170
|
+
release_mapping[repo_url] = {}
|
|
171
|
+
print("❌ No data")
|
|
172
|
+
|
|
173
|
+
# Rate limiting - wait 5 seconds between requests (except for the last one)
|
|
174
|
+
if i < total_repos:
|
|
175
|
+
time.sleep(5)
|
|
176
|
+
|
|
177
|
+
# Save results
|
|
178
|
+
output_data = {
|
|
179
|
+
"generated_at": time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime()),
|
|
180
|
+
"total_repositories": len(all_github_repos),
|
|
181
|
+
"successful_fetches": len([v for v in release_mapping.values() if v]),
|
|
182
|
+
"releases": release_mapping
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
with open(output_json, 'w', encoding='utf-8') as f:
|
|
186
|
+
json.dump(output_data, f, indent=2, ensure_ascii=False)
|
|
187
|
+
|
|
188
|
+
successful = len([v for v in release_mapping.values() if v])
|
|
189
|
+
print("\n📊 Summary:")
|
|
190
|
+
print(f" Total repositories processed: {len(all_github_repos)}")
|
|
191
|
+
print(f" Successful fetches: {successful}")
|
|
192
|
+
print(f" Failed fetches: {len(all_github_repos) - successful}")
|
|
193
|
+
print(f" Output saved to: {output_json}")
|
|
194
|
+
print("✅ Done!")
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
if __name__ == "__main__":
|
|
198
|
+
main()
|