Aggiunta gestione submoduli
This commit is contained in:
parent
5ab2fce4f4
commit
1bbbd09762
@ -25,5 +25,7 @@
|
||||
"pyinstaller_gui_git": {},
|
||||
"geoelevation_git": {},
|
||||
"dependencyanalizer_git": {},
|
||||
"dependencyanalyzer_git": {}
|
||||
"dependencyanalyzer_git": {},
|
||||
"git_utility_git": {},
|
||||
"pyucc_git": {}
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
"description": "Generates .ico files from PNG images, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/CreateIconFromFilesPng",
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_CreateIconFromFilesPng",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "create_icon_file.py"],
|
||||
"has_gui": false,
|
||||
@ -17,7 +17,7 @@
|
||||
"description": "GUI Wrapper for PyInstaller, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/PyInstallerGUIWrapper",
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_PyInstallerGUIWrapper",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "pyinstallerguiwrapper"],
|
||||
"has_gui": true,
|
||||
@ -29,7 +29,7 @@
|
||||
"description": "Get elevation data from network, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/GeoElevation",
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_GeoElevation",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "geoelevation"],
|
||||
"has_gui": true,
|
||||
@ -41,7 +41,7 @@
|
||||
"description": "Manag. requirements from python project, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/DependencyAnalyzer",
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_DependencyAnalyzer",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "dependencyanalyzer"],
|
||||
"has_gui": true,
|
||||
@ -53,7 +53,7 @@
|
||||
"description": "Create standard folders for new dev tool, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/ProjectInitializer",
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_ProjectInitializer",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "projectinitializer"],
|
||||
"has_gui": true,
|
||||
@ -65,7 +65,7 @@
|
||||
"description": "Gui for console application g_reconverter, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/GUI_g_reconverter",
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_GUI_g_reconverter",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "gui_g_reconverter"],
|
||||
"has_gui": true,
|
||||
@ -89,7 +89,7 @@
|
||||
"description": "Backup suite, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/BackupTools",
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_BackupTools",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "backuptools"],
|
||||
"has_gui": true,
|
||||
@ -101,12 +101,85 @@
|
||||
"description": "Launcher tool, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/LauncherTool",
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_LauncherTool",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "launchertool"],
|
||||
"has_gui": true,
|
||||
"parameters_definition_file": null
|
||||
},
|
||||
{
|
||||
"id": "py_hasher_git",
|
||||
"display_name": "PyHasher(Git)",
|
||||
"description": "PyHasher, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_PyHasher",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "pyhasher"],
|
||||
"has_gui": true,
|
||||
"parameters_definition_file": null
|
||||
},
|
||||
{
|
||||
"id": "repo_sync_git",
|
||||
"display_name": "RepoSync (Git)",
|
||||
"description": "Reporter sync, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_RepoSync",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "reposync"],
|
||||
"has_gui": true,
|
||||
"parameters_definition_file": null
|
||||
},
|
||||
{
|
||||
"id": "profile_analyzer_git",
|
||||
"display_name": "Profile Analyzer (Git)",
|
||||
"description": "View profile files, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_ProfileAnalyzer",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "profileanalyzer"],
|
||||
"has_gui": true,
|
||||
"parameters_definition_file": null
|
||||
},
|
||||
{
|
||||
"id": "markdown_converter_git",
|
||||
"display_name": "Markdown Converter (Git)",
|
||||
"description": "Markdown Converter into pdf and docx, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_MarkdownConverter",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "markdownconverter"],
|
||||
"has_gui": true,
|
||||
"parameters_definition_file": null
|
||||
},
|
||||
{
|
||||
"id": "pyucc_git",
|
||||
"display_name": "Py UCC (Git)",
|
||||
"description": "Py UCC, fetched via Git.",
|
||||
"type": "git",
|
||||
"enabled": true,
|
||||
"git_url": "http://192.168.100.10:3000/VALLONGOL/SXXXXXXX_PyUCC",
|
||||
"git_ref": "master",
|
||||
"run_command": ["python", "-m", "pyucc"],
|
||||
"has_gui": true,
|
||||
"parameters_definition_file": null,
|
||||
"auto_update_submodules": true,
|
||||
"submodules": [
|
||||
{
|
||||
"name": "python-resource-monitor",
|
||||
"path": "external/python-resource-monitor",
|
||||
"modules": ["resource_monitor.py"]
|
||||
},
|
||||
{
|
||||
"name": "python-tkinter-logger",
|
||||
"path": "external/python-tkinter-logger",
|
||||
"modules": ["tkinter_logger.py"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "dummy_script",
|
||||
"display_name": "Dummy Script Runner (Local)",
|
||||
|
||||
@ -573,6 +573,28 @@ def update_repository(
|
||||
f"Error in progress callback (post-pull success): {cb_err}",
|
||||
exc_info=True,
|
||||
)
|
||||
|
||||
# --- Submodule handling (if configured) ---
|
||||
try:
|
||||
if getattr(tool_entry, "auto_update_submodules", False) or getattr(
|
||||
tool_entry, "submodules", None
|
||||
):
|
||||
local_path = get_local_repo_path(tool_id, tool_entry.local_dir_name)
|
||||
try:
|
||||
from projectutility.core.submodule_manager import ensure_submodules
|
||||
|
||||
ok = ensure_submodules(local_path, tool_entry.submodules)
|
||||
if not ok:
|
||||
logger.warning(
|
||||
f"[{tool_id}] Submodule update returned non-ok status."
|
||||
)
|
||||
except Exception as e:
|
||||
logger.exception(
|
||||
f"[{tool_id}] Failed to run submodule update: {e}"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.exception(f"[{tool_id}] Error checking submodule config: {e}")
|
||||
|
||||
return (
|
||||
True,
|
||||
f"Repo updated. On branch '{current_branch_name}' tracking '{target_ref}'.",
|
||||
@ -617,6 +639,27 @@ def update_repository(
|
||||
logger.info(
|
||||
f"[{tool_id}] Checkout to detached HEAD at {detached_commit_sha} ('{target_ref}'). Update complete."
|
||||
)
|
||||
# Try submodule update for detached HEAD too
|
||||
try:
|
||||
if getattr(tool_entry, "auto_update_submodules", False) or getattr(
|
||||
tool_entry, "submodules", None
|
||||
):
|
||||
local_path = get_local_repo_path(tool_id, tool_entry.local_dir_name)
|
||||
try:
|
||||
from projectutility.core.submodule_manager import ensure_submodules
|
||||
|
||||
ok = ensure_submodules(local_path, tool_entry.submodules)
|
||||
if not ok:
|
||||
logger.warning(
|
||||
f"[{tool_id}] Submodule update returned non-ok status (detached HEAD)."
|
||||
)
|
||||
except Exception as e:
|
||||
logger.exception(
|
||||
f"[{tool_id}] Failed to run submodule update (detached HEAD): {e}"
|
||||
)
|
||||
except Exception:
|
||||
logger.exception(f"[{tool_id}] Error checking submodule config (detached HEAD)")
|
||||
|
||||
return (
|
||||
True,
|
||||
f"Repo at '{target_ref}' (Detached HEAD {detached_commit_sha}).",
|
||||
|
||||
@ -43,6 +43,9 @@ class ToolRegistryEntry:
|
||||
local_dir_name: Optional[str] = (
|
||||
None # Optional custom name for the local directory in 'managed_tools'. Defaults to 'id' if None.
|
||||
)
|
||||
# --- Submodule support ---
|
||||
auto_update_submodules: bool = False # If true, attempt to init/update submodules automatically
|
||||
submodules: Optional[List[Dict[str, Any]]] = None
|
||||
|
||||
# --- Parameter Definition Source ---
|
||||
# For type='local', this can be an inline list of parameter dicts.
|
||||
|
||||
74
projectutility/core/submodule_manager.py
Normal file
74
projectutility/core/submodule_manager.py
Normal file
@ -0,0 +1,74 @@
|
||||
"""projectutility.core.submodule_manager
|
||||
|
||||
Utilities to ensure Git submodules are initialized/updated for a tool repo.
|
||||
|
||||
This module uses the system `git` command via subprocess to avoid
|
||||
adding a hard dependency on GitPython for submodule operations.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
from typing import List, Optional, Dict
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ensure_submodules(
|
||||
repo_root: str, submodules: Optional[List[Dict[str, str]]] = None, timeout: int = 300
|
||||
) -> bool:
|
||||
"""Ensure submodules are initialized and updated for a repository.
|
||||
|
||||
Args:
|
||||
repo_root: absolute path to the repository root (where .git lives).
|
||||
submodules: optional list of dicts describing submodules. Each dict may
|
||||
contain a `path` key (relative path inside repo). If None,
|
||||
this will attempt to update the whole `external` directory
|
||||
if it exists, otherwise run a global submodule update.
|
||||
timeout: max seconds to wait for the git command.
|
||||
|
||||
Returns:
|
||||
True if git submodule update completed successfully, False otherwise.
|
||||
"""
|
||||
if not os.path.isdir(repo_root):
|
||||
logger.error("Submodule update: repo_root not found: %s", repo_root)
|
||||
return False
|
||||
|
||||
cmd = ["git", "-C", repo_root, "submodule", "update", "--init", "--recursive"]
|
||||
|
||||
# Build path list for git command
|
||||
if submodules:
|
||||
paths = []
|
||||
for entry in submodules:
|
||||
p = entry.get("path") if isinstance(entry, dict) else None
|
||||
if p:
|
||||
paths.append(p)
|
||||
if paths:
|
||||
cmd += paths
|
||||
else:
|
||||
# Fallback: if repo has 'external' directory, limit to it
|
||||
external = os.path.join(repo_root, "external")
|
||||
if os.path.isdir(external):
|
||||
cmd += ["external"]
|
||||
|
||||
logger.info("Running submodule update: %s", " ".join(cmd))
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
cmd, check=True, capture_output=True, text=True, timeout=timeout
|
||||
)
|
||||
if proc.stdout:
|
||||
logger.debug("git submodule stdout: %s", proc.stdout)
|
||||
if proc.stderr:
|
||||
logger.debug("git submodule stderr: %s", proc.stderr)
|
||||
logger.info("Submodule update completed for %s", repo_root)
|
||||
return True
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error(
|
||||
"git submodule update failed for %s: %s", repo_root, e.stderr or str(e)
|
||||
)
|
||||
return False
|
||||
except subprocess.TimeoutExpired:
|
||||
logger.error("git submodule update timeout for %s", repo_root)
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.exception("Unexpected error while updating submodules for %s: %s", repo_root, e)
|
||||
return False
|
||||
@ -164,54 +164,6 @@ except ImportError as e:
|
||||
)
|
||||
# Ensure flag is False and constants remain dummies
|
||||
GIT_ENABLED = False
|
||||
# Define dummy class if import failed completely
|
||||
class git_manager:
|
||||
pass# ridefinito come dummy se fallisce import
|
||||
# ... (definizione dummy di git_manager)
|
||||
|
||||
except Exception as e:
|
||||
logging.getLogger(__name__).error(
|
||||
f"Unexpected error importing git_manager: {e}. Git features disabled.",
|
||||
exc_info=True
|
||||
)
|
||||
GIT_ENABLED = False
|
||||
|
||||
try:
|
||||
# Absolute import
|
||||
from projectutility.core import git_manager
|
||||
|
||||
GIT_ENABLED = git_manager.GITPYTHON_AVAILABLE
|
||||
|
||||
if GIT_ENABLED:
|
||||
# Import real constants only if GitPython is available
|
||||
from projectutility.core.git_manager import (
|
||||
GIT_STATUS_UP_TO_DATE,
|
||||
GIT_STATUS_BEHIND,
|
||||
GIT_STATUS_AHEAD,
|
||||
GIT_STATUS_DIVERGED,
|
||||
GIT_STATUS_NOT_CLONED,
|
||||
GIT_STATUS_ERROR,
|
||||
GIT_STATUS_CHECKING,
|
||||
GIT_STATUS_UPDATING,
|
||||
GIT_STATUS_GITPYTHON_MISSING,
|
||||
)
|
||||
|
||||
logging.getLogger(__name__).info(
|
||||
"Successfully imported git_manager (GitPython available)."
|
||||
)
|
||||
else:
|
||||
logging.getLogger(__name__).warning(
|
||||
"Imported git_manager, but GitPython library not found. Git features disabled."
|
||||
)
|
||||
# Constants keep their default dummy values defined above
|
||||
|
||||
except ImportError as e:
|
||||
logging.getLogger(__name__).error(
|
||||
f"Failed to import core.git_manager: {e}. Git features disabled.", exc_info=True
|
||||
)
|
||||
# Ensure flag is False and constants remain dummies
|
||||
GIT_ENABLED = False
|
||||
|
||||
# Define dummy class if import failed completely
|
||||
class git_manager:
|
||||
GITPYTHON_AVAILABLE = False
|
||||
@ -238,7 +190,7 @@ except ImportError as e:
|
||||
except Exception as e:
|
||||
logging.getLogger(__name__).error(
|
||||
f"Unexpected error importing git_manager: {e}. Git features disabled.",
|
||||
exc_info=True,
|
||||
exc_info=True
|
||||
)
|
||||
GIT_ENABLED = False
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user