Skip to content

Index

core

Core module for axm-edit.

Contains the batch editing engine and git checkpoint logic.

batch_apply(root, operations)

Validate and apply a batch of file operations atomically.

Parameters:

Name Type Description Default
root Path

Project root directory (all paths are relative to this).

required
operations Sequence[Operation]

List of replace, create, and delete operations.

required

Returns:

Type Description
BatchResult

BatchResult with success status, checkpoint SHA, and summary.

Source code in packages/axm-edit/src/axm_edit/core/engine.py
Python
def batch_apply(root: Path, operations: Sequence[Operation]) -> BatchResult:
    """Validate and apply a batch of file operations atomically.

    Args:
        root: Project root directory (all paths are relative to this).
        operations: List of replace, create, and delete operations.

    Returns:
        BatchResult with success status, checkpoint SHA, and summary.
    """
    root = root.resolve()
    grouped = _group_operations(operations)
    resolved_by_file, errors = _validate_all(root, grouped)

    if errors:
        return BatchResult(
            success=False,
            error="Validation failed",
            details=errors,
        )

    checkpoint = create_checkpoint(root)

    total_applied = 0
    for file_rel, resolved in resolved_by_file.items():
        total_applied += _apply_replace(root, file_rel, resolved)
    total_applied += _apply_creates_deletes(root, grouped.creates, grouped.deletes)

    return BatchResult(
        success=True,
        checkpoint=checkpoint,
        applied=total_applied,
        summary={
            "modified": len(resolved_by_file),
            "created": len(grouped.creates),
            "deleted": len(grouped.deletes),
        },
    )

create_checkpoint(root)

Create a git stash checkpoint.

Parameters:

Name Type Description Default
root Path

Project root directory.

required

Returns:

Type Description
str | None

The stash commit SHA, or None if not a git repo or nothing

str | None

to stash.

Source code in packages/axm-edit/src/axm_edit/core/checkpoint.py
Python
def create_checkpoint(root: Path) -> str | None:
    """Create a git stash checkpoint.

    Args:
        root: Project root directory.

    Returns:
        The stash commit SHA, or ``None`` if not a git repo or nothing
        to stash.
    """
    git_dir = root / ".git"
    if not git_dir.exists():
        return None

    try:
        result = subprocess.run(
            ["git", "stash", "create", "-m", "axm-edit checkpoint"],
            cwd=root,
            capture_output=True,
            text=True,
            check=False,
        )
        sha = result.stdout.strip()
        return sha if sha else None
    except OSError:
        return None

rollback(root, checkpoint)

Rollback to a previous checkpoint.

Restores the working tree to the state captured by :func:create_checkpoint.

Parameters:

Name Type Description Default
root Path

Project root directory.

required
checkpoint str

The stash SHA returned by create_checkpoint.

required

Returns:

Type Description
bool

True if rollback succeeded.

Source code in packages/axm-edit/src/axm_edit/core/checkpoint.py
Python
def rollback(root: Path, checkpoint: str) -> bool:
    """Rollback to a previous checkpoint.

    Restores the working tree to the state captured by
    :func:`create_checkpoint`.

    Args:
        root: Project root directory.
        checkpoint: The stash SHA returned by ``create_checkpoint``.

    Returns:
        ``True`` if rollback succeeded.
    """
    try:
        # Reset tracked files
        subprocess.run(
            ["git", "checkout", "--", "."],
            cwd=root,
            capture_output=True,
            text=True,
            check=True,
        )
        # Remove untracked files created by batch_edit
        subprocess.run(
            ["git", "clean", "-fd"],
            cwd=root,
            capture_output=True,
            text=True,
            check=True,
        )
        # Re-apply the stashed state
        if checkpoint:
            subprocess.run(
                ["git", "stash", "apply", checkpoint],
                cwd=root,
                capture_output=True,
                text=True,
                check=True,
            )
        return True
    except (subprocess.CalledProcessError, OSError):
        return False