diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..42b799523 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +* text=auto +*crlf.txt text eol=crlf \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6572957f4..62202845d 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ nosetests.xml coverage.xml *,cover .hypothesis/ +.pytest_cache # Translations *.mo diff --git a/cookiecutter/generate.py b/cookiecutter/generate.py index 7f96dbb23..50081799a 100644 --- a/cookiecutter/generate.py +++ b/cookiecutter/generate.py @@ -170,9 +170,14 @@ def generate_file(project_dir, infile, context, env, skip_if_file_exists=False): raise rendered_file = tmpl.render(**context) + # Detect original file newline to output the rendered file + with io.open(infile, 'r', encoding='utf-8') as rd: + rd.readline() # Read the first line to load 'newlines' value + newline = getattr(rd, 'newlines') + logger.debug('Writing contents to file %s', outfile) - with io.open(outfile, 'w', encoding='utf-8') as fh: + with io.open(outfile, 'w', encoding='utf-8', newline=newline) as fh: fh.write(rendered_file) # Apply file permissions to output file diff --git a/tests/test-generate-files/input{{cookiecutter.food}}/simple-with-newline-crlf.txt b/tests/test-generate-files/input{{cookiecutter.food}}/simple-with-newline-crlf.txt new file mode 100644 index 000000000..865888417 --- /dev/null +++ b/tests/test-generate-files/input{{cookiecutter.food}}/simple-with-newline-crlf.txt @@ -0,0 +1 @@ +I eat {{ cookiecutter.food }} diff --git a/tests/test_generate_files.py b/tests/test_generate_files.py index cae50bd24..f56c3d6bf 100644 --- a/tests/test_generate_files.py +++ b/tests/test_generate_files.py @@ -84,6 +84,25 @@ def test_generate_files_with_trailing_newline(): with io.open(newline_file, 'r', encoding='utf-8') as f: simple_text = f.read() assert simple_text == 'I eat pizzä\n' + assert f.newlines == '\n' + + +@pytest.mark.usefixtures('clean_system', 'remove_additional_folders') +def test_generate_files_with_windows_newline(): + generate.generate_files( + context={ + 'cookiecutter': {'food': 'pizzä'} + }, + repo_dir='tests/test-generate-files' + ) + + newline_file = 'inputpizzä/simple-with-newline-crlf.txt' + assert os.path.isfile(newline_file) + + with io.open(newline_file, 'r') as f: + f.read() + + assert f.newlines == '\r\n' @pytest.mark.usefixtures('clean_system', 'remove_additional_folders')