Skip to content

Commit f722b99

Browse files
committed
Add FilterList.apply_to_buffer, apply_to_file, apply_to_blob
1 parent c57e714 commit f722b99

File tree

3 files changed

+103
-2
lines changed

3 files changed

+103
-2
lines changed

pygit2/decl/filter.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,23 @@ int git_filter_list_contains(
2626
git_filter_list *filters,
2727
const char *name);
2828

29+
int git_filter_list_apply_to_buffer(
30+
git_buf *out,
31+
git_filter_list *filters,
32+
const char* in,
33+
size_t in_len);
34+
35+
int git_filter_list_apply_to_file(
36+
git_buf *out,
37+
git_filter_list *filters,
38+
git_repository *repo,
39+
const char *path);
40+
41+
int git_filter_list_apply_to_blob(
42+
git_buf *out,
43+
git_filter_list *filters,
44+
git_blob *blob);
45+
2946
size_t git_filter_list_length(
3047
const git_filter_list *fl);
3148

pygit2/filter.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import weakref
2727
from collections.abc import Callable
2828

29-
from ._pygit2 import FilterSource, Repository
29+
from ._pygit2 import Blob, FilterSource, Repository
3030
from .errors import check_error
3131
from .ffi import C, ffi
3232
from .utils import to_bytes
@@ -146,5 +146,49 @@ def __contains__(self, name: str) -> bool:
146146
def __len__(self) -> int:
147147
return C.git_filter_list_length(self._pointer)
148148

149+
def apply_to_buffer(self, data: bytes) -> bytes:
150+
"""
151+
Apply a filter list to a data buffer.
152+
Return the filtered contents.
153+
"""
154+
buf = ffi.new('git_buf *')
155+
err = C.git_filter_list_apply_to_buffer(buf, self._pointer, data, len(data))
156+
check_error(err)
157+
try:
158+
return ffi.string(buf.ptr)
159+
finally:
160+
C.git_buf_dispose(buf)
161+
162+
def apply_to_file(self, repo: Repository, path: str) -> bytes:
163+
"""
164+
Apply a filter list to the contents of a file on disk.
165+
Return the filtered contents.
166+
"""
167+
buf = ffi.new('git_buf *')
168+
c_path = to_bytes(path)
169+
err = C.git_filter_list_apply_to_file(buf, self._pointer, repo._repo, c_path)
170+
check_error(err)
171+
try:
172+
return ffi.string(buf.ptr)
173+
finally:
174+
C.git_buf_dispose(buf)
175+
176+
def apply_to_blob(self, blob: Blob) -> bytes:
177+
"""
178+
Apply a filter list to a data buffer.
179+
Return the filtered contents.
180+
"""
181+
buf = ffi.new('git_buf *')
182+
183+
c_blob = ffi.new('git_blob **')
184+
ffi.buffer(c_blob)[:] = blob._pointer[:]
185+
186+
err = C.git_filter_list_apply_to_blob(buf, self._pointer, c_blob[0])
187+
check_error(err)
188+
try:
189+
return ffi.string(buf.ptr)
190+
finally:
191+
C.git_buf_dispose(buf)
192+
149193
def __del__(self):
150194
C.git_filter_list_free(self._pointer)

test/test_filter.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import pygit2
88
from pygit2 import Blob, Filter, FilterSource, Repository
9-
from pygit2.enums import BlobFilter
9+
from pygit2.enums import BlobFilter, FilterMode
1010
from pygit2.errors import Passthrough
1111

1212

@@ -155,6 +155,20 @@ def test_filterlist_crlf(testrepo: Repository) -> None:
155155
1234 in fl
156156

157157

158+
def test_filterlist_crlf_clean(testrepo: Repository) -> None:
159+
testrepo.config['core.autocrlf'] = True
160+
fl = testrepo.load_filter_list('whatever.txt', mode=FilterMode.CLEAN)
161+
filtered = fl.apply_to_buffer(b'hello\r\nworld\r\n')
162+
assert filtered == b'hello\nworld\n'
163+
164+
165+
def test_filterlist_crlf_smudge(testrepo: Repository) -> None:
166+
testrepo.config['core.autocrlf'] = True
167+
fl = testrepo.load_filter_list('whatever.txt', mode=FilterMode.SMUDGE)
168+
filtered = fl.apply_to_buffer(b'hello\nworld\n')
169+
assert filtered == b'hello\r\nworld\r\n'
170+
171+
158172
def test_filterlist_rot13(testrepo: Repository, rot13_filter: Filter) -> None:
159173
fl = testrepo.load_filter_list('hello.txt')
160174
assert fl is not None
@@ -177,3 +191,29 @@ def test_filterlist_rot13_dangerous_unregister(testrepo: Repository) -> None:
177191
# to unregister the filter.
178192
del fl
179193
pygit2.filter_unregister('rot13')
194+
195+
196+
def test_filterlist_rot13_apply_to_buffer(
197+
testrepo: Repository, rot13_filter: Filter
198+
) -> None:
199+
fl = testrepo.load_filter_list('whatever.txt')
200+
filtered = fl.apply_to_buffer(b'bye world\n')
201+
assert filtered == b'olr jbeyq\n'
202+
203+
204+
def test_filterlist_rot13_apply_to_file(
205+
testrepo: Repository, rot13_filter: Filter
206+
) -> None:
207+
fl = testrepo.load_filter_list('bye.txt')
208+
filtered = fl.apply_to_file(testrepo, 'bye.txt')
209+
assert filtered == b'olr jbeyq\n'
210+
211+
212+
def test_filterlist_rot13_apply_to_blob(
213+
testrepo: Repository, rot13_filter: Filter
214+
) -> None:
215+
fl = testrepo.load_filter_list('whatever.txt')
216+
blob_oid = testrepo.create_blob(b'bye world\n')
217+
blob = testrepo[blob_oid]
218+
filtered = fl.apply_to_blob(blob)
219+
assert filtered == b'olr jbeyq\n'

0 commit comments

Comments
 (0)