Skip to content

Commit be81639

Browse files
Refactored versioning (#19)
* fix bug * refactored versioning Co-authored-by: Monty Bot <[email protected]>
1 parent f577ebb commit be81639

File tree

7 files changed

+189
-83
lines changed

7 files changed

+189
-83
lines changed

continuous_delivery_scripts/generate_news.py

Lines changed: 7 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
import logging
1010
import os
1111
import subprocess
12-
from auto_version import auto_version_tool
13-
from continuous_delivery_scripts.utils.definitions import CommitType
14-
from continuous_delivery_scripts.utils.git_helpers import LocalProjectRepository
12+
from continuous_delivery_scripts.utils.versioning import calculate_version, determine_version_string
13+
from typing import Optional, Tuple, Dict
14+
1515
from continuous_delivery_scripts.utils.configuration import configuration, ConfigurationVariable
16-
from continuous_delivery_scripts.utils.logging import log_exception, set_log_level
16+
from continuous_delivery_scripts.utils.definitions import CommitType
1717
from continuous_delivery_scripts.utils.filesystem_helpers import cd
18-
from typing import Optional, Tuple, Dict
18+
from continuous_delivery_scripts.utils.logging import log_exception, set_log_level
1919

2020
logger = logging.getLogger(__name__)
2121

@@ -31,87 +31,11 @@ def version_project(commit_type: CommitType) -> Tuple[bool, Optional[str], Dict[
3131
(is new version, the new version)
3232
"""
3333
use_news_files = commit_type in [CommitType.BETA, CommitType.RELEASE]
34-
is_new_version, new_version, version_elements = _calculate_version(commit_type, use_news_files)
34+
is_new_version, new_version, version_elements = calculate_version(commit_type, use_news_files)
3535
_generate_changelog(new_version, use_news_files)
3636
return is_new_version, new_version, version_elements
3737

3838

39-
def _calculate_version(commit_type: CommitType, use_news_files: bool) -> Tuple[bool, Optional[str], Dict[str, str]]:
40-
"""Calculates the version for the release.
41-
42-
eg. "0.1.2"
43-
44-
Args:
45-
commit_type:
46-
use_news_files: Should the version be dependant on changes recorded in news files
47-
48-
Returns:
49-
Tuple containing
50-
a flag stating whether it is a new version or not
51-
A semver-style version for the latest release
52-
"""
53-
BUMP_TYPES = {CommitType.DEVELOPMENT: "build", CommitType.BETA: "prerelease"}
54-
is_release = commit_type == CommitType.RELEASE
55-
enable_file_triggers = True if use_news_files else None
56-
bump = BUMP_TYPES.get(commit_type)
57-
project_config_path = configuration.get_value(ConfigurationVariable.PROJECT_CONFIG)
58-
new_version: Optional[str] = None
59-
is_new_version: bool = False
60-
with cd(os.path.dirname(project_config_path)):
61-
old, new_version, updates = auto_version_tool.main(
62-
release=is_release,
63-
enable_file_triggers=enable_file_triggers,
64-
commit_count_as=bump,
65-
config_path=project_config_path,
66-
)
67-
# Autoversion second returned value is not actually the new version
68-
# There seem to be a bug in autoversion.
69-
# This is why the following needs to be done to determine the version
70-
version_elements = _get_version_elements(updates)
71-
new_version = version_elements.get(auto_version_tool.Constants.VERSION_FIELD, new_version)
72-
is_new_version = old != new_version
73-
logger.info(":: Determining the new version")
74-
logger.info(f"Version: {new_version}")
75-
return is_new_version, new_version, version_elements
76-
77-
78-
def _update_version_string(
79-
commit_type: CommitType, new_version: Optional[str], version_elements: Dict[str, str]
80-
) -> Optional[str]:
81-
"""Updates the version string for development releases.
82-
83-
Args:
84-
commit_type: commit type
85-
new_version: the new version
86-
version_elements: version elements
87-
"""
88-
if commit_type == CommitType.DEVELOPMENT:
89-
commit_count = version_elements.get(auto_version_tool.Constants.COMMIT_COUNT_FIELD)
90-
if not commit_count:
91-
with LocalProjectRepository() as git:
92-
commit_count = git.get_commit_count()
93-
return "%s-%s.%s+%s" % (
94-
new_version,
95-
auto_version_tool.config.BUILD_TOKEN,
96-
commit_count,
97-
version_elements.get(auto_version_tool.Constants.COMMIT_FIELD),
98-
)
99-
return new_version
100-
101-
102-
def _get_version_elements(native_version_elements: Dict[str, str]) -> Dict[str, str]:
103-
"""Determines the different version elements.
104-
105-
Args:
106-
native_version_elements: native version elements as understood by autoversion
107-
"""
108-
return {
109-
key: native_version_elements[native]
110-
for native, key in auto_version_tool.config.key_aliases.items()
111-
if native in native_version_elements
112-
}
113-
114-
11539
def _generate_changelog(version: Optional[str], use_news_files: bool) -> None:
11640
"""Creates a towncrier log of the release.
11741
@@ -141,7 +65,7 @@ def main() -> None:
14165
try:
14266
commit_type = CommitType.parse(args.release_type)
14367
is_new_version, new_version, version_elements = version_project(commit_type)
144-
version_to_print = _update_version_string(commit_type, new_version, version_elements)
68+
version_to_print = determine_version_string(commit_type, new_version, version_elements)
14569
print(version_to_print)
14670
except Exception as e:
14771
log_exception(logger, e)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#
2+
# Copyright (C) 2020-2021 Arm Limited or its affiliates and Contributors. All rights reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
"""Determine the project new version."""
6+
import sys
7+
8+
import argparse
9+
import logging
10+
from continuous_delivery_scripts.utils.versioning import calculate_version, determine_version_string
11+
12+
from continuous_delivery_scripts.utils.definitions import CommitType
13+
from continuous_delivery_scripts.utils.logging import log_exception, set_log_level
14+
15+
logger = logging.getLogger(__name__)
16+
17+
18+
def get_project_version_string(commit_type: CommitType) -> str:
19+
"""Determine the project version string.
20+
21+
Args:
22+
commit_type: states what is the type of the commit
23+
24+
25+
Returns:
26+
(is new version, the new version)
27+
"""
28+
use_news_files = commit_type in [CommitType.BETA, CommitType.RELEASE]
29+
_, new_version, version_elements = calculate_version(commit_type, use_news_files)
30+
version_string = determine_version_string(commit_type, new_version, version_elements)
31+
return version_string
32+
33+
34+
def main() -> None:
35+
"""Handle command line arguments to determine version string."""
36+
parser = argparse.ArgumentParser(description="Determine project's version.")
37+
parser.add_argument(
38+
"-t", "--release-type", help="type of release to perform", required=True, type=str, choices=CommitType.choices()
39+
)
40+
parser.add_argument("-v", "--verbose", action="count", default=0, help="Verbosity, by default errors are reported.")
41+
args = parser.parse_args()
42+
set_log_level(args.verbose)
43+
44+
try:
45+
commit_type = CommitType.parse(args.release_type)
46+
version_to_print = get_project_version_string(commit_type)
47+
print(version_to_print)
48+
except Exception as e:
49+
log_exception(logger, e)
50+
sys.exit(1)
51+
52+
53+
if __name__ == "__main__":
54+
main()
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#
2+
# Copyright (C) 2020-2021 Arm Limited or its affiliates and Contributors. All rights reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
"""Helpers with regards to versioning."""
6+
7+
import logging
8+
import os
9+
from auto_version import auto_version_tool
10+
from typing import Optional, Tuple, Dict
11+
12+
from continuous_delivery_scripts.utils.configuration import configuration, ConfigurationVariable
13+
from continuous_delivery_scripts.utils.definitions import CommitType
14+
from continuous_delivery_scripts.utils.filesystem_helpers import cd
15+
from continuous_delivery_scripts.utils.git_helpers import LocalProjectRepository
16+
17+
logger = logging.getLogger(__name__)
18+
19+
20+
def calculate_version(commit_type: CommitType, use_news_files: bool) -> Tuple[bool, Optional[str], Dict[str, str]]:
21+
"""Calculates the version for the release.
22+
23+
eg. "0.1.2"
24+
25+
Args:
26+
commit_type: release type
27+
use_news_files: Should the version be dependent on changes recorded in news files
28+
29+
Returns:
30+
Tuple containing
31+
a flag stating whether it is a new version or not
32+
A semver-style version for the latest release
33+
"""
34+
BUMP_TYPES = {CommitType.DEVELOPMENT: "build", CommitType.BETA: "prerelease"}
35+
is_release = commit_type == CommitType.RELEASE
36+
enable_file_triggers = True if use_news_files else None
37+
bump = BUMP_TYPES.get(commit_type)
38+
project_config_path = configuration.get_value(ConfigurationVariable.PROJECT_CONFIG)
39+
new_version: Optional[str] = None
40+
is_new_version: bool = False
41+
with cd(os.path.dirname(project_config_path)):
42+
old, new_version, updates = auto_version_tool.main(
43+
release=is_release,
44+
enable_file_triggers=enable_file_triggers,
45+
commit_count_as=bump,
46+
config_path=project_config_path,
47+
)
48+
# Autoversion second returned value is not actually the new version
49+
# There seem to be a bug in autoversion.
50+
# This is why the following needs to be done to determine the version
51+
version_elements = _get_version_elements(updates)
52+
new_version = version_elements.get(auto_version_tool.Constants.VERSION_FIELD, new_version)
53+
is_new_version = old != new_version
54+
logger.info(":: Determining the new version")
55+
logger.info(f"Version: {new_version}")
56+
return is_new_version, new_version, version_elements
57+
58+
59+
def determine_version_string(
60+
commit_type: CommitType, new_version: Optional[str], version_elements: Dict[str, str]
61+
) -> Optional[str]:
62+
"""Updates the version string depending on the release type.
63+
64+
Args:
65+
commit_type: commit type
66+
new_version: the new version
67+
version_elements: version elements
68+
"""
69+
if commit_type == CommitType.DEVELOPMENT:
70+
commit_count = version_elements.get(auto_version_tool.Constants.COMMIT_COUNT_FIELD, None)
71+
if not commit_count:
72+
with LocalProjectRepository() as git:
73+
commit_count = git.get_commit_count()
74+
commit_hash = version_elements.get(auto_version_tool.Constants.COMMIT_FIELD, None)
75+
if not commit_hash:
76+
with LocalProjectRepository() as git:
77+
commit_hash = git.get_commit_hash()
78+
return "%s-%s.%s+%s" % (
79+
new_version,
80+
auto_version_tool.config.BUILD_TOKEN,
81+
commit_count,
82+
commit_hash,
83+
)
84+
return new_version
85+
86+
87+
def _get_version_elements(native_version_elements: Dict[str, str]) -> Dict[str, str]:
88+
"""Determines the different version elements.
89+
90+
Args:
91+
native_version_elements: native version elements as understood by autoversion
92+
"""
93+
return {
94+
key: native_version_elements[native]
95+
for native, key in auto_version_tool.config.key_aliases.items()
96+
if native in native_version_elements
97+
}

news/202108111347.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix bug in determining the new release/beta version

news/202108111437.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added a command to determine project's version

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"console_scripts": [
4141
f"cd-assert-news={SOURCE_DIR}.assert_news:main",
4242
f"cd-generate-news={SOURCE_DIR}.generate_news:main",
43+
f"cd-determine-version={SOURCE_DIR}.get_version:main",
4344
f"cd-create-news-file={SOURCE_DIR}.create_news_file:main",
4445
f"cd-generate-docs={SOURCE_DIR}.generate_docs:main",
4546
f"cd-tag-and-release={SOURCE_DIR}.tag_and_release:main",

tests/versioning/test_versioning.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#
2+
# Copyright (C) 2020-2021 Arm Limited or its affiliates and Contributors. All rights reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
import unittest
6+
from continuous_delivery_scripts.utils.versioning import calculate_version, determine_version_string
7+
from continuous_delivery_scripts.utils.definitions import CommitType
8+
9+
10+
class TestVersioning(unittest.TestCase):
11+
def test_calculate_version(self):
12+
for release_type in CommitType.choices():
13+
_, new_version, version_elements = calculate_version(CommitType.RELEASE, False)
14+
self.assertIsNotNone(new_version)
15+
self.assertNotEquals(new_version, "")
16+
self.assertIsNotNone(version_elements)
17+
self.assertGreater(len(version_elements), 0)
18+
_, new_version, version_elements = calculate_version(CommitType.RELEASE, True)
19+
self.assertIsNotNone(new_version)
20+
self.assertNotEquals(new_version, "")
21+
self.assertIsNotNone(version_elements)
22+
self.assertGreater(len(version_elements), 0)
23+
24+
def test_determine_version_string(self):
25+
self.assertEqual("1.1.1", determine_version_string(CommitType.RELEASE, "1.1.1", {}))
26+
self.assertEqual("1.1.1", determine_version_string(CommitType.BETA, "1.1.1", {}))
27+
self.assertTrue("1.1.1" in determine_version_string(CommitType.DEVELOPMENT, "1.1.1", {}))
28+
self.assertGreaterEqual(len(determine_version_string(CommitType.DEVELOPMENT, "1.1.1", {})), len("1.1.1"))

0 commit comments

Comments
 (0)