bsdiff4 1.4.0__tar.gz → 1.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bsdiff4-1.4.0/bsdiff4.egg-info → bsdiff4-1.4.2}/PKG-INFO +16 -11
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/README.rst +15 -10
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/bsdiff4/__init__.py +6 -2
- bsdiff4-1.4.2/bsdiff4/cli.py +145 -0
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/bsdiff4/core.c +207 -193
- bsdiff4-1.4.2/bsdiff4/format.py +142 -0
- bsdiff4-1.4.2/bsdiff4/tests.py +680 -0
- {bsdiff4-1.4.0 → bsdiff4-1.4.2/bsdiff4.egg-info}/PKG-INFO +16 -11
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/bsdiff4.egg-info/SOURCES.txt +1 -1
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/setup.py +1 -1
- bsdiff4-1.4.0/bsdiff4/cli.py +0 -96
- bsdiff4-1.4.0/bsdiff4/format.py +0 -142
- bsdiff4-1.4.0/bsdiff4/test_all.py +0 -484
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/LICENSE +0 -0
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/MANIFEST.in +0 -0
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/bsdiff4/py.typed +0 -0
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/bsdiff4.egg-info/dependency_links.txt +0 -0
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/bsdiff4.egg-info/entry_points.txt +0 -0
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/bsdiff4.egg-info/top_level.txt +0 -0
- {bsdiff4-1.4.0 → bsdiff4-1.4.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bsdiff4
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.2
|
|
4
4
|
Summary: binary diff and patch using the BSDIFF4-format
|
|
5
5
|
Home-page: https://github.com/ilanschnell/bsdiff4
|
|
6
6
|
Author: Ilan Schnell
|
|
@@ -42,14 +42,19 @@ The code is mostly derived from ``cx_bsdiff`` (written by Anthony Tuininga,
|
|
|
42
42
|
http://cx-bsdiff.sourceforge.net/). The ``cx_bsdiff`` code in turn was
|
|
43
43
|
derived from bsdiff, the standalone utility produced for BSD which can be
|
|
44
44
|
found at http://www.daemonology.net/bsdiff.
|
|
45
|
-
In addition to the two functions (diff and patch) cx_bsdiff provides, this
|
|
46
|
-
package includes:
|
|
47
45
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
46
|
+
Key features of this package include:
|
|
47
|
+
|
|
48
|
+
* high-level ``diff`` and ``patch`` functions
|
|
49
|
+
* an interface to the BSDIFF4 format
|
|
50
|
+
* stricter validation and improved error handling of malformed patches than
|
|
51
|
+
the standard ``bspatch`` tool; in particular overlong blocks are rejected
|
|
52
|
+
* functions for creating patches from files and applying them to files
|
|
53
|
+
* command-line interfaces: ``bsdiff4`` and ``bspatch4`` (the latter can also
|
|
54
|
+
inspect patches using ``bspatch4 PATCH``)
|
|
55
|
+
* support for free-threaded Python
|
|
56
|
+
* type hints
|
|
57
|
+
* extensive tests
|
|
53
58
|
|
|
54
59
|
|
|
55
60
|
The bsdiff4 package defines the following high level functions:
|
|
@@ -62,15 +67,15 @@ The bsdiff4 package defines the following high level functions:
|
|
|
62
67
|
Apply the BSDIFF4-format ``patch_bytes`` to ``src_bytes`` and return
|
|
63
68
|
the bytes.
|
|
64
69
|
|
|
65
|
-
``file_diff(src_path, dst_path, patch_path)``
|
|
70
|
+
``file_diff(src_path, dst_path, patch_path)`` -> None
|
|
66
71
|
Write a BSDIFF4-format patch (from the file ``src_path`` to the
|
|
67
72
|
file ``dst_path``) to the file ``patch_path``.
|
|
68
73
|
|
|
69
|
-
``file_patch(src_path, dst_path, patch_path)``
|
|
74
|
+
``file_patch(src_path, dst_path, patch_path)`` -> None
|
|
70
75
|
Apply the BSDIFF4-format file ``patch_path`` to the file ``src_path``
|
|
71
76
|
and write the result to the file ``dst_path``.
|
|
72
77
|
|
|
73
|
-
``file_patch_inplace(path, patch_path)``
|
|
78
|
+
``file_patch_inplace(path, patch_path)`` -> None
|
|
74
79
|
Apply the BSDIFF4-format file ``patch_path`` to the file ``path``
|
|
75
80
|
in place.
|
|
76
81
|
|
|
@@ -6,14 +6,19 @@ The code is mostly derived from ``cx_bsdiff`` (written by Anthony Tuininga,
|
|
|
6
6
|
http://cx-bsdiff.sourceforge.net/). The ``cx_bsdiff`` code in turn was
|
|
7
7
|
derived from bsdiff, the standalone utility produced for BSD which can be
|
|
8
8
|
found at http://www.daemonology.net/bsdiff.
|
|
9
|
-
In addition to the two functions (diff and patch) cx_bsdiff provides, this
|
|
10
|
-
package includes:
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
Key features of this package include:
|
|
11
|
+
|
|
12
|
+
* high-level ``diff`` and ``patch`` functions
|
|
13
|
+
* an interface to the BSDIFF4 format
|
|
14
|
+
* stricter validation and improved error handling of malformed patches than
|
|
15
|
+
the standard ``bspatch`` tool; in particular overlong blocks are rejected
|
|
16
|
+
* functions for creating patches from files and applying them to files
|
|
17
|
+
* command-line interfaces: ``bsdiff4`` and ``bspatch4`` (the latter can also
|
|
18
|
+
inspect patches using ``bspatch4 PATCH``)
|
|
19
|
+
* support for free-threaded Python
|
|
20
|
+
* type hints
|
|
21
|
+
* extensive tests
|
|
17
22
|
|
|
18
23
|
|
|
19
24
|
The bsdiff4 package defines the following high level functions:
|
|
@@ -26,15 +31,15 @@ The bsdiff4 package defines the following high level functions:
|
|
|
26
31
|
Apply the BSDIFF4-format ``patch_bytes`` to ``src_bytes`` and return
|
|
27
32
|
the bytes.
|
|
28
33
|
|
|
29
|
-
``file_diff(src_path, dst_path, patch_path)``
|
|
34
|
+
``file_diff(src_path, dst_path, patch_path)`` -> None
|
|
30
35
|
Write a BSDIFF4-format patch (from the file ``src_path`` to the
|
|
31
36
|
file ``dst_path``) to the file ``patch_path``.
|
|
32
37
|
|
|
33
|
-
``file_patch(src_path, dst_path, patch_path)``
|
|
38
|
+
``file_patch(src_path, dst_path, patch_path)`` -> None
|
|
34
39
|
Apply the BSDIFF4-format file ``patch_path`` to the file ``src_path``
|
|
35
40
|
and write the result to the file ``dst_path``.
|
|
36
41
|
|
|
37
|
-
``file_patch_inplace(path, patch_path)``
|
|
42
|
+
``file_patch_inplace(path, patch_path)`` -> None
|
|
38
43
|
Apply the BSDIFF4-format file ``patch_path`` to the file ``path``
|
|
39
44
|
in place.
|
|
40
45
|
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
from bsdiff4.format import (diff, patch, file_diff, file_patch,
|
|
2
2
|
file_patch_inplace)
|
|
3
3
|
|
|
4
|
-
__version__ = "1.4.
|
|
4
|
+
__version__ = "1.4.2"
|
|
5
5
|
|
|
6
6
|
__all__ = ["diff", "patch", "file_diff", "file_patch", "file_patch_inplace"]
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def test(verbosity=1):
|
|
10
|
-
|
|
10
|
+
"""test(verbosity=1) -> TextTestResult
|
|
11
|
+
|
|
12
|
+
Run self-test, and return `unittest.runner.TextTestResult` object.
|
|
13
|
+
"""
|
|
14
|
+
from bsdiff4.tests import run
|
|
11
15
|
return run(verbosity=verbosity)
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from argparse import ArgumentParser
|
|
3
|
+
from os.path import getsize
|
|
4
|
+
|
|
5
|
+
import bsdiff4.core as core # type: ignore
|
|
6
|
+
from bsdiff4 import __version__
|
|
7
|
+
from bsdiff4.format import (file_diff, file_patch, read_patch,
|
|
8
|
+
unpack_header, unpack_control_block)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def human_bytes(n):
|
|
12
|
+
"""
|
|
13
|
+
return the number of bytes 'n' in more human readable form
|
|
14
|
+
"""
|
|
15
|
+
if n < 1024:
|
|
16
|
+
return '%d B' % n
|
|
17
|
+
k = n / 1024
|
|
18
|
+
if k < 1024:
|
|
19
|
+
return '%.1f K' % k
|
|
20
|
+
m = k / 1024
|
|
21
|
+
if m < 1024:
|
|
22
|
+
return '%.1f M' % m
|
|
23
|
+
g = m / 1024
|
|
24
|
+
return '%.2f G' % g
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def show_filesizes(*args):
|
|
28
|
+
for i, name in enumerate(['src', 'dst', 'patch']):
|
|
29
|
+
size = getsize(args[i])
|
|
30
|
+
print('%s: %s (%s)' % (name, args[i], human_bytes(size)))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def show_header(fi):
|
|
34
|
+
total_len = fi.seek(0, 2) # go to EOF and return position
|
|
35
|
+
fi.seek(0)
|
|
36
|
+
control_len, diff_len, dst_len = unpack_header(fi.read(32))
|
|
37
|
+
print("sizes:")
|
|
38
|
+
for name, size in [
|
|
39
|
+
('total', total_len),
|
|
40
|
+
('control', control_len),
|
|
41
|
+
('diff', diff_len),
|
|
42
|
+
('extra', total_len - 32 - control_len - diff_len),
|
|
43
|
+
('dst', dst_len),
|
|
44
|
+
]:
|
|
45
|
+
print('%10s: %10d (%s)' % (name, size, human_bytes(size)))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def show_control(control_block, verbose=False):
|
|
49
|
+
print('\nnumber of control tuples: %d' % (len(control_block) // 24))
|
|
50
|
+
print('%10s %10s %10s %10s' % ('x', 'y', 'z', 'src pos'))
|
|
51
|
+
omitted = False
|
|
52
|
+
src_pos = 0
|
|
53
|
+
totals = (0, 0) # x, y totals
|
|
54
|
+
for i, (x, y, z) in enumerate(unpack_control_block(control_block)):
|
|
55
|
+
if i < 5 or verbose:
|
|
56
|
+
print('%10d %10d %10d %10d' % (x, y, z, src_pos))
|
|
57
|
+
else:
|
|
58
|
+
omitted = True
|
|
59
|
+
totals = (totals[0] + x, totals[1] + y)
|
|
60
|
+
src_pos += x + z
|
|
61
|
+
|
|
62
|
+
if omitted:
|
|
63
|
+
print('%10s %10s %10s' % (3 * ('...',)))
|
|
64
|
+
print('%10s %10s' % (2 * ('------',)))
|
|
65
|
+
print('%10d %10d' % totals)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def show_patch(fi, verbose=False):
|
|
69
|
+
show_header(fi)
|
|
70
|
+
fi.seek(0)
|
|
71
|
+
control_block, diff_block, extra_block = read_patch(fi)
|
|
72
|
+
print("\nuncompressed block sizes:")
|
|
73
|
+
for name, size in [
|
|
74
|
+
('control', len(control_block)),
|
|
75
|
+
('diff', len(diff_block)),
|
|
76
|
+
('extra', len(extra_block)),
|
|
77
|
+
]:
|
|
78
|
+
note = ""
|
|
79
|
+
if name == 'diff' and diff_block:
|
|
80
|
+
nonzero = len(diff_block) - diff_block.count(b'\x00')
|
|
81
|
+
note = ' (non-zero bytes: %d)' % nonzero
|
|
82
|
+
print('%10s: %10d (%s)%s' % (name, size, human_bytes(size), note))
|
|
83
|
+
|
|
84
|
+
show_control(control_block, verbose)
|
|
85
|
+
# validate patch by applying it to empty source
|
|
86
|
+
core.patch(b'', control_block, diff_block, extra_block)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def main_bsdiff4():
|
|
90
|
+
"""
|
|
91
|
+
Generate a BSDIFF4-format PATCH from SRC to DST and write it to PATCH.
|
|
92
|
+
"""
|
|
93
|
+
p = ArgumentParser(description=main_bsdiff4.__doc__)
|
|
94
|
+
p.add_argument('-v', '--verbose', action='store_true',
|
|
95
|
+
help="show file sizes")
|
|
96
|
+
p.add_argument('--version', action='version',
|
|
97
|
+
version="bsdiff4 %s" % __version__)
|
|
98
|
+
p.add_argument('src', metavar='SRC')
|
|
99
|
+
p.add_argument('dst', metavar='DST')
|
|
100
|
+
p.add_argument('patch', metavar='PATCH')
|
|
101
|
+
args = p.parse_args()
|
|
102
|
+
|
|
103
|
+
paths = args.src, args.dst, args.patch
|
|
104
|
+
try:
|
|
105
|
+
file_diff(*paths)
|
|
106
|
+
except (OSError, MemoryError) as e:
|
|
107
|
+
sys.exit("%s: %s" % (p.prog, str(e) or type(e).__name__))
|
|
108
|
+
if args.verbose:
|
|
109
|
+
show_filesizes(*paths)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def main_bspatch4():
|
|
113
|
+
"""
|
|
114
|
+
Generate DST by applying the BSDIFF4-format PATCH file to SRC;
|
|
115
|
+
with only PATCH, display information about and verify the patch.
|
|
116
|
+
"""
|
|
117
|
+
p = ArgumentParser(
|
|
118
|
+
usage="%(prog)s [options] SRC DST PATCH\n"
|
|
119
|
+
" %(prog)s [options] PATCH",
|
|
120
|
+
description=main_bspatch4.__doc__,
|
|
121
|
+
)
|
|
122
|
+
p.add_argument('-v', '--verbose', action='store_true',
|
|
123
|
+
help="show file sizes or all control tuples")
|
|
124
|
+
p.add_argument('--version', action='version',
|
|
125
|
+
version="bsdiff4 %s" % __version__)
|
|
126
|
+
p.add_argument('paths', nargs='+', metavar='PATH')
|
|
127
|
+
args = p.parse_args()
|
|
128
|
+
|
|
129
|
+
if len(args.paths) == 1:
|
|
130
|
+
try:
|
|
131
|
+
with open(args.paths[0], 'rb') as fi:
|
|
132
|
+
show_patch(fi, args.verbose)
|
|
133
|
+
except (ValueError, OSError, MemoryError) as e:
|
|
134
|
+
sys.exit("%s: %s" % (p.prog, str(e) or type(e).__name__))
|
|
135
|
+
return
|
|
136
|
+
|
|
137
|
+
if len(args.paths) != 3:
|
|
138
|
+
p.error("requires either PATCH or SRC DST PATCH")
|
|
139
|
+
|
|
140
|
+
try:
|
|
141
|
+
file_patch(*args.paths)
|
|
142
|
+
except (ValueError, OSError, MemoryError) as e:
|
|
143
|
+
sys.exit("%s: %s" % (p.prog, str(e) or type(e).__name__))
|
|
144
|
+
if args.verbose:
|
|
145
|
+
show_filesizes(*args.paths)
|