chore: snapshot current project updates

This commit is contained in:
windyboy
2026-02-13 13:36:39 +08:00
parent 5931f16a71
commit 0be802eac5
74 changed files with 594899 additions and 66082 deletions
+72 -5
View File
@@ -18,7 +18,9 @@ from .config import Config
from .logging_config import get_logger, log_operation
from .models import ExecutionPlan, FileOperation, OperationResult, RollbackLog
from .quarantine import QuarantineManager
from .utils import ensure_utc, utc_now
from .state import StateManager
from .transaction import TransactionLog
from .utils import ensure_utc, is_within_root, utc_now
class ExecutionEngine:
@@ -28,15 +30,21 @@ class ExecutionEngine:
self,
logger: Optional[logging.Logger] = None,
config: Optional[Config] = None,
verbose_operations: bool = False,
state_manager: Optional[StateManager] = None,
):
"""Initialize the execution engine.
Args:
logger: Optional logger instance (uses default if not provided)
config: Optional config (required for quarantine operations)
verbose_operations: Emit per-operation dry-run logs at INFO when True
state_manager: Optional state manager for updating file statuses
"""
self.logger = logger or get_logger()
self.config = config
self.verbose_operations = verbose_operations
self.state_manager = state_manager
self._quarantine_manager: Optional[QuarantineManager] = (
QuarantineManager(config, self.logger) if config else None
)
@@ -80,12 +88,47 @@ class ExecutionEngine:
f"Starting execution in {mode} mode with {len(plan.operations)} operations",
operation_type="execute"
)
# Initialize transaction log for execute mode
transaction_log = None
if mode == "execute":
log_path = Path.home() / ".vlm" / "transaction.json"
transaction_log = TransactionLog(log_path)
transaction_log.start_transaction(plan)
# Execute all operations
results = []
for operation in plan.operations:
for i, operation in enumerate(plan.operations):
result = self.execute_operation(operation, mode)
results.append(result)
# Update transaction and state logs in execute mode
if mode == "execute":
if transaction_log:
transaction_log.mark_operation_complete(
i, result.success, result.error_message
)
# Update file state if successful and not a no-op
if result.success and operation.operation_type != "no-op" and self.state_manager:
new_status = "quarantined" if operation.operation_type == "quarantine" else "executed"
self.state_manager.set_file_state(
operation.source_path,
status=new_status,
reason=operation.reason
)
# We could save state incrementally, but saving at the end is more efficient.
# For extra safety, we'll save every 10 operations.
if (i + 1) % 10 == 0:
self.state_manager.save()
# Finalize transaction and state
if mode == "execute":
if transaction_log:
status = "completed" if all(r.success for r in results) else "failed"
transaction_log.complete_transaction(status=status)
if self.state_manager:
self.state_manager.save()
# Generate execution summary
summary = self._generate_execution_summary(results)
@@ -156,9 +199,10 @@ class ExecutionEngine:
executed_at=executed_at
)
if mode == "dry-run":
level = logging.INFO if self.verbose_operations else logging.DEBUG
log_operation(
self.logger,
logging.INFO,
level,
f"[DRY-RUN] Would quarantine: {operation.source_path} ({operation.reason})",
operation_type="execute",
file_path=operation.source_path
@@ -219,7 +263,7 @@ class ExecutionEngine:
)
log_operation(
self.logger,
logging.INFO,
logging.INFO if self.verbose_operations else logging.DEBUG,
msg,
operation_type="execute",
file_path=operation.source_path
@@ -266,6 +310,25 @@ class ExecutionEngine:
# Create destination directory if needed
if operation.destination_path:
if self.config and not is_within_root(
operation.destination_path, self.config.library_root
):
error_msg = (
f"Unsafe destination outside library root: {operation.destination_path}"
)
log_operation(
self.logger,
logging.ERROR,
error_msg,
operation_type="execute",
file_path=operation.source_path
)
return OperationResult(
operation=operation,
success=False,
error_message=error_msg,
executed_at=executed_at
)
operation.destination_path.parent.mkdir(parents=True, exist_ok=True)
# Perform the move/rename operation
@@ -316,7 +379,11 @@ class ExecutionEngine:
Dictionary with counts of successful, failed, and skipped operations
"""
successful = sum(1 for r in results if r.success)
failed = sum(1 for r in results if not r.success)
failed = sum(
1
for r in results
if (not r.success) and (not r.operation.has_conflict)
)
skipped = sum(
1 for r in results
if r.operation.operation_type == "no-op" or r.operation.has_conflict