summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Reiter <reiter.christoph@gmail.com>2019-01-23 21:43:14 +0100
committerJussi Pakkanen <jpakkane@gmail.com>2019-01-24 21:02:34 +0200
commit8df5afc98aae6863d1fc24d902dc4e31141a1711 (patch)
treeb0eeae0a152e4cd97143fd5f7f270c773743b62a
parentb45c367d922a0a6baa134f59a7b900390cb3fe7b (diff)
downloadmeson-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.py4
-rwxr-xr-xrun_unittests.py34
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