##// END OF EJS Templates
win32text: give deprecation warning...
Steve Borho -
r12837:c82056f2 stable
parent child Browse files
Show More
@@ -1,166 +1,170 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 # Copyright 2005, 2007-2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2005, 2007-2009 Matt Mackall <mpm@selenic.com> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 '''perform automatic newline conversion
8 '''perform automatic newline conversion
9
9
10 Deprecation: The win32text extension requires each user to configure
10 Deprecation: The win32text extension requires each user to configure
11 the extension again and again for each clone since the configuration
11 the extension again and again for each clone since the configuration
12 is not copied when cloning.
12 is not copied when cloning.
13
13
14 We have therefore made the ``eol`` as an alternative. The ``eol``
14 We have therefore made the ``eol`` as an alternative. The ``eol``
15 uses a version controlled file for its configuration and each clone
15 uses a version controlled file for its configuration and each clone
16 will therefore use the right settings from the start.
16 will therefore use the right settings from the start.
17
17
18 To perform automatic newline conversion, use::
18 To perform automatic newline conversion, use::
19
19
20 [extensions]
20 [extensions]
21 win32text =
21 win32text =
22 [encode]
22 [encode]
23 ** = cleverencode:
23 ** = cleverencode:
24 # or ** = macencode:
24 # or ** = macencode:
25
25
26 [decode]
26 [decode]
27 ** = cleverdecode:
27 ** = cleverdecode:
28 # or ** = macdecode:
28 # or ** = macdecode:
29
29
30 If not doing conversion, to make sure you do not commit CRLF/CR by accident::
30 If not doing conversion, to make sure you do not commit CRLF/CR by accident::
31
31
32 [hooks]
32 [hooks]
33 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
33 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
34 # or pretxncommit.cr = python:hgext.win32text.forbidcr
34 # or pretxncommit.cr = python:hgext.win32text.forbidcr
35
35
36 To do the same check on a server to prevent CRLF/CR from being
36 To do the same check on a server to prevent CRLF/CR from being
37 pushed or pulled::
37 pushed or pulled::
38
38
39 [hooks]
39 [hooks]
40 pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
40 pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
41 # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
41 # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
42 '''
42 '''
43
43
44 from mercurial.i18n import _
44 from mercurial.i18n import _
45 from mercurial.node import short
45 from mercurial.node import short
46 from mercurial import util
46 from mercurial import util
47 import re
47 import re
48
48
49 # regexp for single LF without CR preceding.
49 # regexp for single LF without CR preceding.
50 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
50 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
51
51
52 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
52 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
53 filterstr = {'\r\n': 'clever', '\r': 'mac'}
53 filterstr = {'\r\n': 'clever', '\r': 'mac'}
54
54
55 def checknewline(s, newline, ui=None, repo=None, filename=None):
55 def checknewline(s, newline, ui=None, repo=None, filename=None):
56 # warn if already has 'newline' in repository.
56 # warn if already has 'newline' in repository.
57 # it might cause unexpected eol conversion.
57 # it might cause unexpected eol conversion.
58 # see issue 302:
58 # see issue 302:
59 # http://mercurial.selenic.com/bts/issue302
59 # http://mercurial.selenic.com/bts/issue302
60 if newline in s and ui and filename and repo:
60 if newline in s and ui and filename and repo:
61 ui.warn(_('WARNING: %s already has %s line endings\n'
61 ui.warn(_('WARNING: %s already has %s line endings\n'
62 'and does not need EOL conversion by the win32text plugin.\n'
62 'and does not need EOL conversion by the win32text plugin.\n'
63 'Before your next commit, please reconsider your '
63 'Before your next commit, please reconsider your '
64 'encode/decode settings in \nMercurial.ini or %s.\n') %
64 'encode/decode settings in \nMercurial.ini or %s.\n') %
65 (filename, newlinestr[newline], repo.join('hgrc')))
65 (filename, newlinestr[newline], repo.join('hgrc')))
66
66
67 def dumbdecode(s, cmd, **kwargs):
67 def dumbdecode(s, cmd, **kwargs):
68 checknewline(s, '\r\n', **kwargs)
68 checknewline(s, '\r\n', **kwargs)
69 # replace single LF to CRLF
69 # replace single LF to CRLF
70 return re_single_lf.sub('\\1\r\n', s)
70 return re_single_lf.sub('\\1\r\n', s)
71
71
72 def dumbencode(s, cmd):
72 def dumbencode(s, cmd):
73 return s.replace('\r\n', '\n')
73 return s.replace('\r\n', '\n')
74
74
75 def macdumbdecode(s, cmd, **kwargs):
75 def macdumbdecode(s, cmd, **kwargs):
76 checknewline(s, '\r', **kwargs)
76 checknewline(s, '\r', **kwargs)
77 return s.replace('\n', '\r')
77 return s.replace('\n', '\r')
78
78
79 def macdumbencode(s, cmd):
79 def macdumbencode(s, cmd):
80 return s.replace('\r', '\n')
80 return s.replace('\r', '\n')
81
81
82 def cleverdecode(s, cmd, **kwargs):
82 def cleverdecode(s, cmd, **kwargs):
83 if not util.binary(s):
83 if not util.binary(s):
84 return dumbdecode(s, cmd, **kwargs)
84 return dumbdecode(s, cmd, **kwargs)
85 return s
85 return s
86
86
87 def cleverencode(s, cmd):
87 def cleverencode(s, cmd):
88 if not util.binary(s):
88 if not util.binary(s):
89 return dumbencode(s, cmd)
89 return dumbencode(s, cmd)
90 return s
90 return s
91
91
92 def macdecode(s, cmd, **kwargs):
92 def macdecode(s, cmd, **kwargs):
93 if not util.binary(s):
93 if not util.binary(s):
94 return macdumbdecode(s, cmd, **kwargs)
94 return macdumbdecode(s, cmd, **kwargs)
95 return s
95 return s
96
96
97 def macencode(s, cmd):
97 def macencode(s, cmd):
98 if not util.binary(s):
98 if not util.binary(s):
99 return macdumbencode(s, cmd)
99 return macdumbencode(s, cmd)
100 return s
100 return s
101
101
102 _filters = {
102 _filters = {
103 'dumbdecode:': dumbdecode,
103 'dumbdecode:': dumbdecode,
104 'dumbencode:': dumbencode,
104 'dumbencode:': dumbencode,
105 'cleverdecode:': cleverdecode,
105 'cleverdecode:': cleverdecode,
106 'cleverencode:': cleverencode,
106 'cleverencode:': cleverencode,
107 'macdumbdecode:': macdumbdecode,
107 'macdumbdecode:': macdumbdecode,
108 'macdumbencode:': macdumbencode,
108 'macdumbencode:': macdumbencode,
109 'macdecode:': macdecode,
109 'macdecode:': macdecode,
110 'macencode:': macencode,
110 'macencode:': macencode,
111 }
111 }
112
112
113 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
113 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
114 halt = False
114 halt = False
115 seen = set()
115 seen = set()
116 # we try to walk changesets in reverse order from newest to
116 # we try to walk changesets in reverse order from newest to
117 # oldest, so that if we see a file multiple times, we take the
117 # oldest, so that if we see a file multiple times, we take the
118 # newest version as canonical. this prevents us from blocking a
118 # newest version as canonical. this prevents us from blocking a
119 # changegroup that contains an unacceptable commit followed later
119 # changegroup that contains an unacceptable commit followed later
120 # by a commit that fixes the problem.
120 # by a commit that fixes the problem.
121 tip = repo['tip']
121 tip = repo['tip']
122 for rev in xrange(len(repo)-1, repo[node].rev()-1, -1):
122 for rev in xrange(len(repo)-1, repo[node].rev()-1, -1):
123 c = repo[rev]
123 c = repo[rev]
124 for f in c.files():
124 for f in c.files():
125 if f in seen or f not in tip or f not in c:
125 if f in seen or f not in tip or f not in c:
126 continue
126 continue
127 seen.add(f)
127 seen.add(f)
128 data = c[f].data()
128 data = c[f].data()
129 if not util.binary(data) and newline in data:
129 if not util.binary(data) and newline in data:
130 if not halt:
130 if not halt:
131 ui.warn(_('Attempt to commit or push text file(s) '
131 ui.warn(_('Attempt to commit or push text file(s) '
132 'using %s line endings\n') %
132 'using %s line endings\n') %
133 newlinestr[newline])
133 newlinestr[newline])
134 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
134 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
135 halt = True
135 halt = True
136 if halt and hooktype == 'pretxnchangegroup':
136 if halt and hooktype == 'pretxnchangegroup':
137 crlf = newlinestr[newline].lower()
137 crlf = newlinestr[newline].lower()
138 filter = filterstr[newline]
138 filter = filterstr[newline]
139 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
139 ui.warn(_('\nTo prevent this mistake in your local repository,\n'
140 'add to Mercurial.ini or .hg/hgrc:\n'
140 'add to Mercurial.ini or .hg/hgrc:\n'
141 '\n'
141 '\n'
142 '[hooks]\n'
142 '[hooks]\n'
143 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
143 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
144 '\n'
144 '\n'
145 'and also consider adding:\n'
145 'and also consider adding:\n'
146 '\n'
146 '\n'
147 '[extensions]\n'
147 '[extensions]\n'
148 'win32text =\n'
148 'win32text =\n'
149 '[encode]\n'
149 '[encode]\n'
150 '** = %sencode:\n'
150 '** = %sencode:\n'
151 '[decode]\n'
151 '[decode]\n'
152 '** = %sdecode:\n') % (crlf, crlf, filter, filter))
152 '** = %sdecode:\n') % (crlf, crlf, filter, filter))
153 return halt
153 return halt
154
154
155 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
155 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
156 return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs)
156 return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs)
157
157
158 def forbidcr(ui, repo, hooktype, node, **kwargs):
158 def forbidcr(ui, repo, hooktype, node, **kwargs):
159 return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs)
159 return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs)
160
160
161 def reposetup(ui, repo):
161 def reposetup(ui, repo):
162 if not repo.local():
162 if not repo.local():
163 return
163 return
164 for name, fn in _filters.iteritems():
164 for name, fn in _filters.iteritems():
165 repo.adddatafilter(name, fn)
165 repo.adddatafilter(name, fn)
166
166
167 def extsetup(ui):
168 if ui.configbool('win32text', 'warn', True):
169 ui.warn(_("win32text is deprecated: "
170 "http://mercurial.selenic.com/wiki/Win32TextExtension\n"))
General Comments 0
You need to be logged in to leave comments. Login now