1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
# Silver-Platter Codemod Protocol v1
This document describes how to write codemods (automated code modification scripts) that work with Silver-Platter.
## Overview
Codemods are commands that Silver-Platter runs in version control checkouts to make automated changes. Your codemod can be written in any language and should:
1. Make changes to files in the working directory
2. Optionally commit those changes (or let Silver-Platter handle it)
3. Exit with appropriate status codes
4. Optionally write metadata about the changes
## How Codemods Are Executed
Silver-Platter runs your codemod in a clean VCS checkout. You can:
- **Make and commit changes yourself** - Full control over the commit process
- **Just make changes** - Silver-Platter will auto-commit with a reasonable message
- **Make no changes** - Exit successfully to indicate no changes were needed
By default, uncommitted changes are discarded (with a warning). Use `--autocommit` to have Silver-Platter commit them automatically.
## Configuration Options
These can be specified via command-line flags or in a recipe file:
| Option | Description | Default |
|--------|-------------|---------|
| `name` | Codemod identifier | Filename |
| `command` | Command to execute | Required |
| `commit-message` | Template for commit messages (Jinja2) | Auto-generated |
| `description` | Merge proposal description (Jinja2, markdown/plain) | Auto-generated |
| `resume` | Whether the command supports resuming | `false` |
| `mode` | How to publish changes: `push`, `attempt-push`, `propose` | `attempt-push` |
| `propose-threshold` | Minimum change value before creating proposals | None |
| `autocommit` | Auto-commit uncommitted changes | `true` |
| `target-branch-url` | Override target branch URL | Base URL |
## Exit Codes
- **0**: Success (changes made or no changes needed)
- **1**: Failure (branch will be discarded)
- **Other**: Treated as failure
## Resuming Previous Runs
If your codemod supports resuming (set `resume: true` in config):
1. Silver-Platter may provide a previous branch to continue from
2. The `SVP_RESUME` environment variable will point to a JSON file with metadata from the last run
3. Your codemod should read this metadata and continue where it left off
4. Carry forward any relevant context from the previous run
If resuming is not supported, previous changes are discarded and may be recreated.
## Environment Variables
### Always Set
| Variable | Description | Example |
|----------|-------------|---------||
| `SVP_API` | Silver-Platter API version | `1` |
| `SVP_RESULT` | Path where your codemod should write result JSON | `/tmp/svp-result.json` |
### Conditionally Set
| Variable | Description | When Set |
|----------|-------------|----------|
| `COMMITTER` | Git committer identity | If configured |
| `SVP_RESUME` | Path to previous run's result JSON | If resuming and available |
## Result JSON Format
Write a JSON file to the path specified in `SVP_RESULT` with these fields:
### Required Fields
| Field | Type | Description |
|-------|------|-------------|
| `code` | string | Result code (see below) |
### Result Codes
- `success` - Changes were successfully made
- `nothing-to-do` - No changes were needed
- Other values indicate specific error types
### Optional Fields
| Field | Type | Description |
|-------|------|-------------|
| `transient` | boolean | Whether the error is temporary (e.g., network issue) |
| `stage` | array | Stage names where the codemod failed |
| `description` | string | One-line description of changes or error |
| `value` | integer | Relative importance of changes (for prioritization) |
| `tags` | array | Tags to apply to the change |
| `context` | object | Custom data for template expansion |
| `target-branch-url` | string | Override target branch URL |
### Example Result JSON
```json
{
"code": "success",
"description": "Updated 5 deprecated API calls",
"value": 50,
"tags": ["api-migration", "automated"],
"context": {
"files_changed": 5,
"apis_updated": ["oldAPI", "legacyAPI"]
}
}
```
## Debian-Specific Operations
For Debian packages, additional features are available:
### Branch Naming
Branches follow [DEP-14](https://dep-team.pages.debian.net/deps/dep14/) conventions.
### Additional Environment Variables
| Variable | Description | Values |
|----------|-------------|--------|
| `DEB_SOURCE` | Source package name | e.g., `nginx` |
| `DEB_UPDATE_CHANGELOG` | Whether to update debian/changelog | `update`/`leave` |
| `ALLOW_REFORMATTING` | Whether reformatting is allowed | `true`/`false` |
## Complete Example
Here's a simple codemod that updates deprecated function calls:
```bash
#!/bin/bash
# update-deprecated-api.sh
# Check if we should resume
if [ -n "$SVP_RESUME" ] && [ -f "$SVP_RESUME" ]; then
echo "Resuming from previous run..."
# Load previous state
PROCESSED_FILES=$(jq -r '.context.processed_files[]' "$SVP_RESUME" 2>/dev/null || echo "")
fi
# Make changes
CHANGED_COUNT=0
for file in $(find . -name "*.py" -type f); do
if grep -q "old_function" "$file"; then
sed -i 's/old_function/new_function/g' "$file"
((CHANGED_COUNT++))
fi
done
# Write result
if [ $CHANGED_COUNT -gt 0 ]; then
cat > "$SVP_RESULT" <<EOF
{
"code": "success",
"description": "Updated $CHANGED_COUNT files to use new API",
"value": $((CHANGED_COUNT * 10)),
"context": {
"files_changed": $CHANGED_COUNT
}
}
EOF
git add -A
git commit -m "Replace old_function with new_function
This updates deprecated API calls to use the new function name.
Affected files: $CHANGED_COUNT"
exit 0
else
cat > "$SVP_RESULT" <<EOF
{
"code": "nothing-to-do",
"description": "No deprecated API calls found"
}
EOF
exit 0
fi
```
|