Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add handling of PROJECT_DEV_VERSION in CMakelists.txt. #32

Merged
merged 6 commits into from
Sep 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
### Added
- add handling of PROJECT_DEV_VERSION in CMakeLists.txt if set [#32](https://github.com/greenbone/pontos/pull/32)
### Changed
- set releasename to projectname version [#25](https://github.com/greenbone/pontos/pull/25)
### Deprecated
Expand Down
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 11 additions & 4 deletions pontos/release/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,13 @@ def parse(args=None):
)


def update_version(to: str, _version: version) -> Tuple[bool, str]:
executed, filename = _version.main(False, args=["--quiet", "update", to])
def update_version(
to: str, _version: version, *, develop: bool
) -> Tuple[bool, str]:
develop_arg = '--develop' if develop else ''
executed, filename = _version.main(
False, args=["--quiet", develop_arg, "update", to]
)

if not executed:
if filename == "":
Expand Down Expand Up @@ -186,7 +191,9 @@ def prepare(
if git_version.encode() in git_tags.stdout.splitlines():
raise ValueError('git tag {} is already taken.'.format(git_version))

executed, filename = update_version(release_version, _version)
executed, filename = update_version(
release_version, _version, develop=False
)
if not executed:
return False

Expand Down Expand Up @@ -226,7 +233,7 @@ def prepare(
release_text.write_text(changelog_text)

# set to new version add skeleton
executed, filename = update_version(nextversion, _version)
executed, filename = update_version(nextversion, _version, develop=True)
if not executed:
return False

Expand Down
57 changes: 51 additions & 6 deletions pontos/version/cmake_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def run(self, args=None) -> Union[int, str]:
if commandline_arguments.command == 'update':
self.update_version(
commandline_arguments.version,
develop=commandline_arguments.develop,
)
elif commandline_arguments.command == 'show':
self.print_current_version()
Expand All @@ -70,11 +71,11 @@ def __print(self, *args):
if not self.__quiet:
print(*args)

def update_version(self, version: str):
def update_version(self, version: str, *, develop: bool = False):
content = self.__cmake_filepath.read_text()
cmvp = CMakeVersionParser(content)
previous_version = cmvp.get_current_version()
new_content = cmvp.update_version(version)
new_content = cmvp.update_version(version, develop=develop)
self.__cmake_filepath.write_text(new_content)
self.__print(
'Updated version from {} to {}'.format(previous_version, version)
Expand All @@ -96,17 +97,20 @@ def verify_version(self, version: str):

class CMakeVersionParser:
def __init__(self, cmake_content_lines: str):
line_no, current_version = self._find_version_in_cmake(
line_no, current_version, pd_line_no, pd = self._find_version_in_cmake(
cmake_content_lines
)
self._cmake_content_lines = cmake_content_lines.split('\n')
self._version_line_number = line_no
self._current_version = current_version
self._project_dev_version_line_number = pd_line_no
self._project_dev_version = pd

__cmake_scanner = re.Scanner(
[
(r'#.*', lambda _, token: ("comment", token)),
(r'"[^"]*"', lambda _, token: ("string", token)),
(r'"[0-9]+"', lambda _, token: ("number", token)),
(r"\(", lambda _, token: ("open_bracket", token)),
(r"\)", lambda _, token: ("close_bracket", token)),
(r'[^ \t\r\n()#"]+', lambda _, token: ("word", token)),
Expand All @@ -119,7 +123,7 @@ def __init__(self, cmake_content_lines: str):
def get_current_version(self) -> str:
return self._current_version

def update_version(self, new_version: str) -> str:
def update_version(self, new_version: str, *, develop: bool = False) -> str:
if not is_version_pep440_compliant(new_version):
raise VersionError(
"version {} is not pep 440 compliant.".format(new_version)
Expand All @@ -130,13 +134,31 @@ def update_version(self, new_version: str) -> str:

self._cmake_content_lines[self._version_line_number] = updated
self._current_version = new_version
if self._project_dev_version_line_number:
self._cmake_content_lines[
self._project_dev_version_line_number
] = self._cmake_content_lines[
self._project_dev_version_line_number
].replace(
str(int(not develop)), str(int(develop))
)
self._project_dev_version = str(int(develop))

return '\n'.join(self._cmake_content_lines)

def _find_version_in_cmake(self, content: str) -> Tuple[int, str]:
in_project = False
in_version = False

version_line_no: int = None
version: str = None

in_set = False
in_project_dev_version = False

project_dev_version_line_no: int = None
project_dev_version: int = None

for lineno, token_type, value in self._tokenize(content):
if token_type == 'word' and value == 'project':
in_project = True
Expand All @@ -145,11 +167,34 @@ def _find_version_in_cmake(self, content: str) -> Tuple[int, str]:
elif in_version and (
token_type == 'word' or token_type == 'string'
):
return lineno, value
version_line_no = lineno
version = value
in_project = False
in_version = False
elif token_type == 'word' and value == 'set':
in_set = True
elif (
in_set
and token_type == 'word'
and value == 'PROJECT_DEV_VERSION'
):
in_project_dev_version = True
elif in_project_dev_version and (
token_type == 'word' or token_type == 'number'
):
project_dev_version_line_no = lineno
project_dev_version = value
elif in_project and token_type == 'close_bracket':
raise ValueError('unable to find cmake version in project.')

raise ValueError('unable to find cmake project.')
if not version or version_line_no is None:
raise ValueError('unable to find cmake version.')
return (
version_line_no,
version,
project_dev_version_line_no,
project_dev_version,
)

def _tokenize(
self, content: str
Expand Down
10 changes: 6 additions & 4 deletions pontos/version/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ def initialize_default_parser() -> argparse.ArgumentParser:
help="don't check if version is already set",
action="store_true",
)
update_parser.add_argument(
'--develop',
help="indicates if it is a develop version",
action="store_true",
)
return parser


Expand Down Expand Up @@ -291,10 +296,7 @@ def run(self, args=None) -> Union[int, str]:

try:
if args.command == 'update':
self.update_version(
args.version,
force=args.force,
)
self.update_version(args.version, force=args.force)
elif args.command == 'show':
self.print_current_version()
elif args.command == 'verify':
Expand Down
53 changes: 49 additions & 4 deletions tests/version/test_cmake_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from unittest.mock import MagicMock
from pontos.version import CMakeVersionParser, VersionError, CMakeVersionCommand

# pylint: disable=W0212


class CMakeVersionCommandTestCase(unittest.TestCase):
def test_raise_exception_file_not_exists(self):
Expand Down Expand Up @@ -61,12 +63,16 @@ def test_raise_update_version(self):
fake_path = fake_path_class.return_value
fake_path.__str__.return_value = 'CMakeLists.txt'
fake_path.exists.return_value = True
fake_path.read_text.return_value = "project(VERSION 21)"
fake_path.read_text.return_value = (
"project(VERSION 21)\nset(PROJECT_DEV_VERSION 0)"
)
CMakeVersionCommand(cmake_lists_path=fake_path).run(
args=['update', '22']
args=['update', '22', '--develop']
)
fake_path.read_text.assert_called_with()
fake_path.write_text.assert_called_with('project(VERSION 22)')
fake_path.write_text.assert_called_with(
'project(VERSION 22)\nset(PROJECT_DEV_VERSION 1)'
)


class CMakeVersionParserTestCase(unittest.TestCase):
Expand Down Expand Up @@ -95,6 +101,45 @@ def test_get_current_version_multiline_project(self):
under_test = CMakeVersionParser("project\n(\nVERSION\n\t 2.3.4)")
self.assertEqual(under_test.get_current_version(), '2.3.4')

def test_find_project_dev_version(self):
test_cmake_lists = """
project(
DESCRIPTION something
VERSION 41.41.41
LANGUAGES c
)
set(
PROJECT_DEV_VERSION 1
)
"""
under_test = CMakeVersionParser(test_cmake_lists)
self.assertEqual(under_test._project_dev_version_line_number, 7)
self.assertEqual(under_test._project_dev_version, '1')

def test_update_project_dev_version(self):
test_cmake_lists = """
project(
DESCRIPTION something
VERSION 41.41.41
LANGUAGES c
)
set(
PROJECT_DEV_VERSION 1
)
"""
under_test = CMakeVersionParser(test_cmake_lists)

self.assertEqual(under_test._project_dev_version_line_number, 7)
self.assertEqual(under_test._project_dev_version, '1')
result = under_test.update_version('41.41.41', develop=False)
self.assertEqual(under_test._project_dev_version, '0')
self.assertEqual(
result,
test_cmake_lists.replace(
'PROJECT_DEV_VERSION 1', 'PROJECT_DEV_VERSION 0'
),
)

def test_get_current_version_multiline_project_combined_token(self):
under_test = CMakeVersionParser(
"project\n(\nDESCRIPTION something VERSION 2.3.4 LANGUAGES c\n)"
Expand All @@ -115,5 +160,5 @@ def test_raise_exception_no_project(self):
)

self.assertEqual(
str(context.exception), 'unable to find cmake project.'
str(context.exception), 'unable to find cmake version.'
)