Skip to content

Commit 676dc01

Browse files
authored
Use tempfile to derive the temp dir of the host (#33) (Fixes #26)
* use tempfile to derive the temp dir of the host * update test to skip if patch is missing, use methods in tmp file building * update readme with message about patch * bump travis to bionic * use os.path instead of pathlib * add a history file * update history notes for upcoming release * drop python2 * might as well drop 3.4, too * remove unused snippets
1 parent 74530bf commit 676dc01

File tree

8 files changed

+262
-256
lines changed

8 files changed

+262
-256
lines changed

.travis.yml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
dist: xenial
1+
dist: bionic
22
sudo: false
33
language: python
44
matrix:
55
include:
6-
- python: 3.4
7-
env: TOX_ENV=py34
8-
96
- python: 3.5
107
env: TOX_ENV=py35
118

@@ -19,11 +16,6 @@ matrix:
1916
env: TOX_ENV=py38
2017
- python: 3.8
2118
env: TOX_ENV=lint
22-
23-
- python: 2.7
24-
env: TOX_ENV=py27
25-
- python: 2.7
26-
env: TOX_ENV=lint
2719
addons:
2820
apt:
2921
packages:

HISTORY.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# next
2+
3+
- Issue #26 fix where hardcoded "/tmp" reference was being used
4+
- Support up to Python 3.8
5+
- Drop support for Python 2, 3.4
6+
7+
# 0.0.6
8+
9+
- PR #13 Support for reverse patching (Thanks, @graingert)
10+
- This is a breaking change that converted the parsed tuples into
11+
namedtuples and added the hunk number to that tuple
12+
- PR #20 Support up to Python 3.7, drop support for 3.3 (Thanks, @graingert)
13+
- Issue #18 fix for empty file adds in git
14+
15+
# 0.0.5
16+
17+
- PR #6 Added better support for binary files. (Thanks, @ramusus)
18+
- PR #3 Added support for git index revision ids that have more than 7 characters (Thanks, @jopereria)
19+
20+
# 0.0.4
21+
22+
- PR #2 Bug fix for one-liner diffs (Thanks, @thoward)
23+
- Issue #1 fix where some old real test cases were left failing
24+
- Added a Code of Conduct
25+
- Added support for Python 3.5
26+
27+
# 0.0.3
28+
29+
- Better matching for almost all patch headers
30+
- Support patches that have entire hunks removed
31+
- Support git patches that are missing index header file modes
32+
- Moved to MIT license
33+
- Officially adopt Python 3
34+
35+
# 0.0.2
36+
37+
- Initial support to apply parsed patches
38+
- Support diffs that do not have headers
39+
40+
# 0.0.1
41+
42+
- The very first release that included parsing support for patches in unified
43+
diff format, context diff format, ed diff format, git, bazaar, subversion,
44+
and cvs.

README.rst

Lines changed: 156 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -1,153 +1,156 @@
1-
What The Patch!?
2-
================
3-
4-
.. image:: https://travis-ci.org/cscorley/whatthepatch.svg?style=flat
5-
:target: https://travis-ci.org/cscorley/whatthepatch
6-
7-
What The Patch!? is a library for both parsing and applying patch files.
8-
9-
Features
10-
---------
11-
12-
- Parsing of almost all ``diff`` formats (except forwarded ed):
13-
14-
- normal (default, --normal)
15-
- copied context (-c, --context)
16-
- unified context (-u, --unified)
17-
- ed script (-e, --ed)
18-
- rcs ed script (-n, --rcs)
19-
20-
- Parsing of several SCM patches:
21-
22-
- CVS
23-
- SVN
24-
- Git
25-
26-
Installation
27-
------------
28-
29-
To install What The Patch!?, simply:
30-
31-
.. code-block:: bash
32-
33-
$ pip install whatthepatch
34-
35-
Usage
36-
=====
37-
38-
Let us say we have a patch file containing some changes, aptly named
39-
'somechanges.patch':
40-
41-
.. code-block:: diff
42-
43-
--- lao 2012-12-26 23:16:54.000000000 -0600
44-
+++ tzu 2012-12-26 23:16:50.000000000 -0600
45-
@@ -1,7 +1,6 @@
46-
-The Way that can be told of is not the eternal Way;
47-
-The name that can be named is not the eternal name.
48-
The Nameless is the origin of Heaven and Earth;
49-
-The Named is the mother of all things.
50-
+The named is the mother of all things.
51-
+
52-
Therefore let there always be non-being,
53-
so we may see their subtlety,
54-
And let there always be being,
55-
@@ -9,3 +8,6 @@
56-
The two are the same,
57-
But after they are produced,
58-
they have different names.
59-
+They both may be called deep and profound.
60-
+Deeper and more profound,
61-
+The door of all subtleties!
62-
63-
64-
Parsing
65-
-------
66-
67-
Here is how we would use What The Patch!? in Python to get the changeset for
68-
each diff in the patch:
69-
70-
.. code-block:: python
71-
72-
>>> import whatthepatch
73-
>>> import pprint
74-
>>> with open('tests/casefiles/diff-unified.diff') as f:
75-
... text = f.read()
76-
...
77-
>>> for diff in whatthepatch.parse_patch(text):
78-
... print(diff) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
79-
...
80-
diff(header=header(index_path=None,
81-
old_path='lao',
82-
old_version='2013-01-05 16:56:19.000000000 -0600',
83-
new_path='tzu',
84-
new_version='2013-01-05 16:56:35.000000000 -0600'),
85-
changes=[Change(old=1, new=None, line='The Way that can be told of is not the eternal Way;', hunk=1),
86-
Change(old=2, new=None, line='The name that can be named is not the eternal name.', hunk=1),
87-
Change(old=3, new=1, line='The Nameless is the origin of Heaven and Earth;', hunk=1),
88-
Change(old=4, new=None, line='The Named is the mother of all things.', hunk=1),
89-
Change(old=None, new=2, line='The named is the mother of all things.', hunk=1),
90-
Change(old=None, new=3, line='', hunk=1),
91-
Change(old=5, new=4, line='Therefore let there always be non-being,', hunk=1),
92-
Change(old=6, new=5, line=' so we may see their subtlety,', hunk=1),
93-
Change(old=7, new=6, line='And let there always be being,', hunk=1),
94-
Change(old=9, new=8, line='The two are the same,', hunk=2),
95-
Change(old=10, new=9, line='But after they are produced,', hunk=2),
96-
Change(old=11, new=10, line=' they have different names.', hunk=2),
97-
Change(old=None, new=11, line='They both may be called deep and profound.', hunk=2),
98-
Change(old=None, new=12, line='Deeper and more profound,', hunk=2),
99-
Change(old=None, new=13, line='The door of all subtleties!', hunk=2)],
100-
text='...')
101-
102-
The changes are listed as they are in the patch, but instead of the +/- syntax
103-
of the patch, we get a tuple of two numbers and the text of the line.
104-
What these numbers indicate are as follows:
105-
106-
#. ``( old=1, new=None, ... )`` indicates line 1 of the file lao was **removed**.
107-
#. ``( old=None, new=2, ... )`` indicates line 2 of the file tzu was **inserted**.
108-
#. ``( old=5, new=4, ... )`` indicates that line 5 of lao and line 4 of tzu are **equal**.
109-
110-
Please note that not all patch formats provide the actual lines modified, so some
111-
results will have the text portion of the tuple set to ``None``.
112-
113-
Applying
114-
--------
115-
116-
To apply a diff to some lines of text, first read the patch and parse it.
117-
118-
.. code-block:: python
119-
120-
>>> import whatthepatch
121-
>>> with open('tests/casefiles/diff-default.diff') as f:
122-
... text = f.read()
123-
...
124-
>>> with open('tests/casefiles/lao') as f:
125-
... lao = f.read()
126-
...
127-
>>> diff = [x for x in whatthepatch.parse_patch(text)]
128-
>>> diff = diff[0]
129-
>>> tzu = whatthepatch.apply_diff(diff, lao)
130-
>>> tzu # doctest: +NORMALIZE_WHITESPACE
131-
['The Nameless is the origin of Heaven and Earth;',
132-
'The named is the mother of all things.',
133-
'',
134-
'Therefore let there always be non-being,',
135-
' so we may see their subtlety,',
136-
'And let there always be being,',
137-
' so we may see their outcome.',
138-
'The two are the same,',
139-
'But after they are produced,',
140-
' they have different names.',
141-
'They both may be called deep and profound.',
142-
'Deeper and more profound,',
143-
'The door of all subtleties!']
144-
145-
146-
Contribute
147-
==========
148-
149-
#. Fork this repository
150-
#. Create a new branch to work on
151-
#. Commit your tests and/or changes
152-
#. Push and create a pull request here!
153-
1+
What The Patch!?
2+
================
3+
4+
.. image:: https://travis-ci.org/cscorley/whatthepatch.svg?style=flat
5+
:target: https://travis-ci.org/cscorley/whatthepatch
6+
7+
What The Patch!? is a library for both parsing and applying patch files.
8+
9+
Features
10+
---------
11+
12+
- Parsing of almost all ``diff`` formats (except forwarded ed):
13+
14+
- normal (default, --normal)
15+
- copied context (-c, --context)
16+
- unified context (-u, --unified)
17+
- ed script (-e, --ed)
18+
- rcs ed script (-n, --rcs)
19+
20+
- Parsing of several SCM patches:
21+
22+
- CVS
23+
- SVN
24+
- Git
25+
26+
Installation
27+
------------
28+
29+
To install What The Patch!?, simply:
30+
31+
.. code-block:: bash
32+
33+
$ pip install whatthepatch
34+
35+
Usage
36+
=====
37+
38+
Let us say we have a patch file containing some changes, aptly named
39+
'somechanges.patch':
40+
41+
.. code-block:: diff
42+
43+
--- lao 2012-12-26 23:16:54.000000000 -0600
44+
+++ tzu 2012-12-26 23:16:50.000000000 -0600
45+
@@ -1,7 +1,6 @@
46+
-The Way that can be told of is not the eternal Way;
47+
-The name that can be named is not the eternal name.
48+
The Nameless is the origin of Heaven and Earth;
49+
-The Named is the mother of all things.
50+
+The named is the mother of all things.
51+
+
52+
Therefore let there always be non-being,
53+
so we may see their subtlety,
54+
And let there always be being,
55+
@@ -9,3 +8,6 @@
56+
The two are the same,
57+
But after they are produced,
58+
they have different names.
59+
+They both may be called deep and profound.
60+
+Deeper and more profound,
61+
+The door of all subtleties!
62+
63+
64+
Parsing
65+
-------
66+
67+
Here is how we would use What The Patch!? in Python to get the changeset for
68+
each diff in the patch:
69+
70+
.. code-block:: python
71+
72+
>>> import whatthepatch
73+
>>> import pprint
74+
>>> with open('tests/casefiles/diff-unified.diff') as f:
75+
... text = f.read()
76+
...
77+
>>> for diff in whatthepatch.parse_patch(text):
78+
... print(diff) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
79+
...
80+
diff(header=header(index_path=None,
81+
old_path='lao',
82+
old_version='2013-01-05 16:56:19.000000000 -0600',
83+
new_path='tzu',
84+
new_version='2013-01-05 16:56:35.000000000 -0600'),
85+
changes=[Change(old=1, new=None, line='The Way that can be told of is not the eternal Way;', hunk=1),
86+
Change(old=2, new=None, line='The name that can be named is not the eternal name.', hunk=1),
87+
Change(old=3, new=1, line='The Nameless is the origin of Heaven and Earth;', hunk=1),
88+
Change(old=4, new=None, line='The Named is the mother of all things.', hunk=1),
89+
Change(old=None, new=2, line='The named is the mother of all things.', hunk=1),
90+
Change(old=None, new=3, line='', hunk=1),
91+
Change(old=5, new=4, line='Therefore let there always be non-being,', hunk=1),
92+
Change(old=6, new=5, line=' so we may see their subtlety,', hunk=1),
93+
Change(old=7, new=6, line='And let there always be being,', hunk=1),
94+
Change(old=9, new=8, line='The two are the same,', hunk=2),
95+
Change(old=10, new=9, line='But after they are produced,', hunk=2),
96+
Change(old=11, new=10, line=' they have different names.', hunk=2),
97+
Change(old=None, new=11, line='They both may be called deep and profound.', hunk=2),
98+
Change(old=None, new=12, line='Deeper and more profound,', hunk=2),
99+
Change(old=None, new=13, line='The door of all subtleties!', hunk=2)],
100+
text='...')
101+
102+
The changes are listed as they are in the patch, but instead of the +/- syntax
103+
of the patch, we get a tuple of two numbers and the text of the line.
104+
What these numbers indicate are as follows:
105+
106+
#. ``( old=1, new=None, ... )`` indicates line 1 of the file lao was **removed**.
107+
#. ``( old=None, new=2, ... )`` indicates line 2 of the file tzu was **inserted**.
108+
#. ``( old=5, new=4, ... )`` indicates that line 5 of lao and line 4 of tzu are **equal**.
109+
110+
Please note that not all patch formats provide the actual lines modified, so some
111+
results will have the text portion of the tuple set to ``None``.
112+
113+
Applying
114+
--------
115+
116+
To apply a diff to some lines of text, first read the patch and parse it.
117+
118+
.. code-block:: python
119+
120+
>>> import whatthepatch
121+
>>> with open('tests/casefiles/diff-default.diff') as f:
122+
... text = f.read()
123+
...
124+
>>> with open('tests/casefiles/lao') as f:
125+
... lao = f.read()
126+
...
127+
>>> diff = [x for x in whatthepatch.parse_patch(text)]
128+
>>> diff = diff[0]
129+
>>> tzu = whatthepatch.apply_diff(diff, lao)
130+
>>> tzu # doctest: +NORMALIZE_WHITESPACE
131+
['The Nameless is the origin of Heaven and Earth;',
132+
'The named is the mother of all things.',
133+
'',
134+
'Therefore let there always be non-being,',
135+
' so we may see their subtlety,',
136+
'And let there always be being,',
137+
' so we may see their outcome.',
138+
'The two are the same,',
139+
'But after they are produced,',
140+
' they have different names.',
141+
'They both may be called deep and profound.',
142+
'Deeper and more profound,',
143+
'The door of all subtleties!']
144+
145+
If apply does not satisfy your needs and you are on a system that has `patch`
146+
in `PATH`, you can also call `apply_diff(diff, lao, use_patch=True)`. The
147+
default is False, and patch is not necessary to apply diffs to text.
148+
149+
Contribute
150+
==========
151+
152+
#. Fork this repository
153+
#. Create a new branch to work on
154+
#. Commit your tests and/or changes
155+
#. Push and create a pull request here!
156+

0 commit comments

Comments
 (0)