Python Makefile - Simple command orchestration through Makefile.py
Project description
Python Makefile (pmake)
Using Makefiles for project command orchestration is becoming more common.
However often writing logic in bash is a pain - pmake allows writing everything in Python using the powerful amoffat/sh library.
Note: Python Makefile (pmake) is not for building CLIs, just a simple way to run orchestration within your project.
Overview
# Create a Makefile.py in your project directory (see guidance with pmake when no file exists)
# Run the default command from your Makefile.py
pmake
# Run specific command directly
pmake build_images
pmake status
pmake build_and_push
# Pass parameters and override environment variables
pmake build_images IMAGE=myapp VERSION=1.0.0
Example:
Content in Makefile.py
from pmake import sh, _, dep
from pmake import docker, git, echo # Direct command imports
# Read from env
DOCKER_REPO = _('DOCKER_REPO')
IMAGE = _('IMAGE')
VERSION = _('VERSION', "0.0.1") # Default value
def build_images():
# Use sh object - automatically inherits environment including venv
sh.docker("build", "-f", "./docker/Dockerfile", ".",
"-t", f"{DOCKER_REPO}/{IMAGE}:{VERSION}")
def push_images():
# Use direct command imports - environment variables from _() automatically available
docker("push", f"{DOCKER_REPO}/{IMAGE}:{VERSION}")
def status():
# All commands automatically use your current shell environment
git("status")
echo(f"Build completed for {IMAGE} v{VERSION}!")
@dep(build_images, push_images)
def build_and_push():
pass
Run commands
# Runs the default command (first alphabetically: build_and_push in this case)
pmake
# Run specific commands directly
pmake build_images
pmake push_images
pmake status
# Runs build_and_push (with dependencies: build_images, push_images)
pmake build_and_push
# Run with parameter overrides
pmake build_and_push IMAGE="myimage" VERSION="2.0.0"
# See all available commands with descriptions and dependencies
pmake --help
Getting Started
Creating Your First Makefile.py
When you run pmake in a directory without a Makefile.py, it will show helpful guidance. Here's a simple starter example:
from pmake import sh, _, dep
from pmake import echo, python, pip
def hello():
'''Say hello - this will be your default command'''
echo('Hello from pmake!')
def test():
'''Run tests'''
python('-m', 'pytest')
@dep(test)
def deploy():
'''Deploy after running tests'''
echo('Deploying application...')
Then run:
pmake- Runs default command (hello in this case)pmake test- Runs test commandpmake deploy- Runs test, then deploy (due to @dep dependency)pmake --help- Shows all available commands with descriptions and dependencies
Features
Universal Command Imports
Import any shell command directly from pmake:
from pmake import docker, git, echo, ls, grep, curl, wget, find
# Equivalent to: from sh import docker, git, echo, ls, grep, curl, wget, find
# Use them directly
docker("build", "-t", "myapp", ".")
git("commit", "-m", "Update")
echo("Hello World")
Powerful Shell Execution with Automatic Environment Inheritance
pmake uses the amoffat/sh library under the hood with enhanced environment management:
- Automatic virtual environment inheritance: Commands use your current venv
- Environment variable tracking: Variables accessed via
_()are automatically available to shell commands - Parameter override inheritance: CLI
PARAM=valueoverrides are passed to all shell commands - Better error handling and superior command composition
- Rich command objects with piping support
No more _env=os.environ needed! All pmake shell commands automatically include:
- Your current shell environment (including PATH, VIRTUAL_ENV, etc.)
- Any environment variables accessed through
_()calls - Any parameter overrides from the command line
Automatic Environment Inheritance
All shell commands automatically inherit your environment:
from pmake import sh, python, pip, _
# Environment variables accessed via _() are tracked
VENV_PATH = _('VIRTUAL_ENV')
PROJECT_NAME = _('PROJECT_NAME', 'myproject')
def setup_venv():
# python command automatically uses current virtual environment
python("-m", "pip", "install", "-e", ".")
# No need for _env=os.environ - it's automatic!
pip("install", "pytest", "black", "mypy")
def test():
# All environment variables from _() calls are available
python("-c", f"print('Testing {PROJECT_NAME}')")
Both Syntaxes Supported
from pmake import sh, docker
# Option 1: Direct imports (automatically inherit environment)
docker("build", "-t", "myapp", ".")
# Option 2: Through sh object (automatically inherit environment)
sh.docker("build", "-t", "myapp", ".")
# Complex shell operations (with full environment)
sh.bash("-c", "docker build . | grep 'Successfully built'")
Equivalent makefile
IMAGE ?= $(IMAGE)
DOCKER_REPO ?= $(DOCKER_REPO)
VERSION ?= $(VERSION)
build_images:
docker build -f ./docker/Dockerfile . \
-t $(DOCKER_REPO)/$(IMAGE):$(VERSION)
push_images:
docker push $(DOCKER_REPO)/$(IMAGE):$(VERSION)
build_and_push: build_images, push_images
Migration from bash()
The old bash() function has been removed in favor of direct command usage:
# OLD (removed)
bash("echo hello")
bash("docker build -t myapp .")
# NEW - Direct imports
from pmake import echo, docker
echo("hello")
docker("build", "-t", "myapp", ".")
# NEW - sh object
from pmake import sh
sh.echo("hello")
sh.docker("build", "-t", "myapp", ".")
Project details
Release history Release notifications | RSS feed
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 python_pmake-0.1.0.tar.gz.
File metadata
- Download URL: python_pmake-0.1.0.tar.gz
- Upload date:
- Size: 19.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
abc6b7f971d4e57a9e15299deee65c084d99365201955abfaf5937be2cb90ab7
|
|
| MD5 |
742b8be9eac5913d5dfcfaa35eb2349a
|
|
| BLAKE2b-256 |
8cb386e981495467560ad732900515929f1a15d4ce10bc2a6c526606ec404118
|
File details
Details for the file python_pmake-0.1.0-py3-none-any.whl.
File metadata
- Download URL: python_pmake-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0837fb8ba5f7aae388976fb360de22780693649ef350979a2d97d67e94f0f610
|
|
| MD5 |
28a490f70b06574618bf758ef94bd937
|
|
| BLAKE2b-256 |
920e21d94853cd85b43294a9f825bde6946010c4006fa1c9ab430c3f575d23ae
|