From 3f88e7955ca78dd51e2aceadda2f6e2655824421 Mon Sep 17 00:00:00 2001 From: thebjorn Date: Sat, 17 Jan 2015 01:39:25 +0100 Subject: [PATCH] Harmonize line endings amongst source file and search/replace text. We want to keep the line endings in the source file, regardless of what the line endings in the config file is. The algorithm for finding the line ending, and the decision to only look at the first line, is inspired by ConfigObj (https://github.com/DiffSK/configobj/blob/0daebcb55aec2b5a18b287bbb2f4f6f03599f00e/configobj.py#L1294). This fixes the windows test failure of test_search_replace_expanding_changelog. --- bumpversion/__init__.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/bumpversion/__init__.py b/bumpversion/__init__.py index ccfaff0..c3b6878 100644 --- a/bumpversion/__init__.py +++ b/bumpversion/__init__.py @@ -234,14 +234,33 @@ def replace(self, current_version, new_version, context, dry_run): with io.open(self.path, 'rb') as f: file_content_before = f.read().decode('utf-8') + def line_ending(txt): + lines = txt.splitlines(True) + if not lines: + return os.linesep # use system default + first = lines[0] + if first.endswith('\r\n'): + return '\r\n' + if first.endswith('\n'): + return '\n' + if first.endswith('\r'): + return '\r' + return os.linesep + + eol = line_ending(file_content_before) + context['current_version'] = self._versionconfig.serialize(current_version, context) context['new_version'] = self._versionconfig.serialize(new_version, context) search_for = self._versionconfig.search.format(**context) replace_with = self._versionconfig.replace.format(**context) + search_for_eol = line_ending(search_for) + replace_with_eol = line_ending(replace_with) + file_content_after = file_content_before.replace( - search_for, replace_with + search_for.replace(search_for_eol, eol), + replace_with.replace(replace_with_eol, eol) ) if file_content_before == file_content_after: @@ -714,7 +733,7 @@ def main(original_args=None): for section_name in config.sections(): - section_name_match = re.compile("^bumpversion:(file|part):(.+)").match(section_name) + section_name_match = re.compile(r"^bumpversion:(file|part):(.+)").match(section_name) if not section_name_match: continue @@ -743,7 +762,7 @@ def main(original_args=None): section_config['part_configs'] = part_configs if not 'parse' in section_config: - section_config['parse'] = defaults.get("parse", '(?P\d+)\.(?P\d+)\.(?P\d+)') + section_config['parse'] = defaults.get("parse", r'(?P\d+)\.(?P\d+)\.(?P\d+)') if not 'serialize' in section_config: section_config['serialize'] = defaults.get('serialize', [str('{major}.{minor}.{patch}')])