A Pythonic stepfile runner that executes commands from a configuration file.
Project description
:# Stepfile Runner
A Pythonic task runner that executes commands from a simple configuration file called a "Stepfile". Think of it as a lightweight alternative to Makefiles or shell scripts with built-in variable support.
Features
- Simple syntax: Define variables and commands in a clean, readable format
- Variable expansion: Use
$VAR$syntax to reference variables in commands - Shell environment variables: Export variables to command environments with
.shsuffix - Flexible execution: Run commands sequentially or concurrently
- Secure by default: Uses
shlexfor proper command parsing and avoids shell injection
Installation
pip install -e .
Or copy stepfile_runner.py to your project.
Quick Start
Create a file named Stepfile in your project directory:
# Variables
PROJECT_NAME=myapp
VERSION=1.0.0
BUILD_DIR=./build
# Shell environment variable (exported to commands)
PYTHONPATH.sh=/opt/custom/lib
# Commands
echo "Building $PROJECT_NAME$ version $VERSION$"
mkdir -p $BUILD_DIR$
python -m pytest tests/
Run it:
python stepfile_runner.py
Stepfile Syntax
Comments
Lines starting with # are ignored:
# This is a comment
Variable Definitions
Assign variables using NAME=value:
APP_NAME=myproject
PORT=8080
Shell Environment Variables
Variables ending with .sh are exported to the command environment:
PATH.sh=/usr/local/bin:$PATH
DATABASE_URL.sh=postgresql://localhost/mydb
Commands
Any line that isn't a comment or assignment is treated as a command:
npm install
python manage.py migrate
docker build -t $APP_NAME$ .
Variable Expansion
Reference variables using $VARNAME$ syntax:
OUTPUT_DIR=./dist
mkdir -p $OUTPUT_DIR$
cp config.json $OUTPUT_DIR$/config.json
Variables are resolved from:
- Variables defined in the Stepfile
- System environment variables
- If not found, the literal
$VAR$text remains
Usage
As a Library
from stepfile_runner import StepfileRunner
# Parse and run all commands
runner = StepfileRunner("path/to/Stepfile")
runner.parse()
processes = runner.run()
# Wait for all processes to complete
for proc in processes:
proc.wait()
Sequential Execution
Wait for each command to complete before starting the next:
runner = StepfileRunner()
runner.parse()
runner.run(wait_for_completion=True)
Custom Command Execution
Execute specific commands with output capture:
runner = StepfileRunner()
runner.parse()
process = runner.execute_command(
"echo Hello $PROJECT_NAME$",
capture_output=True
)
stdout, stderr = process.communicate()
print(stdout.decode())
Example Stepfile
# Project configuration
PROJECT=webserver
VERSION=2.1.0
BUILD_DIR=./build
DOCKER_REPO=mycompany/images
# Environment setup
FLASK_ENV.sh=production
DATABASE_URL.sh=postgresql://db:5432/prod
# Build pipeline
echo "Starting build for $PROJECT$ v$VERSION$"
python -m pytest --cov=src tests/
python setup.py sdist bdist_wheel
mkdir -p $BUILD_DIR$
cp dist/* $BUILD_DIR$/
docker build -t $DOCKER_REPO$/$PROJECT$:$VERSION$ .
docker push $DOCKER_REPO$/$PROJECT$:$VERSION$
echo "Build complete!"
Logging
The runner uses Python's logging module at DEBUG level. You'll see output like:
12:34:56 [DEBUG] Launched: ['echo', 'Building', 'myapp', 'version', '1.0.0']
12:34:57 [DEBUG] Launched: ['mkdir', '-p', './build']
Error Handling
- Missing Stepfile: Exits with code 100
- Other errors: Exits with code 1
Security Notes
- Commands are parsed with
shlexto prevent shell injection shell=Falseis used in subprocess calls- No arbitrary shell execution
Limitations
- Variable syntax uses
$VAR$(not${VAR}or$VAR) to avoid conflicts - No conditional execution or loops (use Python for complex logic)
- Commands run with
shell=False, so shell features like pipes (|) won't work directly
License
See LICENSE file for details.
Contributing
Contributions welcome! Please submit pull requests or open issues for bugs and feature requests.
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 stepfile_runner-0.1.1.tar.gz.
File metadata
- Download URL: stepfile_runner-0.1.1.tar.gz
- Upload date:
- Size: 3.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/2.0.0 pkginfo/1.12.1.2 requests/2.32.5 setuptools/80.9.0 requests-toolbelt/1.0.0 tqdm/4.67.1 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a8f43b995cedb8d210e42c8fe9bdd7188a6d8497f28a59f8f4bfb61a052dff1
|
|
| MD5 |
68f95b5a3bba4d8ede77d2446bb3aee5
|
|
| BLAKE2b-256 |
260bbb8711d3e02df0ffb7b3a9d24663fea10299da656553f22dfaeb9f3d5121
|
File details
Details for the file stepfile_runner-0.1.1-py3-none-any.whl.
File metadata
- Download URL: stepfile_runner-0.1.1-py3-none-any.whl
- Upload date:
- Size: 3.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/2.0.0 pkginfo/1.12.1.2 requests/2.32.5 setuptools/80.9.0 requests-toolbelt/1.0.0 tqdm/4.67.1 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa67d7b01e44b86c120cb09b2af0996a0806461a8cc852c32756c8d59cfa7aca
|
|
| MD5 |
3cbad9bb284ef04898b92edc16629fc1
|
|
| BLAKE2b-256 |
43f5356babbd434b3308b8caa2581a15cbeacb19593379efc6ce2cc8024ce520
|