##// END OF EJS Templates
win32text: actually import util so util.binary() can be used
Dirkjan Ochtman -
r6510:37ab2331 default
parent child Browse files
Show More
@@ -1,143 +1,144 b''
1 # win32text.py - LF <-> CRLF/CR translation utilities for Windows/Mac users
1 # win32text.py - LF <-> CRLF/CR translation utilities for Windows/Mac users
2 #
2 #
3 # This software may be used and distributed according to the terms
3 # This software may be used and distributed according to the terms
4 # of the GNU General Public License, incorporated herein by reference.
4 # of the GNU General Public License, incorporated herein by reference.
5 #
5 #
6 # To perform automatic newline conversion, use:
6 # To perform automatic newline conversion, use:
7 #
7 #
8 # [extensions]
8 # [extensions]
9 # hgext.win32text =
9 # hgext.win32text =
10 # [encode]
10 # [encode]
11 # ** = cleverencode:
11 # ** = cleverencode:
12 # # or ** = macencode:
12 # # or ** = macencode:
13 # [decode]
13 # [decode]
14 # ** = cleverdecode:
14 # ** = cleverdecode:
15 # # or ** = macdecode:
15 # # or ** = macdecode:
16 #
16 #
17 # If not doing conversion, to make sure you do not commit CRLF/CR by accident:
17 # If not doing conversion, to make sure you do not commit CRLF/CR by accident:
18 #
18 #
19 # [hooks]
19 # [hooks]
20 # pretxncommit.crlf = python:hgext.win32text.forbidcrlf
20 # pretxncommit.crlf = python:hgext.win32text.forbidcrlf
21 # # or pretxncommit.cr = python:hgext.win32text.forbidcr
21 # # or pretxncommit.cr = python:hgext.win32text.forbidcr
22 #
22 #
23 # To do the same check on a server to prevent CRLF/CR from being pushed or
23 # To do the same check on a server to prevent CRLF/CR from being pushed or
24 # pulled:
24 # pulled:
25 #
25 #
26 # [hooks]
26 # [hooks]
27 # pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
27 # pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
28 # # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
28 # # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
29
29
30 from mercurial.i18n import gettext as _
30 from mercurial.i18n import gettext as _
31 from mercurial.node import bin, short
31 from mercurial.node import bin, short
32 from mercurial import util
32 import re
33 import re
33
34
34 # regexp for single LF without CR preceding.
35 # regexp for single LF without CR preceding.
35 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
36 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
36
37
37 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
38 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
38 filterstr = {'\r\n': 'clever', '\r': 'mac'}
39 filterstr = {'\r\n': 'clever', '\r': 'mac'}
39
40
40 def checknewline(s, newline, ui=None, repo=None, filename=None):
41 def checknewline(s, newline, ui=None, repo=None, filename=None):
41 # warn if already has 'newline' in repository.
42 # warn if already has 'newline' in repository.
42 # it might cause unexpected eol conversion.
43 # it might cause unexpected eol conversion.
43 # see issue 302:
44 # see issue 302:
44 # http://www.selenic.com/mercurial/bts/issue302
45 # http://www.selenic.com/mercurial/bts/issue302
45 if newline in s and ui and filename and repo:
46 if newline in s and ui and filename and repo:
46 ui.warn(_('WARNING: %s already has %s line endings\n'
47 ui.warn(_('WARNING: %s already has %s line endings\n'
47 'and does not need EOL conversion by the win32text plugin.\n'
48 'and does not need EOL conversion by the win32text plugin.\n'
48 'Before your next commit, please reconsider your '
49 'Before your next commit, please reconsider your '
49 'encode/decode settings in \nMercurial.ini or %s.\n') %
50 'encode/decode settings in \nMercurial.ini or %s.\n') %
50 (filename, newlinestr[newline], repo.join('hgrc')))
51 (filename, newlinestr[newline], repo.join('hgrc')))
51
52
52 def dumbdecode(s, cmd, **kwargs):
53 def dumbdecode(s, cmd, **kwargs):
53 checknewline(s, '\r\n', **kwargs)
54 checknewline(s, '\r\n', **kwargs)
54 # replace single LF to CRLF
55 # replace single LF to CRLF
55 return re_single_lf.sub('\\1\r\n', s)
56 return re_single_lf.sub('\\1\r\n', s)
56
57
57 def dumbencode(s, cmd):
58 def dumbencode(s, cmd):
58 return s.replace('\r\n', '\n')
59 return s.replace('\r\n', '\n')
59
60
60 def macdumbdecode(s, cmd, **kwargs):
61 def macdumbdecode(s, cmd, **kwargs):
61 checknewline(s, '\r', **kwargs)
62 checknewline(s, '\r', **kwargs)
62 return s.replace('\n', '\r')
63 return s.replace('\n', '\r')
63
64
64 def macdumbencode(s, cmd):
65 def macdumbencode(s, cmd):
65 return s.replace('\r', '\n')
66 return s.replace('\r', '\n')
66
67
67 def cleverdecode(s, cmd, **kwargs):
68 def cleverdecode(s, cmd, **kwargs):
68 if not util.binary(s):
69 if not util.binary(s):
69 return dumbdecode(s, cmd, **kwargs)
70 return dumbdecode(s, cmd, **kwargs)
70 return s
71 return s
71
72
72 def cleverencode(s, cmd):
73 def cleverencode(s, cmd):
73 if not util.binary(s):
74 if not util.binary(s):
74 return dumbencode(s, cmd)
75 return dumbencode(s, cmd)
75 return s
76 return s
76
77
77 def macdecode(s, cmd, **kwargs):
78 def macdecode(s, cmd, **kwargs):
78 if not util.binary(s):
79 if not util.binary(s):
79 return macdumbdecode(s, cmd, **kwargs)
80 return macdumbdecode(s, cmd, **kwargs)
80 return s
81 return s
81
82
82 def macencode(s, cmd):
83 def macencode(s, cmd):
83 if not util.binary(s):
84 if not util.binary(s):
84 return macdumbencode(s, cmd)
85 return macdumbencode(s, cmd)
85 return s
86 return s
86
87
87 _filters = {
88 _filters = {
88 'dumbdecode:': dumbdecode,
89 'dumbdecode:': dumbdecode,
89 'dumbencode:': dumbencode,
90 'dumbencode:': dumbencode,
90 'cleverdecode:': cleverdecode,
91 'cleverdecode:': cleverdecode,
91 'cleverencode:': cleverencode,
92 'cleverencode:': cleverencode,
92 'macdumbdecode:': macdumbdecode,
93 'macdumbdecode:': macdumbdecode,
93 'macdumbencode:': macdumbencode,
94 'macdumbencode:': macdumbencode,
94 'macdecode:': macdecode,
95 'macdecode:': macdecode,
95 'macencode:': macencode,
96 'macencode:': macencode,
96 }
97 }
97
98
98 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
99 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
99 halt = False
100 halt = False
100 for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
101 for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
101 c = repo.changectx(rev)
102 c = repo.changectx(rev)
102 for f in c.files():
103 for f in c.files():
103 if f not in c:
104 if f not in c:
104 continue
105 continue
105 data = c[f].data()
106 data = c[f].data()
106 if not util.binary(data) and newline in data:
107 if not util.binary(data) and newline in data:
107 if not halt:
108 if not halt:
108 ui.warn(_('Attempt to commit or push text file(s) '
109 ui.warn(_('Attempt to commit or push text file(s) '
109 'using %s line endings\n') %
110 'using %s line endings\n') %
110 newlinestr[newline])
111 newlinestr[newline])
111 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
112 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
112 halt = True
113 halt = True
113 if halt and hooktype == 'pretxnchangegroup':
114 if halt and hooktype == 'pretxnchangegroup':
114 crlf = newlinestr[newline].lower()
115 crlf = newlinestr[newline].lower()
115 filter = filterstr[newline]
116 filter = filterstr[newline]
116 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
117 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
117 'add to Mercurial.ini or .hg/hgrc:\n'
118 'add to Mercurial.ini or .hg/hgrc:\n'
118 '\n'
119 '\n'
119 '[hooks]\n'
120 '[hooks]\n'
120 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
121 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
121 '\n'
122 '\n'
122 'and also consider adding:\n'
123 'and also consider adding:\n'
123 '\n'
124 '\n'
124 '[extensions]\n'
125 '[extensions]\n'
125 'hgext.win32text =\n'
126 'hgext.win32text =\n'
126 '[encode]\n'
127 '[encode]\n'
127 '** = %sencode:\n'
128 '** = %sencode:\n'
128 '[decode]\n'
129 '[decode]\n'
129 '** = %sdecode:\n') % (crlf, crlf, filter, filter))
130 '** = %sdecode:\n') % (crlf, crlf, filter, filter))
130 return halt
131 return halt
131
132
132 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
133 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
133 return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs)
134 return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs)
134
135
135 def forbidcr(ui, repo, hooktype, node, **kwargs):
136 def forbidcr(ui, repo, hooktype, node, **kwargs):
136 return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs)
137 return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs)
137
138
138 def reposetup(ui, repo):
139 def reposetup(ui, repo):
139 if not repo.local():
140 if not repo.local():
140 return
141 return
141 for name, fn in _filters.iteritems():
142 for name, fn in _filters.iteritems():
142 repo.adddatafilter(name, fn)
143 repo.adddatafilter(name, fn)
143
144
General Comments 0
You need to be logged in to leave comments. Login now