Loading...
No commits yet
Not committed History
Blame
_create.py • 5.3 KB
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File: src/scitex_writer/_project/_create.py

"""
Project creation logic for writer module.

Handles creating new writer projects from template.
"""

from __future__ import annotations

import shutil
import subprocess
from logging import getLogger
from pathlib import Path
from typing import Optional

logger = getLogger(__name__)

# Template repository URL
TEMPLATE_REPO_URL = "https://github.com/ywatanabe1989/scitex-writer.git"


def clone_writer_project(
    project_dir: str,
    git_strategy: Optional[str] = "child",
    branch: Optional[str] = None,
    tag: Optional[str] = None,
) -> bool:
    """
    Initialize a new writer project directory from scitex-writer template.

    Args:
        project_dir: Path to project directory (will be created)
        git_strategy: Git initialization strategy (optional)
            - 'child': Create isolated git in project directory (default)
            - 'parent': Use parent git repository
            - 'origin': Preserve template's original git history
            - None or 'none': Disable git initialization
        branch: Specific branch of the template repository to clone (optional)
            If None, clones the default branch. Mutually exclusive with tag.
        tag: Specific tag/release of the template repository to clone (optional)
            If None, clones the default branch. Mutually exclusive with branch.

    Returns:
        True if successful, False otherwise

    Examples:
        >>> clone_writer_project("my_paper")
        >>> clone_writer_project("./papers/my_paper")
        >>> clone_writer_project("my_paper", git_strategy="parent")
        >>> clone_writer_project("my_paper", branch="develop")
        >>> clone_writer_project("my_paper", tag="v1.0.0")
    """
    try:
        project_path = Path(project_dir)

        if project_path.exists():
            logger.error(f"Directory already exists: {project_path}")
            return False

        # Build git clone command
        cmd = ["git", "clone"]

        if branch:
            cmd.extend(["--branch", branch])
        elif tag:
            cmd.extend(["--branch", tag])

        cmd.extend([TEMPLATE_REPO_URL, str(project_path)])

        # Execute git clone
        result = subprocess.run(cmd, capture_output=True, text=True)

        if result.returncode != 0:
            logger.error(f"Git clone failed: {result.stderr}")
            return False

        # Handle git strategy
        if git_strategy == "none" or git_strategy is None:
            git_dir = project_path / ".git"
            if git_dir.exists():
                shutil.rmtree(git_dir)
        elif git_strategy == "child":
            git_dir = project_path / ".git"
            if git_dir.exists():
                shutil.rmtree(git_dir)
            subprocess.run(["git", "init"], cwd=str(project_path), capture_output=True)
            subprocess.run(
                ["git", "add", "."], cwd=str(project_path), capture_output=True
            )
            subprocess.run(
                ["git", "commit", "-m", "Initial commit from scitex-writer template"],
                cwd=str(project_path),
                capture_output=True,
            )
        # "parent" and "origin" strategies keep the git history as-is

        logger.info(f"Successfully created writer project at {project_path}")
        return True

    except Exception as e:
        logger.error(f"Failed to initialize writer directory: {e}")
        return False


def ensure_project_exists(
    project_dir: Path,
    project_name: str,
    git_strategy: Optional[str] = "child",
    branch: Optional[str] = None,
    tag: Optional[str] = None,
) -> Path:
    """
    Ensure project directory exists, creating it if necessary.

    Parameters
    ----------
    project_dir : Path
        Path to project directory
    project_name : str
        Name of the project
    git_strategy : str or None
        Git initialization strategy
    branch : str, optional
        Specific branch of template repository to clone. If None, clones the default branch.
        Mutually exclusive with tag parameter.
    tag : str, optional
        Specific tag/release of template repository to clone. If None, clones the default branch.
        Mutually exclusive with branch parameter.

    Returns
    -------
    Path
        Path to the project directory

    Raises
    ------
    RuntimeError
        If project creation fails
    """
    if project_dir.exists():
        logger.info(f"Attached to existing project at {project_dir.absolute()}")
        return project_dir

    logger.info(f"Creating new project '{project_name}' at {project_dir.absolute()}")

    # Initialize project directory structure
    success = clone_writer_project(str(project_dir), git_strategy, branch, tag)

    if not success:
        logger.error(f"Failed to initialize project directory for {project_name}")
        raise RuntimeError(f"Could not create project directory at {project_dir}")

    # Verify project directory was created
    if not project_dir.exists():
        logger.error(f"Project directory {project_dir} was not created")
        raise RuntimeError(f"Project directory {project_dir} was not created")

    logger.info(f"Successfully created project at {project_dir.absolute()}")
    return project_dir


__all__ = ["ensure_project_exists", "clone_writer_project"]

# EOF