A tool to automatically find and apply patch version upgrades for Go modules and npm/yarn packages
Project description
go-patch-it
A tool to automatically find and apply patch version upgrades for npm/yarn packages and Go modules in your repository. Only upgrades patch versions (bugfix releases) within the same major.minor version, avoiding breaking changes.
Features
- Scans all package.json and go.mod files - Works with single repos and monorepos (Yarn/npm workspaces, multiple go.mod files)
- Patch versions only - Only suggests bugfix upgrades, never major or minor bumps
- No pre-releases - Filters out canary, beta, alpha, and RC versions
- Two-stage workflow - Generate a report for review, then apply approved upgrades
- Multi-package manager - Supports Yarn, npm, and Go modules
- Detailed reports - JSON and markdown summaries for easy review
- Optional backups - Can create backups with
--backupflag (default: False, since files are version controlled) - Smart caching - Caches package version data to reduce redundant API calls (6-hour TTL, configurable)
- Go module support - Handles
+incompatibleversions, skips pseudo-versions, preserves// indirectcomments
Alternatives
For npm-only projects, you may want to consider npm-check-updates (ncu), which provides a simpler solution for patch-only updates.
Use go-patch-it if you:
- Need support for Go modules (npm-check-updates only supports npm/yarn)
- Want a two-stage workflow (generate report → review → apply)
- Work with monorepos or multiple package.json/go.mod files
- Prefer detailed JSON/markdown reports for review
Requirements
- Python 3.8+ (no external dependencies required)
yarnornpm(for npm/yarn projects)gocommand (for Go module projects) - must be available in your PATH
Installation
From PyPI (Recommended)
pip install go-patch-it
Then run using:
go-patch-it # Runs both generate and apply
go-patch-it --generate # Generate report only
go-patch-it --apply # Apply upgrades only
go-patch-it --version # Print version
Or use uvx for one-off runs without installing:
uvx go-patch-it
From GitHub Releases
Download the wheel file from the Releases page and install:
pip install go_patch_it-0.1.0-py3-none-any.whl
From Source
git clone https://github.com/Grochocinski/go-patch-it.git
cd go-patch-it
pip install .
Quick Start
Step 1: Generate Upgrade Report
./go-patch-it-generate.py
This will:
- Auto-detect your package manager (Yarn, npm, or Go)
- Scan all
package.jsonorgo.modfiles in your repository - Find available patch version upgrades
- Generate two files:
patch-upgrades.json- Machine-readable JSON reportpatch-upgrades-summary.md- Human-readable markdown summary
Step 2: Review the Report
Open patch-upgrades-summary.md to review all suggested upgrades. You can:
- Research CVEs fixed by these upgrades
- Edit
patch-upgrades.jsonto remove any upgrades you don't want - Verify that all upgrades are patch versions only
Step 3: Apply Upgrades
./go-patch-it-apply.py patch-upgrades.json
This will:
- Apply all upgrades from the report
- Automatically regenerate lockfiles after applying upgrades:
- Go modules: Runs
go mod tidyto regeneratego.sum - npm: Runs
npm installto regeneratepackage-lock.json - Yarn: Runs
yarn install --mode=update-lockfileto regenerateyarn.lock
- Go modules: Runs
- Verify builds after regeneration
- Show a summary of applied, skipped, and failed upgrades
Command-Line Options
go-patch-it-generate.py
Usage: go-patch-it-generate.py [OPTIONS]
OPTIONS:
-r, --root DIR Repository root directory (default: current directory)
-o, --output-dir DIR Output directory for reports (default: current directory)
-p, --package-manager PM Force package manager: yarn, npm, or go (default: auto-detect)
--no-dev Exclude devDependencies
--no-prod Exclude dependencies
--clear-cache Clear the persistent cache file before running
--refresh-cache Alias for --clear-cache
--no-cache Skip using cache for this run only
--cache-ttl HOURS Cache TTL in hours (default: 6.0)
-h, --help Show this help message
go-patch-it-apply.py
Usage: go-patch-it-apply.py [OPTIONS] <upgrade-report.json>
OPTIONS:
-r, --root DIR Repository root directory (default: current directory)
--backup Create backups of package.json files
--dry-run Show what would be changed without making any modifications (skips confirmation prompt)
-h, --help Show this help message
ARGUMENTS:
upgrade-report.json Path to the JSON upgrade report (required)
Examples
Basic Usage
# Generate report in current directory
./go-patch-it-generate.py
# Review the generated files
cat patch-upgrades-summary.md
# Apply the upgrades
./go-patch-it-apply.py patch-upgrades.json
Custom Output Directory
# Generate reports in a specific directory
./go-patch-it-generate.py --output-dir ./reports
# Apply from that directory
./go-patch-it-apply.py ./reports/patch-upgrades.json
Different Repository Root
# Scan a different repository
./go-patch-it-generate.py --root /path/to/other/repo
# Apply upgrades to that repository
./go-patch-it-apply.py --root /path/to/other/repo patch-upgrades.json
Force Package Manager
# Force npm even if yarn.lock exists
./go-patch-it-generate.py --package-manager npm
Exclude Dependency Types
# Only check dependencies (skip devDependencies)
./go-patch-it-generate.py --no-dev
# Only check devDependencies (skip dependencies)
./go-patch-it-generate.py --no-prod
Dry Run (Preview Changes)
# Preview what would be changed without applying
./go-patch-it-apply.py --dry-run patch-upgrades.json
Cache Management
# Clear cache and force fresh fetch
./go-patch-it-generate.py --clear-cache
# Skip cache for this run (doesn't delete cache file)
./go-patch-it-generate.py --no-cache
# Custom cache TTL (12 hours)
./go-patch-it-generate.py --cache-ttl 12
How It Works
-
Package Manager Detection: Automatically detects Yarn, npm, or Go by checking for:
yarn.lockorpackage-lock.json(npm/yarn)go.mod(Go modules)
-
File Detection: Finds all relevant files:
- For npm/yarn: Finds all
package.jsonfiles by reading theworkspacesarray from rootpackage.json(Yarn/npm workspaces) and including the rootpackage.json - For Go: Finds all
go.modfiles recursively in the repository
- For npm/yarn: Finds all
-
Version Analysis: For each dependency:
- Extracts the current version constraint (e.g.,
^1.2.3for npm,v1.2.3for Go) - Determines the major.minor version (e.g.,
1.2) - Queries the package registry/module versions (uses cache when available):
- npm/yarn: Uses
npm viewcommand - Go: Uses
go list -m -mod=readonly -versionscommand (automatically handles vendored dependencies without modifying go.sum)
- npm/yarn: Uses
- Finds the latest patch version within the same major.minor (e.g.,
1.2.5orv1.2.5) - Filters out pre-release versions (anything with
-alpha,-beta,-rc) - For Go: Filters out pseudo-versions (commit-based versions)
- For Go: Handles
+incompatibleversions correctly (preserves suffix) - Caches results to reduce redundant API calls (6-hour TTL by default)
- Extracts the current version constraint (e.g.,
-
Report Generation: Creates a JSON report with all upgrade candidates
-
Safe Application: When applying:
- Creates backups of all modified files (package.json/go.mod and lock files/go.sum)
- Validates current versions match before updating
- Updates dependency files with new versions
- Automatically regenerates lockfiles (go.sum, package-lock.json, yarn.lock)
- Verifies builds (go mod verify, npm ci, yarn install --frozen-lockfile)
- Provides detailed feedback on success/failure
Supported Scenarios
Single package.json or go.mod Repository
Works out of the box - just run the script in your repository root.
Yarn Workspaces
Automatically detects and processes all workspace packages defined in the root package.json:
{
"workspaces": ["packages/*", "apps/*"]
}
npm Workspaces
Same as Yarn workspaces - uses the same workspaces format in package.json.
Go Modules
Automatically detects and processes all go.mod files in the repository. Each go.mod file is processed independently. Supports:
- Multiple
go.modfiles in monorepos - Direct dependencies only (skips
// indirectdependencies) +incompatibleversions (preserves suffix when upgrading)- Skips pseudo-versions (commit-based versions)
- Skips dependencies in
replacedirectives - Skips dependencies in
excludedirectives
Output Files
patch-upgrades.json
JSON array of upgrade objects:
[
{
"package": "express",
"location": "package.json",
"type": "dependencies",
"current": "^4.18.1",
"proposed": "^4.18.3",
"majorMinor": "4.18",
"currentPatch": 1,
"proposedPatch": 3
},
{
"package": "github.com/gin-gonic/gin",
"location": "go.mod",
"type": "require",
"current": "v1.9.1",
"proposed": "v1.9.2",
"majorMinor": "1.9",
"currentPatch": 1,
"proposedPatch": 2
}
]
patch-upgrades-summary.md
Human-readable markdown report with:
- Summary statistics
- Upgrades grouped by package
- Upgrades grouped by location (package.json file)
Safety Features
- Read-only generation: The generate script never modifies files
- Version validation: Apply script verifies current versions match before updating
- Optional backups: Backups can be created with
--backupflag - Patch-only upgrades: Only suggests upgrades within the same major.minor version
- No pre-releases: Filters out unstable versions
Caching
The generate script uses a persistent cache to reduce redundant API calls:
- Cache location:
.go-patch-it-cache.jsonin the go-patch-it repository folder - Default TTL: 6 hours (configurable with
--cache-ttl) - Automatic refresh: Stale entries are refreshed on next access
- Cache management:
--clear-cacheor--refresh-cache: Delete cache and force fresh fetch--no-cache: Skip cache for this run only (doesn't delete file)
- Benefits: Significantly faster runs when scanning many packages, especially in monorepos
Pre-commit Hooks
This project uses pre-commit to automatically run linting and type checking before commits.
Setup
# Install pre-commit (if not already installed)
pip install pre-commit
# or with uv
uv pip install pre-commit
# Install the git hooks
pre-commit install
Usage
Once installed, pre-commit will automatically run on every commit:
- Ruff: Linting (with auto-fix) and formatting checks
- Ty: Type checking
Note: Both hooks use local installations (from your pyproject.toml dev dependencies), ensuring consistency with your project's tool versions.
You can also run manually:
# Run on all files
pre-commit run --all-files
# Run on staged files only
pre-commit run
Bypassing Hooks
If you need to bypass the hooks (not recommended):
git commit --no-verify
Testing
To run tests, first install the test dependencies:
pip install -r requirements-test.txt
Then run the test suite:
# Run all tests
pytest
# Run with coverage report
pytest --cov=. --cov-report=html
# Run specific test file
pytest tests/test_generate.py
# Run specific test
pytest tests/test_generate.py::test_extract_major_minor
# Verbose output
pytest -v
The scripts themselves require no external dependencies - only the tests need pytest and related packages.
Troubleshooting
"Could not detect package manager"
Ensure you have either yarn.lock, package-lock.json, or go.mod in your repository root, or use --package-manager to specify manually.
"No package.json found" or "No go.mod files found"
Run the script from a directory containing a package.json or go.mod file, or use --root to specify the repository root.
Package not found errors
Some packages/modules may not be available in the npm registry or Go module proxy, or may have been unpublished. These will be skipped automatically with a warning.
Go module version discovery failures
If go list -m -versions fails (e.g., for private modules or network issues), the module will be skipped with a warning. The script will continue processing other modules.
Version mismatch warnings
If you see "current version mismatch" warnings when applying, it means the package.json file was modified between generating the report and applying it. Review the changes and regenerate the report if needed.
Vendored Dependencies
If your repository uses vendored dependencies (has a vendor/ directory), the tool automatically handles this by using the -mod=readonly flag when querying the Go module proxy. No additional configuration is needed - the tool will bypass the vendor directory to discover available versions without modifying go.sum.
Go command not found
If you see an error that 'go' command not found in PATH, ensure that:
- Go is installed on your system
- The
gocommand is available in your PATH - You can verify by running:
go version
If Go is installed but not in PATH, you may need to:
- Add Go's bin directory to your PATH environment variable
- Restart your terminal/command prompt
- Check your Go installation documentation for PATH setup instructions
Pseudo-Versions
Go modules sometimes use pseudo-versions (commit-based versions like v0.0.0-20211024170158-b87d35c0b86f or v1.2.1-0.20220228012449-10b1cf09e00b). These are automatically skipped during upgrade detection as they cannot be patch-upgraded in the traditional sense. You'll see a warning message when pseudo-versions are encountered, but processing will continue normally.
License
MIT License - see LICENSE file for details.
Contributing
Contributions welcome! Please feel free to submit issues or pull 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 go_patch_it-0.1.0.post1.tar.gz.
File metadata
- Download URL: go_patch_it-0.1.0.post1.tar.gz
- Upload date:
- Size: 109.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0e80ae38029d03415ea0c2881b444542e64e40863caa57e5cbda706e6e8b801
|
|
| MD5 |
5a2784a889275122897b16c2157da2bd
|
|
| BLAKE2b-256 |
b970140d4a0bd4b99930c4342575c2ebcc1618d9a74b4bf7c8a4586841ff5542
|
Provenance
The following attestation bundles were made for go_patch_it-0.1.0.post1.tar.gz:
Publisher:
release.yml on Grochocinski/go-patch-it
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
go_patch_it-0.1.0.post1.tar.gz -
Subject digest:
d0e80ae38029d03415ea0c2881b444542e64e40863caa57e5cbda706e6e8b801 - Sigstore transparency entry: 854786402
- Sigstore integration time:
-
Permalink:
Grochocinski/go-patch-it@4d2522ec66b6aca4d785ce48d50e21236fa07132 -
Branch / Tag:
refs/tags/v0.1.0.post1 - Owner: https://github.com/Grochocinski
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4d2522ec66b6aca4d785ce48d50e21236fa07132 -
Trigger Event:
release
-
Statement type:
File details
Details for the file go_patch_it-0.1.0.post1-py3-none-any.whl.
File metadata
- Download URL: go_patch_it-0.1.0.post1-py3-none-any.whl
- Upload date:
- Size: 36.8 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 |
d2420fe3a0e21152e9062593f6fe29a2911c464f7ad1e18622a50ffb75a20b7b
|
|
| MD5 |
b596b7bbb1221f00c2939b57350c7406
|
|
| BLAKE2b-256 |
bc23a44c08f509b8b58c115e50d93c334e3b5b517b4212129b486128439f6c37
|
Provenance
The following attestation bundles were made for go_patch_it-0.1.0.post1-py3-none-any.whl:
Publisher:
release.yml on Grochocinski/go-patch-it
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
go_patch_it-0.1.0.post1-py3-none-any.whl -
Subject digest:
d2420fe3a0e21152e9062593f6fe29a2911c464f7ad1e18622a50ffb75a20b7b - Sigstore transparency entry: 854786409
- Sigstore integration time:
-
Permalink:
Grochocinski/go-patch-it@4d2522ec66b6aca4d785ce48d50e21236fa07132 -
Branch / Tag:
refs/tags/v0.1.0.post1 - Owner: https://github.com/Grochocinski
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4d2522ec66b6aca4d785ce48d50e21236fa07132 -
Trigger Event:
release
-
Statement type: