Merge branch 'feat/offline' into 'main'

feat: Added local update functions

See merge request CodeByMrFinchum/PyPiUpdater!6
This commit is contained in:
Mr Finchum 2025-02-03 15:21:47 +00:00
commit 6c59a1ae98
2 changed files with 55 additions and 0 deletions

View file

@ -1,5 +1,15 @@
# Changelog # Changelog
## 0.6.0: New Local Update Feature
- Added support for updating from a local folder containing package files.
- Scans a specified folder for available updates.
- Installs updates directly from local package files.
- **Note:** Local version handling depends on how dependencies are managed.
- Example: If a package requires **PyPiUpdater 0.6.0**, but the installed version is **0.0.1** (e.g., from a dev environment), **OptimaLab35 v0.9.1** may not install correctly.
- This is due to **pip's dependency checks**, ensuring all required versions are satisfied before installation.
---
## 0.5.0: Rework (BREAKING CHANGE) ## 0.5.0: Rework (BREAKING CHANGE)
- Improved code consistency: return values are now always **lists** when containing multiple objects. - Improved code consistency: return values are now always **lists** when containing multiple objects.
- **Simplified the package**: Removed the default waiting period for update checks. - **Simplified the package**: Removed the default waiting period for update checks.

View file

@ -4,6 +4,7 @@ import sys
import os import os
import time import time
import json import json
import re
from packaging import version from packaging import version
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
@ -59,6 +60,50 @@ class PyPiUpdater:
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
return [False, f"Update failed: {str(e)}"] return [False, f"Update failed: {str(e)}"]
def check_update_local(self, folder_path):
"""
Check if a newer version of the package is available in the local folder.
:param folder_path: Path to the folder containing package files.
:return: (bool, latest_version) - True if newer version found, otherwise False.
"""
if not os.path.exists(folder_path):
return [None, "Folder does not exist"]
pattern = re.compile(rf"{re.escape(self.package_name.lower())}-(\d+\.\d+\.\d+[a-zA-Z0-9]*)")
available_versions = []
for file in os.listdir(folder_path):
match = pattern.search(file)
if match:
found_version = match.group(1)
available_versions.append(version.parse(found_version))
if not available_versions:
return [None, "No valid package versions found in the folder"]
latest_version = max(available_versions)
is_newer = latest_version > self.local_version
return [is_newer, str(latest_version)]
def update_from_local(self, folder_path):
"""
Install the latest package version from a local folder.
:param folder_path: Path to the folder containing package files.
:return: (bool, message) - Success status and message.
"""
print(f"Installing {self.package_name} from {folder_path}...")
try:
subprocess.run(
[sys.executable, "-m", "pip", "install", "--no-index", "--find-links", folder_path, self.package_name, "-U"],
check=True
)
return [True, f"{self.package_name} updated successfully from local folder."]
except subprocess.CalledProcessError as e:
return [False, f"Update from local folder failed: {str(e)}"]
def restart_program(self): def restart_program(self):
"""Restart the Python program after an update.""" """Restart the Python program after an update."""
print("Restarting the application...") print("Restarting the application...")