2 """This is a pre-commit hook that checks whether the contents of PO files
3 committed to the repository are encoded in UTF-8.
9 from svn
import core
, fs
, delta
, repos
11 # Set to the path of the 'msgfmt' executable to use msgfmt to check
12 # the syntax of the po file
16 if USE_MSGFMT
is not None:
20 self
.pipe
= popen2
.Popen3("%s -c -o /dev/null -" % (USE_MSGFMT
))
21 self
.pipe
.fromchild
.close()
24 def write(self
, data
):
28 self
.pipe
.tochild
.write(data
)
34 self
.pipe
.tochild
.close()
37 return self
.pipe
.wait() == 0 and not self
.io_error
40 def write(self
, data
):
46 class ChangeReceiver(delta
.Editor
):
47 def __init__(self
, txn_root
, base_root
, pool
):
48 self
.txn_root
= txn_root
49 self
.base_root
= base_root
52 def add_file(self
, path
, parent_baton
,
53 copyfrom_path
, copyfrom_revision
, file_pool
):
56 def open_file(self
, path
, parent_baton
, base_revision
, file_pool
):
59 def apply_textdelta(self
, file_baton
, base_checksum
):
64 def close_file(self
, file_baton
, text_checksum
):
65 changed
, path
= file_baton
66 if len(path
) < 3 or path
[-3:] != '.po' or not changed
:
67 # This is not a .po file, or it hasn't changed
71 # Read the file contents through a validating UTF-8 decoder
72 subpool
= core
.svn_pool_create(self
.pool
)
73 checker
= MsgFmtChecker()
75 stream
= core
.Stream(fs
.file_contents(self
.txn_root
, path
, subpool
))
76 reader
= codecs
.getreader('UTF-8')(stream
, 'strict')
77 writer
= codecs
.getwriter('UTF-8')(checker
, 'strict')
79 data
= reader
.read(core
.SVN_STREAM_CHUNK_SIZE
)
83 if not checker
.close():
84 sys
.exit("PO format check failed for '" + path
+ "'")
86 sys
.exit("PO file is not in UTF-8: '" + path
+ "'")
88 core
.svn_pool_destroy(subpool
)
91 def check_po(pool
, repos_path
, txn
):
92 def authz_cb(root
, path
, pool
):
95 fs_ptr
= repos
.fs(repos
.open(repos_path
, pool
))
96 txn_ptr
= fs
.open_txn(fs_ptr
, txn
, pool
)
97 txn_root
= fs
.txn_root(txn_ptr
, pool
)
98 base_root
= fs
.revision_root(fs_ptr
, fs
.txn_base_revision(txn_ptr
), pool
)
99 editor
= ChangeReceiver(txn_root
, base_root
, pool
)
100 e_ptr
, e_baton
= delta
.make_editor(editor
, pool
)
101 repos
.dir_delta(base_root
, '', '', txn_root
, '',
102 e_ptr
, e_baton
, authz_cb
, 0, 1, 0, 0, pool
)
105 if __name__
== '__main__':
106 assert len(sys
.argv
) == 3
107 core
.run_app(check_po
, sys
.argv
[1], sys
.argv
[2])