Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 205 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,229 @@
[![PyPI version](https://badge.fury.io/py/repo-scaffold.svg)](https://badge.fury.io/py/repo-scaffold)
[![Python Version](https://img.shields.io/pypi/pyversions/repo-scaffold.svg)](https://pypi.org/project/repo-scaffold/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Tests](https://github.com/your-username/repo-scaffold/workflows/Tests/badge.svg)](https://github.com/your-username/repo-scaffold/actions)

A modern project scaffolding tool with component-based architecture.
A modern, intelligent project scaffolding tool that generates production-ready Python projects in seconds.

## Features
## Features

- 🚀 Quick project creation
- 📦 Component-based templates
- ⚙️ Interactive configuration
- 🔧 Best practices included
- 🚀 **Zero-config setup** - Create projects instantly without answering questions
- 📦 **Component-based architecture** - Mix and match features as needed
- 🎯 **Production-ready templates** - Includes CI/CD, testing, documentation, and more
- 🔧 **Modern Python tooling** - Built with uv, Ruff, pytest, and Task automation
- 🐳 **Container support** - Optional Podman/Docker integration
- 📚 **Documentation ready** - MkDocs setup with auto-generated API docs
- 🔄 **GitHub Actions** - Complete CI/CD workflows included
- 📦 **PyPI publishing** - Automated package publishing with trusted publishing
- 🎨 **Code quality** - Pre-commit hooks, linting, and formatting configured

## Quick Start
## 🚀 Quick Start

### Installation

```bash
# Install
# Install globally with uvx (recommended)
uvx install repo-scaffold

# Create project
# Or install with pip
pip install repo-scaffold
```

### Create Your First Project

```bash
# Create a Python library project (uses smart defaults)
repo-scaffold create

# That's it! Your project is ready with:
# ✅ Modern Python setup (pyproject.toml, uv)
# ✅ Testing framework (pytest with coverage)
# ✅ Code quality tools (ruff, pre-commit)
# ✅ GitHub Actions CI/CD
# ✅ Documentation (MkDocs)
# ✅ Task automation (Taskfile)
```

### What You Get

After running `repo-scaffold create`, you'll have a complete project structure:

```
my-python-library/
├── .github/workflows/ # CI/CD pipelines
├── docs/ # MkDocs documentation
├── tests/ # Test suite
├── my_python_library/ # Your package
├── pyproject.toml # Modern Python configuration
├── Taskfile.yml # Task automation
├── README.md # Project documentation
└── .pre-commit-config.yaml # Code quality hooks
```

### Start Developing

```bash
cd my-python-library
task init # Initialize development environment
task test # Run tests
task lint # Check code quality
task docs # Serve documentation locally
```

## 📋 Available Commands

```bash
# Project creation
repo-scaffold create # Create with defaults (recommended)
repo-scaffold create --input # Interactive mode with prompts
repo-scaffold create -t python-library # Specify template explicitly
repo-scaffold create -o ./my-project # Specify output directory

# Information commands
repo-scaffold list # List available templates
repo-scaffold components # List available components
repo-scaffold show python-library # Show template details
repo-scaffold --help # Show help
```

## 🎯 Usage Examples

### Basic Usage (Recommended)

```bash
# Create a project with smart defaults - no questions asked!
repo-scaffold create
```

This creates a full-featured Python library with:
- **Python Core**: Modern pyproject.toml setup with uv
- **Task Automation**: Taskfile.yml for common development tasks
- **GitHub Actions**: Complete CI/CD with testing, linting, and publishing
- **Documentation**: MkDocs with auto-generated API docs
- **Code Quality**: Pre-commit hooks, Ruff linting and formatting
- **Container Support**: Podman/Docker setup for containerized development
- **PyPI Publishing**: Automated package publishing workflows

### Interactive Mode

```bash
# If you want to customize the setup
repo-scaffold create --input
```

# Or run directly
uvx run repo-scaffold create
This will prompt you to:
- Choose which components to include
- Configure project details
- Set up custom options

### Advanced Usage

```bash
# Create in specific directory
repo-scaffold create -o ~/projects/my-new-lib

# Use different template (when more templates are available)
repo-scaffold create -t python-library

# Combine options
repo-scaffold create -t python-library -o ~/projects --input
```

## 🧩 Available Components

The `python-library` template includes these components:

| Component | Description | Included by Default |
|-----------|-------------|-------------------|
| **Python Core** | Modern Python setup with pyproject.toml and uv | ✅ |
| **Task Automation** | Taskfile.yml for development workflows | ✅ |
| **GitHub Actions** | CI/CD pipelines for testing and deployment | ✅ |
| **MkDocs** | Documentation site with auto-generated API docs | ✅ |
| **Pre-commit** | Code quality hooks and automated formatting | ✅ |
| **Podman** | Container support for development and deployment | ✅ |
| **PyPI Publishing** | Automated package publishing to PyPI | ✅ |

## 🛠️ Development Workflow

After creating your project, here's the typical development workflow:

```bash
# 1. Initialize the development environment
task init

# 2. Make your changes
# Edit code in your_package/

# 3. Run tests
task test

# 4. Check code quality
task lint

# 5. View documentation
task docs

# 6. Build package
task build

# 7. Commit changes (pre-commit hooks will run automatically)
git add .
git commit -m "feat: add new feature"

# 8. Push to trigger CI/CD
git push
```

## Commands
## 🔧 Configuration

### Default Values

The tool uses sensible defaults for all configuration:

- **Project Name**: "My Python Library"
- **Package Name**: Auto-generated from project name
- **Author**: "Your Name" (customize in interactive mode)
- **License**: MIT
- **Python Version**: 3.10-3.12 support, 3.10 for development
- **All Components**: Enabled by default

### Customization

Use `--input` flag for interactive customization:

```bash
repo-scaffold list # List templates
repo-scaffold components # List components
repo-scaffold create # Create project
repo-scaffold show <name> # Show template info
repo-scaffold create --input
```

## Documentation
This allows you to:
- Set custom project name and description
- Choose your preferred license
- Select which components to include
- Configure component-specific options

## 📚 Documentation

- [Getting Started](docs/getting-started/)
- [Installation](docs/getting-started/installation.md)
- [Quick Start](docs/getting-started/quick-start.md)
- [Configuration](docs/getting-started/configuration.md)
- [Components](docs/components/)
- [Templates](docs/templates/)

## 🤝 Contributing

Contributions are welcome! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🙏 Acknowledgments

Built with modern Python tooling:
- [uv](https://github.com/astral-sh/uv) - Fast Python package manager
- [Ruff](https://github.com/astral-sh/ruff) - Lightning-fast Python linter
- [pytest](https://pytest.org/) - Testing framework
- [MkDocs](https://www.mkdocs.org/) - Documentation generator
- [Task](https://taskfile.dev/) - Task automation
- [Cookiecutter](https://github.com/cookiecutter/cookiecutter) - Template engine
52 changes: 41 additions & 11 deletions repo_scaffold/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
import click
import yaml

from .core.component_manager import ComponentManager
from .core.cookiecutter_runner import CookiecutterRunner
from .core.template_composer import TemplateComposer
from repo_scaffold.core.component_manager import ComponentManager
from repo_scaffold.core.cookiecutter_runner import CookiecutterRunner
from repo_scaffold.core.template_composer import TemplateComposer


# Default paths - can be overridden by environment variables or config
Expand All @@ -35,19 +35,49 @@ def cli():
default=Path.cwd(),
help="Output directory for the generated project",
)
def create(template: str | None, output: Path):
"""Create a new project from a template."""
@click.option(
"--no-input",
is_flag=True,
default=True,
help="Do not prompt for parameters and only use cookiecutter.json file content (default: True)",
)
@click.option(
"--input",
"prompt_input",
is_flag=True,
help="Prompt for parameters interactively (overrides --no-input)",
)
def create(template: str | None, output: Path, no_input: bool, prompt_input: bool):
"""Create a new project from a template.

By default, uses template defaults without prompting (--no-input).
Use --input to enable interactive prompts for customization.
"""
try:
# Determine if we should prompt for input
# --input flag overrides the default --no-input behavior
should_prompt = prompt_input or not no_input

if template:
# Use specified template
template_config = load_template_config(template)
template_name = template
else:
# Interactive template selection
template_name, template_config = interactive_template_selection()

# Interactive component selection
selected_components = interactive_component_selection(template_config)
# Interactive template selection (only if prompting is enabled)
if should_prompt:
template_name, template_config = interactive_template_selection()
else:
# Use default template when no input is requested
template_name = "python-library"
template_config = load_template_config(template_name)

# Component selection
if should_prompt:
# Interactive component selection
selected_components = interactive_component_selection(template_config)
else:
# Use all required components when no input is requested
selected_components = template_config.get("required_components", [])

# Initialize core components
component_manager = ComponentManager(DEFAULT_COMPONENTS_DIR)
Expand All @@ -69,7 +99,7 @@ def create(template: str | None, output: Path):
try:
# Run cookiecutter
click.echo("🚀 Generating project...")
project_path = runner.run_cookiecutter(temp_template_dir, output)
project_path = runner.run_cookiecutter(temp_template_dir, output, no_input=not should_prompt)

click.echo(f"✅ Project created successfully at: {project_path}")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ permissions:
contents: read
env:
{% if cookiecutter.use_private_pypi == "true" -%}
UV_INDEX_{{cookiecutter.private_pypi_name | upper}}_USERNAME: ${{ secrets.PYPI_SERVER_USERNAME }}
UV_INDEX_{{cookiecutter.private_pypi_name | upper}}_PASSWORD: ${{ secrets.PYPI_SERVER_PASSWORD }}
PYPI_SERVER_USERNAME: ${{ secrets.PYPI_SERVER_USERNAME }}
PYPI_SERVER_PASSWORD: ${{ secrets.PYPI_SERVER_PASSWORD }}
UV_INDEX_{{cookiecutter.private_pypi_name | upper}}_USERNAME: ${% raw %}{{ secrets.PYPI_SERVER_USERNAME }}{% endraw %}
UV_INDEX_{{cookiecutter.private_pypi_name | upper}}_PASSWORD: ${% raw %}{{ secrets.PYPI_SERVER_PASSWORD }}{% endraw %}
PYPI_SERVER_USERNAME: ${% raw %}{{ secrets.PYPI_SERVER_USERNAME }}{% endraw %}
PYPI_SERVER_PASSWORD: ${% raw %}{{ secrets.PYPI_SERVER_PASSWORD }}{% endraw %}
{% endif -%}
jobs:
check:
Expand Down Expand Up @@ -58,13 +58,13 @@ jobs:
id: build-container
uses: redhat-actions/buildah-build@v2
with:
image: ${{ github.repository }}-test
tags: test-${{ github.sha }}
image: ${% raw %}{{ github.repository }}{% endraw %}-test
tags: test-${% raw %}{{ github.sha }}{% endraw %}
containerfiles: ./container/Containerfile
platforms: linux/amd64,linux/arm64
{% if cookiecutter.use_private_pypi == "true" -%}
build-args: |-
PYPI_SERVER_USERNAME=${{ env.PYPI_SERVER_USERNAME }}
PYPI_SERVER_PASSWORD=${{ env.PYPI_SERVER_PASSWORD }}
PYPI_SERVER_USERNAME=${% raw %}{{ env.PYPI_SERVER_USERNAME }}{% endraw %}
PYPI_SERVER_PASSWORD=${% raw %}{{ env.PYPI_SERVER_PASSWORD }}{% endraw %}
{% endif -%}
{% endif -%}
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ permissions:
pull-requests: write # 用于创建 PR
jobs:
bump-version:
if: ${{ github.event_name == 'workflow_dispatch' || !startsWith(github.event.head_commit.message, 'bump:') }}
if: ${% raw %}{{ github.event_name == 'workflow_dispatch' || !startsWith(github.event.head_commit.message, 'bump:') }}{% endraw %}
runs-on: ubuntu-latest
name: Bump version and create changelog with commitizen
steps:
- name: Check out
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
token: ${% raw %}{{ secrets.PERSONAL_ACCESS_TOKEN }}{% endraw %}
- name: Create bump and changelog
uses: commitizen-tools/commitizen-action@master
with:
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
github_token: ${% raw %}{{ secrets.PERSONAL_ACCESS_TOKEN }}{% endraw %}
branch: master
increment: ${{ github.event.inputs.increment || '' }}
increment: ${% raw %}{{ github.event.inputs.increment || '' }}{% endraw %}
no_raise: '21'
1 change: 0 additions & 1 deletion repo_scaffold/components/mkdocs/component.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ category: documentation
dependencies: []
conflicts: []
cookiecutter_vars:
use_docs: true
use_mkdocs: true
files:
- src: mkdocs.yml.j2
Expand Down
Loading