Unified CLI to scaffold, build, test, lint, and document Python and R packages
Project description
pkrr
Unified CLI to scaffold, build, test, lint, and document Python and R packages from a single, consistent workflow.
Why pkrr?
Many packages exist in both R and Python — either as ports of each other or as parallel implementations for different audiences. Data science teams often use R for analysis and Python for production, while community projects like ggplot2/plotnine, tidyverse/pyjanitor, and bioconductor/scanpy show how common cross-language packaging is.
Maintaining packages in both languages means juggling two build systems, two test frameworks, two sets of linting rules, and two version files. One wrong step and your versions drift, your metadata is inconsistent, or your CI only tests one language.
pkrr solves this by:
- Unifying your workflow — one CLI for build, test, lint, docs, and versioning across both languages
- Preventing version drift — bump the version once and it propagates to
pyproject.tomlandDESCRIPTIONautomatically - Scaffolding quickly — generate a ready-to-run package skeleton for either language in seconds
- Checking your environment —
pkrr doctortells you exactly what tools you're missing before you start
If you maintain a package in both Python and R, or you're porting one to the other, pkrr keeps everything in sync from a single pkg.yaml manifest.
Install
# Run without installing (recommended)
uvx pkrr
# Install into current environment
uv pip install pkrr
# Install as a standalone CLI tool
uv tool install pkrr
# Developer install from source
git clone https://github.com/<owner>/pkrr.git
cd pkrr
uv pip install -e .
Quick start
# Initialize in current directory (prompts for name, scaffolds all files)
pkrr init
# Or with options
pkrr init --name my-package --languages python,r
# Scaffold a new Python package (creates directory)
pkrr new python my-package
# Scaffold a new R package
pkrr new r my-r-package
Commands
| Command | Description |
|---|---|
pkrr init |
Create pkg.yaml and scaffold project files in current directory |
pkrr new <lang> <name> |
Scaffold a new package in a new directory |
pkrr build |
Build artifacts for the package(s) |
pkrr test |
Run tests for the package(s) |
pkrr lint |
Run linters for the package(s) |
pkrr docs |
Build documentation for the package(s) |
pkrr version |
Bump or set the version and propagate to ecosystem files |
pkrr doctor |
Diagnose local environment for Python and R tooling |
Most commands accept a --lang flag to restrict operations to a single language.
Usage
Scaffold a new package
# Use pkrr init in an empty directory to create pkg.yaml and scaffold files there
# Use pkrr new to create a new directory with the package
pkrr new python my-lib # creates my-lib/ with pyproject.toml, src/, tests/, docs/
pkrr new r my-r-lib # creates my-r-lib/ with DESCRIPTION, R/, tests/, NAMESPACE
pkrr new python my-lib --template minimal # specify a template (default: minimal)
Initialize a project
# Interactive mode (prompts for package name)
pkrr init
# With options
pkrr init --name my-project --version 1.0.0 --license MIT --languages python,r
This creates a pkg.yaml manifest and scaffolds project files for all specified languages in the current directory.
Build, test, lint, docs
pkrr build # python: python -m build; R: R CMD build .
pkrr test # python: pytest; R: testthat::test_local()
pkrr lint # python: ruff + black; R: lintr::lint_package()
pkrr docs # python: mkdocs; R: pkgdown::build_site()
# Restrict to one language in a multi-language project
pkrr build --lang python
pkrr test --lang r
Version management
pkrr version patch # 0.1.0 -> 0.1.1
pkrr version minor # 0.1.1 -> 0.2.0
pkrr version major # 0.2.0 -> 1.0.0
pkrr version --set 2.0.0 # set exact version
pkrr version patch --dry-run # show what would change without writing
pkrr version patch --no-propagate # update pkg.yaml only, skip ecosystem files
pkrr version patch --lang python # propagate only to Python ecosystem files
Version changes are propagated to language-specific files automatically:
- Python: updates
versioninpyproject.toml - R: updates
VersioninDESCRIPTION
Diagnose environment
pkrr doctor
Checks for required tooling (Python, pip, pytest, ruff, black, mkdocs, R, Rscript, testthat, lintr, pkgdown, pandoc) and reports what is missing.
The manifest (pkg.yaml)
pkrr uses a pkg.yaml file as the single source of truth for package metadata. Example:
name: my-package
version: 0.1.0
license: MIT
description: My awesome package
languages:
- python
- r
authors:
- name: Jane Doe
email: jane@example.com
keywords:
- data
python:
build_backend: hatchling
requires: []
r:
depends: []
docs:
python: mkdocs
r: pkgdown
ci:
provider: none
release_on_tag: false
Supported languages
| Language | Build | Test | Lint | Docs | Version propagation |
|---|---|---|---|---|---|
| Python | python -m build |
pytest |
ruff, black |
mkdocs |
pyproject.toml |
| R | R CMD build |
testthat |
lintr |
pkgdown |
DESCRIPTION |
Dependencies
- Python >= 3.9
- typer, pydantic, PyYAML, Jinja2 (installed automatically)
Per-language tooling (pytest, ruff, R, etc.) must be installed separately. Run pkrr doctor to check what you need.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pkrr-1.0.0.tar.gz.
File metadata
- Download URL: pkrr-1.0.0.tar.gz
- Upload date:
- Size: 11.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08c83665ca2ed9eadfa8e4ddfbfc9db7eccc8895fc83cd481da83a7d547fdb10
|
|
| MD5 |
efebdd87b6febb9f6eb55d7e7ed4e303
|
|
| BLAKE2b-256 |
6f9cd11867bce8236ef0f3b31de8a16328be0021bcee66016296e5b22a485d63
|
Provenance
The following attestation bundles were made for pkrr-1.0.0.tar.gz:
Publisher:
publish.yml on nortelabs/pkrr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pkrr-1.0.0.tar.gz -
Subject digest:
08c83665ca2ed9eadfa8e4ddfbfc9db7eccc8895fc83cd481da83a7d547fdb10 - Sigstore transparency entry: 1201397887
- Sigstore integration time:
-
Permalink:
nortelabs/pkrr@b8cb5e56601748f51219f39e53ff2fcd58a8bbe3 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/nortelabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b8cb5e56601748f51219f39e53ff2fcd58a8bbe3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pkrr-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pkrr-1.0.0-py3-none-any.whl
- Upload date:
- Size: 19.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a9db77f3240138f329d2145926451e18a2cb0b26c7d310b9b3ab70989b2cd5b
|
|
| MD5 |
144b0602528a6b84ac60594fdd9a71ee
|
|
| BLAKE2b-256 |
9fda2bc0e7974a7f841fc2f5d568fa63f99175344e61fbe3d12800c3c378f7a0
|
Provenance
The following attestation bundles were made for pkrr-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on nortelabs/pkrr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pkrr-1.0.0-py3-none-any.whl -
Subject digest:
0a9db77f3240138f329d2145926451e18a2cb0b26c7d310b9b3ab70989b2cd5b - Sigstore transparency entry: 1201398133
- Sigstore integration time:
-
Permalink:
nortelabs/pkrr@b8cb5e56601748f51219f39e53ff2fcd58a8bbe3 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/nortelabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b8cb5e56601748f51219f39e53ff2fcd58a8bbe3 -
Trigger Event:
push
-
Statement type: