SAFE is a command-line tool written in Go that helps you determine if upgrading a package in your project is safe. It analyzes two different versions of a package (the one you're currently using and the one you want to upgrade to), and based on how you're using the package in your codebase, it tells you whether the upgrade is likely to cause breaking changes.
SAFE takes the following inputs:
- Ecosystem: The package ecosystem you're working with (e.g.,
pypi,npm,go modules). - Package Name: The name of the package you want to evaluate.
- Current Version: The version of the package you are currently using.
- New Version: The version of the package you want to upgrade to.
- Package Usage: A description of how you are using the package in your codebase. This includes filenames and the specific functions, methods, classes, types, or interfaces you are using.
SAFE then performs the following steps:
- Clones the package's repository.
- Checks out the
current versionof the package. - Analyzes the source code of the
current versionto understand the APIs you are using. - Checks out the
new versionof the package. - Compares the APIs you are using in the
current versionwith thenew versionto identify any breaking changes.
SAFE provides the following exit codes to indicate the compatibility of the new package version:
exit 0: Safe to upgrade. The new version is backward-compatible with your current usage.exit 1: Safe to upgrade with minor changes. The new version has some minor breaking changes that will require small modifications to your code (e.g., renaming a function, changing a function signature).exit 2: Unsafe to upgrade. The new version has significant breaking changes that will require a major refactoring of your code.
safe --ecosystem <ecosystem> --package <package-name> --from <current-version> --to <new-version> --usage <usage-file> [--deep] [--diff-output-dir <dir>] [--diff-output-single-file <file>]--deep: Perform a deep, AST-based analysis of API changes. Without this flag, SAFE only performs a file-level diff.--diff-output-dir <dir>: If changes are detected, write the diff for each changed file to a separate file in the specified directory. The original file paths are sanitized by replacing path separators (like/) with underscores (e.g., a diff forsrc/api/client.gowill be saved assrc_api_client.go.diff).--diff-output-single-file <file>: If changes are detected, write the combined diff for all changed files to a single specified file.
The usage-file is a JSON file that describes how you are using the package in your codebase. Here is an example:
{
"files": [
{
"path": "src/main.go",
"uses": [
{
"type": "function",
"name": "DoSomething"
},
{
"type": "interface",
"name": "MyInterface"
}
]
}
]
}Contributions are welcome! Please feel free to submit a pull request or open an issue on GitHub.
This project is licensed under the MIT License. See the LICENSE file for details.
