Skip to content

Commit c9cafa2

Browse files
MarioBotDuComptoirDesPharmaciesGeorges Fayedolfinus
authored
adding formatting function for branches (#13)
* adding formatting function for branches Co-authored-by: Georges Faye <[email protected]> Co-authored-by: Martynov Maxim <[email protected]>
1 parent 55b8e70 commit c9cafa2

File tree

2 files changed

+86
-6
lines changed

2 files changed

+86
-6
lines changed

README.md

+78-2
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ setuptools.setup(
281281

282282
When you'll try to get current version in non-master branch, the content of this file will be returned instead.
283283

284-
### Development releases (prereleases) from another branch
284+
### Development releases (prereleases) from `dev` branch
285285

286286
For example, current repo state is:
287287
```
@@ -334,6 +334,79 @@ Then you decided to release new version:
334334
- `N` in `.devN` suffix is a number of commits since the last change of a certain file.
335335
- **Note: every change of this file in the `dev` branch will lead to this `N` suffix to be reset to `0`. Update this file only in the case when you've setting up the next release version!**
336336

337+
338+
### Development releases (prereleases) from any branch (`feature`/`bugfix`/`preview`/`beta`/etc)
339+
340+
Just like previous example, but you want to make development releases (prereleases) with a branch name present in the version number.
341+
342+
In case of branch names which are PEP-440 compatible, you can just use `{branch}` substitution in a version template.
343+
344+
For example, if the branch name is something like `alpha`, `beta`, `preview` or `rc`:
345+
```python
346+
setuptools.setup(
347+
...
348+
version_config={
349+
"count_commits_from_version_file": True,
350+
"dev_template": "{tag}.{branch}{ccount}",
351+
"dirty_template": "{tag}.{branch}{ccount}",
352+
"version_file": VERSION_FILE
353+
},
354+
setup_requires=['setuptools-git-versioning'],
355+
...
356+
)
357+
```
358+
Adding a commit to the `alpha` branch will generate a version number like `1.2.3.alpha4`, new commit to the `beta` branch will generate a version number like `1.2.3.beta5` and so on.
359+
360+
It is also possible to use branch names prefixed with a major version number, like `1.0-alpha` or `1.1.beta`:
361+
```python
362+
setuptools.setup(
363+
...
364+
version_config={
365+
"count_commits_from_version_file": True,
366+
"dev_template": "{branch}{ccount}",
367+
"dirty_template": "{branch}{ccount}",
368+
"version_file": VERSION_FILE
369+
},
370+
setup_requires=['setuptools-git-versioning'],
371+
...
372+
)
373+
```
374+
Adding a commit to the `1.0-alpha` branch will generate a version number like `1.0.alpha2`, new commit to the `1.2.beta` branch will generate a version number like `1.2.beta3` and so on.
375+
376+
But if branch name is not PEP-440 compatible at all, like `feature/ABC-123` or `bugfix/ABC-123`, you'll get version number which `pip` cannot understand.
377+
378+
To fix that you can define a callback which will receive current branch name and return a propery formatted one:
379+
```python
380+
import re
381+
382+
def format_branch_name(name):
383+
# If branch has name like "bugfix/issue-1234-bug-title", take only "1234" part
384+
pattern = re.compile('^(bugfix|feature)\/issue-([0-9]+)-\S+')
385+
386+
match = pattern.search(name)
387+
if not match:
388+
return match.group(2)
389+
390+
# function is called even if branch name is not used in a current template
391+
# just left properly named branches intact
392+
if name == "master":
393+
return name
394+
395+
# fail in case of wrong branch names like "bugfix/issue-title"
396+
raise ValueError(f"Wrong branch name: {name}")
397+
398+
setuptools.setup(
399+
...
400+
version_config={
401+
"dev_template": "{branch}.dev{ccount}",
402+
"dirty_template": "{branch}.dev{ccount}",
403+
"branch_formatter": format_branch_name
404+
},
405+
setup_requires=['setuptools-git-versioning'],
406+
...
407+
)
408+
```
409+
337410
## Options
338411

339412
Default options are:
@@ -348,7 +421,8 @@ setuptools.setup(
348421
"starting_version": "0.0.1",
349422
"version_callback": None,
350423
"version_file": None,
351-
"count_commits_from_version_file": False
424+
"count_commits_from_version_file": False,
425+
"branch_formatter": None
352426
},
353427
...
354428
setup_requires=['setuptools-git-versioning'],
@@ -370,6 +444,8 @@ setuptools.setup(
370444

371445
- `count_commits_from_version_file`: `True` to fetch `version_file` last commit instead of tag commit, `False` otherwise
372446

447+
- `branch_formatter`: callback to be used for formatting a branch name before template substitution
448+
373449
### Substitions
374450

375451
You can use these substitutions in `template`, `dev_template` or `dirty_template` options:

setuptools_git_versioning.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ def parse_config(dist, _, value): # type: (Distribution, Any, Any) -> None
109109
version_callback = value.get('version_callback', None)
110110
version_file = value.get('version_file', None)
111111
count_commits_from_version_file = value.get('count_commits_from_version_file', False)
112+
branch_formatter = value.get('branch_formatter', None)
112113

113114
version = version_from_git(
114115
template=template,
@@ -117,7 +118,8 @@ def parse_config(dist, _, value): # type: (Distribution, Any, Any) -> None
117118
starting_version=starting_version,
118119
version_callback=version_callback,
119120
version_file=version_file,
120-
count_commits_from_version_file=count_commits_from_version_file
121+
count_commits_from_version_file=count_commits_from_version_file,
122+
branch_formatter=branch_formatter
121123
)
122124
dist.metadata.version = version
123125

@@ -133,8 +135,10 @@ def version_from_git(template=DEFAULT_TEMPLATE,
133135
starting_version=DEFAULT_STARTING_VERSION,
134136
version_callback=None,
135137
version_file=None,
136-
count_commits_from_version_file=False
137-
): # type: (str, str, str, str, Optional[Any, Callable], Optional[str], bool) -> str
138+
count_commits_from_version_file=False,
139+
branch_formatter=None,
140+
):
141+
# type: (str, str, str, str, Optional[Any, Callable], Optional[str], bool, Optional[Callable[[str], str]]) -> str
138142

139143
# Check if PKG-INFO exists and return value in that if it does
140144
if os.path.exists('PKG-INFO'):
@@ -171,7 +175,7 @@ def version_from_git(template=DEFAULT_TEMPLATE,
171175
full_sha = head_sha if head_sha is not None else ''
172176
ccount = count_since(tag_sha)
173177
on_tag = head_sha is not None and head_sha == tag_sha and not from_file
174-
branch = get_branch()
178+
branch = get_branch() if branch_formatter is None else branch_formatter(get_branch())
175179

176180
if dirty:
177181
t = dirty_template

0 commit comments

Comments
 (0)