jbuncle / php-autosemver
Installs: 101
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
Type:project
Requires
- php: >=7.2
- nikic/php-parser: ^4@stable
This package is auto-updated.
Last update: 2024-12-05 22:09:49 UTC
README
Still in development, though largely stable
Manage your PHP library versions automatically
Automatically calculates the Semantic Version (SemVer) increment automatically based on source code changes between different Git references (revisions, tags, etc). This increment can then be used to determine the next version number (e.g. using the built in composer-version
command).
Given two Git revisions (or a Working Copy), it will return MAJOR, MINOR or PATCH based on the changes between those revisions, based on Semantic Versioning rules (see https://semver.org/).
This allows the versioning process to be fully automated, where you would otherwise require a manual step to set the version would be required.
There are some edge cases, however automation is probably still better than manually maintaining semantic versions since such processes take time and are prone to human error.
Installation with Composer
Install globally:
composer global require jbuncle/php-autosemver
Basic Usage
With composer
cd <your project> php-autosemver <revision-from> <revision-to>
With docker
cd <your project> docker run -v $(pwd):/app -it --rm jbuncle/php-autosemver <revision-from> <revision-to>
A "revision" can be a commit, tag, branch, HEAD
, or WC
(use working copy).
Examples
Compare your working copy to Git
Run from your the root of your project.
With composer global
php-autosemver --verbosity=1 HEAD WC
With Docker
docker run -v $(pwd):/app -it --rm jbuncle/php-autosemver bash -c "php-autosemver --verbosity=1 HEAD WC"
Useful for checking whether your commit introduces an API breaking change and print out the relevant differences.
Automatically tag current Git revision
Create a Git tag by comparing current revision to last tag.
With composer
# Ensure we have fetched existing tags git fetch --tags # Calculate the version number using php-autosemver LATEST_TAG=$(latesttag); INCREMENT=$(php-autosemver ${LAST_VERSION}); NEW_VERSION=$(composer-version --inc ${LATEST_TAG} ${INCREMENT}); # Create the tag and push it git tag ${NEW_VERSION} git push origin ${NEW_VERSION}
With Docker
# Ensure we have fetched existing tags git fetch --tags # Calculate the version number using php-autosemver docker image NEW_VERSION=$(docker run -it --rm -v $(pwd):/app jbuncle/php-autosemver bash -c '\ LATEST_TAG=$(latesttag);\ INCREMENT=$(php-autosemver ${LATEST_TAG});\ composer-version --inc ${LATEST_TAG} ${INCREMENT}') # Create the tag and push it git tag ${NEW_VERSION} git push origin ${NEW_VERSION}
How it works
The tool parses all the PHP files and generates a list of all the possible, accessible signatures (including variations) found. For Git revisions it will traverse the Git commit directly using the Git CLI (therefore the git
command is required).
Once generated for both sets of changes, it will compare the generated signature strings lists looking for removed signatures (MAJOR change), new signatures (MINOR change) or no signature changes (PATCH).
For example, the following in PHP code:
namespace MyNamespace; class SomeClass { public function aMethod($a, $b = 0) {} }
Would be interpreted into 3 unique signature variations:
\MyNamespace\SomeClass->aMethod(mixed, mixed = 0)
\MyNamespace\SomeClass->aMethod(mixed, mixed)
\MyNamespace\SomeClass->aMethod(mixed)
Known Edge Cases
- Changing method signature to be a variadic will show as breaking change, even if the change is backward compatible.
- Inherited changes as a result of updates to parent classes/traits that exist outside search directory won't be detected
- Adding a constructor with a signature that matches the parent will show as a breaking changes
- Adding a return type that was previously not type hinted will show as a breaking change, even if the type matches what was previously returned (technically this is a breaking changes as method might be overridden and then not match).
- Removing a type parameter will show as breaking change
- Doesn't recognise an addition of a method signature to an interface as a breaking change.
Improvements
- Make more aware of composer
- Inspect composer dependencies (if a dependency has incremented, then this project should match the increment)
- Inspect autoload paths (don't worry about classes that can't/shouldn't be accessed)
- Only bother parsing files that have changed
- Analyse parent classes for additional, inherited signatures
- Treat addition of a signature to an interface as a breaking change
- Ignore change of default values on parameters (these aren't breaking changes)
- Don't treat making abstract class non-abstract as a breaking change
- Subversion (SVN) support