diff options
author | Christoph Reiter <reiter.christoph@gmail.com> | 2019-01-23 21:43:14 +0100 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2019-01-24 21:02:34 +0200 |
commit | 8df5afc98aae6863d1fc24d902dc4e31141a1711 (patch) | |
tree | b0eeae0a152e4cd97143fd5f7f270c773743b62a | |
parent | b45c367d922a0a6baa134f59a7b900390cb3fe7b (diff) | |
download | meson-8df5afc98aae6863d1fc24d902dc4e31141a1711.tar.gz |
configure_file: preserve newlines of the input file. Fixes #4817
In some cases (see #4817) it's helpful if the output file uses the
same newlines as the input file without translating them to the
platform defaults.
open() by default recognizes all newline styles and translates them
to "\n" and then to the platform default when writing.
Passing "" to "newline" disables the translation and lets us pass through
the original newline characters.
-rw-r--r-- | mesonbuild/mesonlib.py | 4 | ||||
-rwxr-xr-x | run_unittests.py | 34 |
2 files changed, 36 insertions, 2 deletions
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 98c2366d6..2170fec52 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -729,7 +729,7 @@ def do_mesondefine(line, confdata): def do_conf_file(src, dst, confdata, format, encoding='utf-8'): try: - with open(src, encoding=encoding) as f: + with open(src, encoding=encoding, newline='') as f: data = f.readlines() except Exception as e: raise MesonException('Could not read input file %s: %s' % (src, str(e))) @@ -763,7 +763,7 @@ def do_conf_file(src, dst, confdata, format, encoding='utf-8'): result.append(line) dst_tmp = dst + '~' try: - with open(dst_tmp, 'w', encoding=encoding) as f: + with open(dst_tmp, 'w', encoding=encoding, newline='') as f: f.writelines(result) except Exception as e: raise MesonException('Could not write output file %s: %s' % (dst, str(e))) diff --git a/run_unittests.py b/run_unittests.py index ea5b310fc..d97ae7eed 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -30,6 +30,7 @@ import functools from itertools import chain from unittest import mock from configparser import ConfigParser +from contextlib import contextmanager from glob import glob from pathlib import (PurePath, Path) @@ -192,6 +193,24 @@ def skip_if_not_base_option(feature): return actual +@contextmanager +def temp_filename(): + '''A context manager which provides a filename to an empty temporary file. + + On exit the file will be deleted. + ''' + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + yield filename + finally: + try: + os.remove(filename) + except OSError: + pass + + class PatchModule: ''' Fancy monkey-patching! Whee! Can't use mock.patch because it only @@ -1296,6 +1315,21 @@ class AllPlatformTests(BasePlatformTests): prefix = opt['value'] self.assertEqual(prefix, '/absoluteprefix') + def test_do_conf_file_preserve_newlines(self): + + def conf_file(in_data, confdata): + with temp_filename() as fin: + with open(fin, 'wb') as fobj: + fobj.write(in_data.encode('utf-8')) + with temp_filename() as fout: + mesonbuild.mesonlib.do_conf_file(fin, fout, confdata, 'meson') + with open(fout, 'rb') as fobj: + return fobj.read().decode('utf-8') + + confdata = {'VAR': ('foo', 'bar')} + self.assertEqual(conf_file('@VAR@\n@VAR@\n', confdata), 'foo\nfoo\n') + self.assertEqual(conf_file('@VAR@\r\n@VAR@\r\n', confdata), 'foo\r\nfoo\r\n') + def test_absolute_prefix_libdir(self): ''' Tests that setting absolute paths for --prefix and --libdir work. Can't |