diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..67911ee --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,28 @@ +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + + workflow_dispatch: + +jobs: + build: + runs-on: self-hosted + strategy: + matrix: + python-version: [ '2.7', '3.6', '3.7', '3.8', '3.9' ] + fail-fast: false + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + architecture: 'x64' + - name: 'Run Tests' + run: $GITHUB_WORKSPACE/run_tests.sh + shell: bash + diff --git a/tests/samples/git_cr.diff b/tests/samples/git_cr.diff new file mode 100644 index 0000000..c7e39a4 --- /dev/null +++ b/tests/samples/git_cr.diff @@ -0,0 +1,9 @@ +diff --git a/src/test/org/apache/commons/math/util/ExpandableDoubleArrayTest.java b/src/test/org/apache/commons/math/util/ExpandableDoubleArrayTest.java +new file mode 100644 +index 000000000..2b38fa232 +--- /dev/null ++++ b/a.txt +@@ -0,0 +1,3 @@ ++ "This line is broken into two lines by CR. " + "but it should be treated as one line in the text diff file" ++ "This has no CR" ++ "This line also has CR. " + "but it should also be treated as one line in the text diff file". diff --git a/tests/test_parser.py b/tests/test_parser.py index 964dbc6..e078c33 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -231,6 +231,18 @@ def test_parse_malformed_diff_shorter_than_expected(self): with open(utf8_file, 'r') as diff_file: self.assertRaises(UnidiffParseError, PatchSet, diff_file) + def test_from_filename_with_cr_in_diff_text_files(self): + """Parse git diff text files that contain CR""" + utf8_file = os.path.join(self.samples_dir, 'samples/git_cr.diff') + self.assertRaises(UnidiffParseError, PatchSet.from_filename, utf8_file) + + ps1 = PatchSet.from_filename(utf8_file, newline='\n') + import io + with io.open(utf8_file, 'r', newline='\n') as diff_file: + ps2 = PatchSet(diff_file) + + self.assertEqual(ps1, ps2) + def test_parse_diff_with_new_and_modified_binary_files(self): """Parse git diff file with newly added and modified binaries files.""" utf8_file = os.path.join(self.samples_dir, 'samples/sample8.diff') diff --git a/unidiff/patch.py b/unidiff/patch.py index 16834d2..4dfb42d 100644 --- a/unidiff/patch.py +++ b/unidiff/patch.py @@ -52,8 +52,10 @@ PY2 = sys.version_info[0] == 2 if PY2: + import io from StringIO import StringIO - open_file = codecs.open + # open_file = codecs.open + open_file = io.open make_str = lambda x: x.encode(DEFAULT_ENCODING) def implements_to_string(cls): @@ -557,10 +559,10 @@ def _parse(self, diff, encoding, metadata_only): patch_info.append(line) @classmethod - def from_filename(cls, filename, encoding=DEFAULT_ENCODING, errors=None): + def from_filename(cls, filename, encoding=DEFAULT_ENCODING, errors=None, newline=None): # type: (str, str, Optional[str]) -> PatchSet """Return a PatchSet instance given a diff filename.""" - with open_file(filename, 'r', encoding=encoding, errors=errors) as f: + with open_file(filename, 'r', encoding=encoding, errors=errors, newline=newline) as f: instance = cls(f) return instance