c4urself / bump2version

Version-bump your software with a single command
https://pypi.python.org/pypi/bump2version
MIT License
1.05k stars 134 forks source link

New side_effect config option for version parts #193

Closed markmacode closed 1 year ago

markmacode commented 3 years ago

This is a feature that will fulfill #190 which I create a while ago.

Feature description

You can use the side_effect attribute for part bumps inside the bump2version config. This means you can execute your own python code along with the bumping of a part. You can also manually set the version parts, and avoid the default bumping of any part value that you set. Within your project you can store the side_effect functions in any module, although the module needs to be discoverable by python. Meaning that the PYTHONPATH environment variable needs to be set to the project's base directory, or the base directory needs to be in sys.path. You would reference the function similarly to an import statement in python (e.g. package.module.function)

It would be nice to have this feature work out of the box, without the user needing to set PYTHONPATH or sys.path, but I am not aware of a way to work around this.

Example

This example is one that will resolve my issue outlined in #190, and since this gives complete control, that means this solution can avoid the pitfall of the initial reset_with suggestion:

This solution has a pitfall though. If there is a version of 3.8.5-beta.2, if the patch part is not in the reset_with list, then bumping the patch will go from 3.8.5-beta.2 -> 3.8.6-beta.2.

Notice the side_effect inside the [bumpversion:part:patch] config section.

# setup.cfg
[bumpversion]
current_version = 3.8.4
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<pre>[a-z]+)\.(?P<build>\d+))?
serialize = 
    {major}.{minor}.{patch}-{pre}.{build}
    {major}.{minor}.{patch}

[bumpversion:part:patch]
side_effect = mybump.bump_patch

[bumpversion:part:pre]
first_value = alpha
optional_value = gamma
values = 
    alpha
    beta
    rc
    gamma

[bumpversion:part:build]
first_value = 1
# mybump.py
def bump_patch(version):
    version["pre"].value = "gamma"
    version["build"].value = "1"

My custom side effect is being executed and will set the pre and build part of the version manually. The side effect will only get executed for a patch bump, and does not override the bumps of any other part under this config. So a bump2version major will give a version of 4.0.0-alpha.1, which is the default expected behaviour.

My thoughts

I initially started out with a conditional_bump config option, because my use case was to just bump parts conditionally based on other parts. Then I realised that this opens up a lot of custom automation possibilities for people. After implementing this I can also see a way to easily implement something like a pre_bump and a post_bump for executing code before or after a bump - this would open up even more automation possibilities. A pre_bump and post_bump should provide the version values, but not allow the user to change the values, maybe this can be a topic for future discussion.

florisla commented 3 years ago

Hi,

This creative approach allows for a lot of flexibility.

I am a bit worried though about supporting this in the long term. It exposes a part of the internal API of bump2version to the users. Potentially, this makes it harder to change bump2version without breaking user's configurations.