From 8a021663deb73f1861acbd091525ce4d91865234 Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Mon, 25 Mar 2019 23:06:10 +0100 Subject: [PATCH 1/4] Detect the original file newline style and apply it to rendered template --- .gitattributes | 1 + .gitignore | 4 ++++ cookiecutter/generate.py | 7 ++++++- .../simple-with-newline-crlf.txt | 1 + tests/test_generate_files.py | 18 ++++++++++++++++++ 5 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 .gitattributes create mode 100644 tests/test-generate-files/input{{cookiecutter.food}}/simple-with-newline-crlf.txt diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..9cd4cb534 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*crlf.txt text eol=crlf # To keep clrf files with windows new line style \ No newline at end of file diff --git a/.gitignore b/.gitignore index 446285da3..056b01a65 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ nosetests.xml coverage.xml *,cover .hypothesis/ +.pytest_cache # Translations *.mo @@ -61,3 +62,6 @@ target/ # PyCharm .idea/ .env + +# VSCode +.vscode/ diff --git a/cookiecutter/generate.py b/cookiecutter/generate.py index e53613612..4a9f2295c 100644 --- a/cookiecutter/generate.py +++ b/cookiecutter/generate.py @@ -171,9 +171,14 @@ def generate_file(project_dir, infile, context, env): raise rendered_file = tmpl.render(**context) + # Detect original file newline to output the rendered file + with io.open(infile, 'r') as rd: + rd.readline() # Read the first line to load 'newlines' value + newline = getattr(rd, 'newlines') + logger.debug('Writing contents to file {}'.format(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 65b582f51..dfb2b8869 100644 --- a/tests/test_generate_files.py +++ b/tests/test_generate_files.py @@ -102,6 +102,24 @@ def test_generate_files_with_trailing_newline(): assert simple_text == u'I eat pizzä\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') def test_generate_files_binaries(): generate.generate_files( From d59f4a4029174019a647a259a9b4e8ecd2935bb8 Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Mon, 25 Mar 2019 23:11:51 +0100 Subject: [PATCH 2/4] Check the unix ending too in tests --- tests/test_generate_files.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_generate_files.py b/tests/test_generate_files.py index dfb2b8869..3658c686f 100644 --- a/tests/test_generate_files.py +++ b/tests/test_generate_files.py @@ -100,6 +100,7 @@ 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 == u'I eat pizzä\n' + assert f.newlines == '\n' @pytest.mark.usefixtures('clean_system', 'remove_additional_folders') From f1fc75f21c6e3828d5996d9f327cfeceec65f335 Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Tue, 26 Mar 2019 07:25:41 +0100 Subject: [PATCH 3/4] Fixed .gitattributes file --- .gitattributes | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 9cd4cb534..42b799523 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ -*crlf.txt text eol=crlf # To keep clrf files with windows new line style \ No newline at end of file +* text=auto +*crlf.txt text eol=crlf \ No newline at end of file From f30809468b5ebd5ae8209b6f2526da1106fbf41d Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Mon, 4 Nov 2019 17:54:06 +0100 Subject: [PATCH 4/4] Open file as UTF-8 --- cookiecutter/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookiecutter/generate.py b/cookiecutter/generate.py index 4a9f2295c..2d47aaec1 100644 --- a/cookiecutter/generate.py +++ b/cookiecutter/generate.py @@ -172,7 +172,7 @@ def generate_file(project_dir, infile, context, env): rendered_file = tmpl.render(**context) # Detect original file newline to output the rendered file - with io.open(infile, 'r') as rd: + with io.open(infile, 'r', encoding='utf-8') as rd: rd.readline() # Read the first line to load 'newlines' value newline = getattr(rd, 'newlines')