# pp
[](https://github.com/JoshCap20/pp/actions/workflows/test.yml)
[](https://github.com/JoshCap20/pp/actions/workflows/publish.yml)
**A declarative, language-agnostic task runner and build system.**
Stop memorizing different build tools. Define your commands once in `pp.yaml` and run them anywhere.
```bash
pp myapp build    # Build your app
pp myapp test     # Run tests
pp myapp deploy   # Deploy
```
Works with any language: Python, Node.js, Rust, Go, Docker, or shell scripts.
## Why pp?
- ✅ **One interface for everything** - Same commands across all projects
- ✅ **Task dependencies** - Automatic execution ordering (lint → test → build)
- ✅ **Type-safe parameters** - Validated arguments with defaults and constraints
- ✅ **Environment management** - Automatic venv activation, env vars, working directories
- ✅ **Simple & fast** - 1,000 lines of straightforward code, zero dependencies
## Quick Start
**1. Install:**
```bash
pip install ppbuild
```
<details>
<summary>macOS users: click for installation options</summary>
If you get an "externally-managed-environment" error:
```bash
# Option 1: Use pipx (recommended)
brew install pipx
pipx install ppbuild
# Option 2: Use venv
python3 -m venv ~/.pp-env
source ~/.pp-env/bin/activate
pip install ppbuild
```
</details>
**2. Create `pp.yaml`:**
```yaml
applications:
  myapp:
    help: "My awesome application"
    actions:
      build:
        help: "Build the project"
        command: ["cargo", "build", "--release"]
      test:
        help: "Run tests"
        command: ["cargo", "test"]
        depends_on: [build]
      deploy:
        help: "Deploy to production"
        command: ["./deploy.sh"]
        depends_on: [test]
```
**3. Run:**
```bash
pp myapp deploy   # Automatically runs: build → test → deploy
```
## Features
### Task Dependencies
Actions run in the correct order automatically:
```yaml
actions:
  deploy:
    command: ["./deploy.sh"]
    depends_on: [lint, test, build]  # Runs lint → test → build → deploy
```
### Typed Parameters
Add validated, type-safe parameters to your commands:
```yaml
actions:
  run:
    parameters:
      port:
        type: integer
        default: 8000
        min: 1024
        max: 65535
      debug:
        type: boolean
        default: false
    command: ["python", "app.py", "--port", "{port}", "{debug:--debug}"]
```
```bash
pp myapp run --port 3000 --debug
```
### Environment Management
Automatic environment setup:
```yaml
applications:
  backend:
    directory: "~/projects/backend"  # Auto-changes directory
    venv: ".venv"                    # Auto-activates venv
    env_vars:
      DATABASE_URL: "postgresql://localhost/db"
      API_KEY: "${SECRET_API_KEY}"   # Substitutes env vars
    actions:
      # ... your actions
```
### Flexible Configuration
- **Global:** `~/.pp/pp.yaml` for system-wide tools
- **Project:** `./pp.yaml` for project-specific commands
- **Environment:** `.pp.env` for secrets and local overrides
## Examples
**Web Development:**
```yaml
applications:
  web:
    directory: "./frontend"
    actions:
      dev:
        command: ["npm", "run", "dev"]
      build:
        command: ["npm", "run", "build"]
      deploy:
        command: ["vercel", "deploy"]
        depends_on: [build]
```
**Python Project:**
```yaml
applications:
  api:
    venv: ".venv"
    env_vars:
      PYTHONPATH: "./src"
    actions:
      install:
        command: ["pip", "install", "-r", "requirements.txt"]
      test:
        command: ["pytest", "--cov=src"]
        depends_on: [install]
      lint:
        command: ["black", ".", "--check"]
```
**Multi-Service:**
```yaml
applications:
  stack:
    actions:
      up:
        command: ["docker-compose", "up", "-d"]
      logs:
        command: ["docker-compose", "logs", "-f"]
      down:
        command: ["docker-compose", "down"]
```
See [examples/](examples/) for more configurations.
## Documentation
- **[TEMPLATE.md](TEMPLATE.md)** - Complete configuration reference
## Development
```bash
# Clone and install
git clone https://github.com/JoshCap20/pp.git
cd pp
pip install -e .
# Run tests
pytest                           # Run all tests
pytest --cov=lib                # With coverage
# Format and lint
black .
isort .
```
## Architecture
Simple, straightforward Python code. No design patterns, no over-engineering.
```
pp/
├── pp.py              # Main entry point (144 lines)
└── lib/               # Core library (~850 lines)
    ├── config.py      # YAML loading & validation
    ├── params.py      # Parameter handling
    ├── execution.py   # Command execution
    ├── dependencies.py # Dependency resolution
    └── cli.py         # Argument parser
```
**Test coverage:** 72% overall, 99% on core logic
## License
MIT License - see [LICENSE](LICENSE)
## Contributing
Contributions welcome! This project values **simplicity** above all else. Before adding features, consider whether they truly need to exist.
---
**Stop context-switching between build tools. Use `pp`.**
            
         
        Raw data
        
            {
    "_id": null,
    "home_page": "https://github.com/JoshCap20/pp",
    "name": "ppbuild",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "build-system, developer-tools, automation, cli, yaml, cross-platform",
    "author": "Josh Caponigro",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/2c/07/f3ebfdabafe251332ec14e53bee1c205a71a0196cadfe3fb8421d79fa63b/ppbuild-2.0.0.tar.gz",
    "platform": null,
    "description": "# pp\n\n[](https://github.com/JoshCap20/pp/actions/workflows/test.yml)\n[](https://github.com/JoshCap20/pp/actions/workflows/publish.yml)\n\n**A declarative, language-agnostic task runner and build system.**\n\nStop memorizing different build tools. Define your commands once in `pp.yaml` and run them anywhere.\n\n```bash\npp myapp build    # Build your app\npp myapp test     # Run tests\npp myapp deploy   # Deploy\n```\n\nWorks with any language: Python, Node.js, Rust, Go, Docker, or shell scripts.\n\n## Why pp?\n\n- \u2705 **One interface for everything** - Same commands across all projects\n- \u2705 **Task dependencies** - Automatic execution ordering (lint \u2192 test \u2192 build)\n- \u2705 **Type-safe parameters** - Validated arguments with defaults and constraints\n- \u2705 **Environment management** - Automatic venv activation, env vars, working directories\n- \u2705 **Simple & fast** - 1,000 lines of straightforward code, zero dependencies\n\n## Quick Start\n\n**1. Install:**\n\n```bash\npip install ppbuild\n```\n\n<details>\n<summary>macOS users: click for installation options</summary>\n\nIf you get an \"externally-managed-environment\" error:\n\n```bash\n# Option 1: Use pipx (recommended)\nbrew install pipx\npipx install ppbuild\n\n# Option 2: Use venv\npython3 -m venv ~/.pp-env\nsource ~/.pp-env/bin/activate\npip install ppbuild\n```\n</details>\n\n**2. Create `pp.yaml`:**\n\n```yaml\napplications:\n  myapp:\n    help: \"My awesome application\"\n    actions:\n      build:\n        help: \"Build the project\"\n        command: [\"cargo\", \"build\", \"--release\"]\n\n      test:\n        help: \"Run tests\"\n        command: [\"cargo\", \"test\"]\n        depends_on: [build]\n\n      deploy:\n        help: \"Deploy to production\"\n        command: [\"./deploy.sh\"]\n        depends_on: [test]\n```\n\n**3. Run:**\n\n```bash\npp myapp deploy   # Automatically runs: build \u2192 test \u2192 deploy\n```\n\n## Features\n\n### Task Dependencies\n\nActions run in the correct order automatically:\n\n```yaml\nactions:\n  deploy:\n    command: [\"./deploy.sh\"]\n    depends_on: [lint, test, build]  # Runs lint \u2192 test \u2192 build \u2192 deploy\n```\n\n### Typed Parameters\n\nAdd validated, type-safe parameters to your commands:\n\n```yaml\nactions:\n  run:\n    parameters:\n      port:\n        type: integer\n        default: 8000\n        min: 1024\n        max: 65535\n      debug:\n        type: boolean\n        default: false\n    command: [\"python\", \"app.py\", \"--port\", \"{port}\", \"{debug:--debug}\"]\n```\n\n```bash\npp myapp run --port 3000 --debug\n```\n\n### Environment Management\n\nAutomatic environment setup:\n\n```yaml\napplications:\n  backend:\n    directory: \"~/projects/backend\"  # Auto-changes directory\n    venv: \".venv\"                    # Auto-activates venv\n    env_vars:\n      DATABASE_URL: \"postgresql://localhost/db\"\n      API_KEY: \"${SECRET_API_KEY}\"   # Substitutes env vars\n    actions:\n      # ... your actions\n```\n\n### Flexible Configuration\n\n- **Global:** `~/.pp/pp.yaml` for system-wide tools\n- **Project:** `./pp.yaml` for project-specific commands\n- **Environment:** `.pp.env` for secrets and local overrides\n\n## Examples\n\n**Web Development:**\n\n```yaml\napplications:\n  web:\n    directory: \"./frontend\"\n    actions:\n      dev:\n        command: [\"npm\", \"run\", \"dev\"]\n      build:\n        command: [\"npm\", \"run\", \"build\"]\n      deploy:\n        command: [\"vercel\", \"deploy\"]\n        depends_on: [build]\n```\n\n**Python Project:**\n\n```yaml\napplications:\n  api:\n    venv: \".venv\"\n    env_vars:\n      PYTHONPATH: \"./src\"\n    actions:\n      install:\n        command: [\"pip\", \"install\", \"-r\", \"requirements.txt\"]\n      test:\n        command: [\"pytest\", \"--cov=src\"]\n        depends_on: [install]\n      lint:\n        command: [\"black\", \".\", \"--check\"]\n```\n\n**Multi-Service:**\n\n```yaml\napplications:\n  stack:\n    actions:\n      up:\n        command: [\"docker-compose\", \"up\", \"-d\"]\n      logs:\n        command: [\"docker-compose\", \"logs\", \"-f\"]\n      down:\n        command: [\"docker-compose\", \"down\"]\n```\n\nSee [examples/](examples/) for more configurations.\n\n## Documentation\n\n- **[TEMPLATE.md](TEMPLATE.md)** - Complete configuration reference\n\n## Development\n\n```bash\n# Clone and install\ngit clone https://github.com/JoshCap20/pp.git\ncd pp\npip install -e .\n\n# Run tests\npytest                           # Run all tests\npytest --cov=lib                # With coverage\n\n# Format and lint\nblack .\nisort .\n```\n\n## Architecture\n\nSimple, straightforward Python code. No design patterns, no over-engineering.\n\n```\npp/\n\u251c\u2500\u2500 pp.py              # Main entry point (144 lines)\n\u2514\u2500\u2500 lib/               # Core library (~850 lines)\n    \u251c\u2500\u2500 config.py      # YAML loading & validation\n    \u251c\u2500\u2500 params.py      # Parameter handling\n    \u251c\u2500\u2500 execution.py   # Command execution\n    \u251c\u2500\u2500 dependencies.py # Dependency resolution\n    \u2514\u2500\u2500 cli.py         # Argument parser\n```\n\n**Test coverage:** 72% overall, 99% on core logic\n\n## License\n\nMIT License - see [LICENSE](LICENSE)\n\n## Contributing\n\nContributions welcome! This project values **simplicity** above all else. Before adding features, consider whether they truly need to exist.\n\n---\n\n**Stop context-switching between build tools. Use `pp`.**\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A declarative, language-agnostic build system and utility manager",
    "version": "2.0.0",
    "project_urls": {
        "Bug Tracker": "https://github.com/JoshCap20/pp/issues",
        "Documentation": "https://github.com/JoshCap20/pp/blob/main/TEMPLATE.md",
        "Homepage": "https://github.com/JoshCap20/pp",
        "Source Code": "https://github.com/JoshCap20/pp"
    },
    "split_keywords": [
        "build-system",
        " developer-tools",
        " automation",
        " cli",
        " yaml",
        " cross-platform"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9d97266436dd08ed39ee400f3032b6068e6815a47cbb0ee692372f76d9ddd914",
                "md5": "18bcde066e6f9c76745a6341e0efa570",
                "sha256": "4b0f96a436bdf3775bc2bd2addf61e2367cfc53e262b45b6fc4b3087946d56ff"
            },
            "downloads": -1,
            "filename": "ppbuild-2.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "18bcde066e6f9c76745a6341e0efa570",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 15220,
            "upload_time": "2025-10-21T06:42:18",
            "upload_time_iso_8601": "2025-10-21T06:42:18.324287Z",
            "url": "https://files.pythonhosted.org/packages/9d/97/266436dd08ed39ee400f3032b6068e6815a47cbb0ee692372f76d9ddd914/ppbuild-2.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2c07f3ebfdabafe251332ec14e53bee1c205a71a0196cadfe3fb8421d79fa63b",
                "md5": "32f7d4e579850d764397798bfe64b350",
                "sha256": "1de2ffffa9f7f66390bb03c660a4678b34b0c27a30ad0d9d9e378e358818e165"
            },
            "downloads": -1,
            "filename": "ppbuild-2.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "32f7d4e579850d764397798bfe64b350",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 20428,
            "upload_time": "2025-10-21T06:42:19",
            "upload_time_iso_8601": "2025-10-21T06:42:19.912765Z",
            "url": "https://files.pythonhosted.org/packages/2c/07/f3ebfdabafe251332ec14e53bee1c205a71a0196cadfe3fb8421d79fa63b/ppbuild-2.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-21 06:42:19",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "JoshCap20",
    "github_project": "pp",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "ppbuild"
}