comparison hgext/win32text.py @ 43076:2372284d9457

formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:45:02 -0400
parents e7aa113b14f7
children 687b865b95ad
comparison
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
43 43
44 from __future__ import absolute_import 44 from __future__ import absolute_import
45 45
46 import re 46 import re
47 from mercurial.i18n import _ 47 from mercurial.i18n import _
48 from mercurial.node import ( 48 from mercurial.node import short
49 short,
50 )
51 from mercurial import ( 49 from mercurial import (
52 pycompat, 50 pycompat,
53 registrar, 51 registrar,
54 ) 52 )
55 from mercurial.utils import ( 53 from mercurial.utils import stringutil
56 stringutil,
57 )
58 54
59 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for 55 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
60 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should 56 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
61 # be specifying the version(s) of Mercurial they are tested with, or 57 # be specifying the version(s) of Mercurial they are tested with, or
62 # leave the attribute unspecified. 58 # leave the attribute unspecified.
63 testedwith = 'ships-with-hg-core' 59 testedwith = 'ships-with-hg-core'
64 60
65 configtable = {} 61 configtable = {}
66 configitem = registrar.configitem(configtable) 62 configitem = registrar.configitem(configtable)
67 63
68 configitem('win32text', 'warn', 64 configitem(
69 default=True, 65 'win32text', 'warn', default=True,
70 ) 66 )
71 67
72 # regexp for single LF without CR preceding. 68 # regexp for single LF without CR preceding.
73 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE) 69 re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
74 70
75 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'} 71 newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
76 filterstr = {'\r\n': 'clever', '\r': 'mac'} 72 filterstr = {'\r\n': 'clever', '\r': 'mac'}
73
77 74
78 def checknewline(s, newline, ui=None, repo=None, filename=None): 75 def checknewline(s, newline, ui=None, repo=None, filename=None):
79 # warn if already has 'newline' in repository. 76 # warn if already has 'newline' in repository.
80 # it might cause unexpected eol conversion. 77 # it might cause unexpected eol conversion.
81 # see issue 302: 78 # see issue 302:
82 # https://bz.mercurial-scm.org/302 79 # https://bz.mercurial-scm.org/302
83 if newline in s and ui and filename and repo: 80 if newline in s and ui and filename and repo:
84 ui.warn(_('WARNING: %s already has %s line endings\n' 81 ui.warn(
85 'and does not need EOL conversion by the win32text plugin.\n' 82 _(
86 'Before your next commit, please reconsider your ' 83 'WARNING: %s already has %s line endings\n'
87 'encode/decode settings in \nMercurial.ini or %s.\n') % 84 'and does not need EOL conversion by the win32text plugin.\n'
88 (filename, newlinestr[newline], repo.vfs.join('hgrc'))) 85 'Before your next commit, please reconsider your '
86 'encode/decode settings in \nMercurial.ini or %s.\n'
87 )
88 % (filename, newlinestr[newline], repo.vfs.join('hgrc'))
89 )
90
89 91
90 def dumbdecode(s, cmd, **kwargs): 92 def dumbdecode(s, cmd, **kwargs):
91 checknewline(s, '\r\n', **kwargs) 93 checknewline(s, '\r\n', **kwargs)
92 # replace single LF to CRLF 94 # replace single LF to CRLF
93 return re_single_lf.sub('\\1\r\n', s) 95 return re_single_lf.sub('\\1\r\n', s)
94 96
97
95 def dumbencode(s, cmd): 98 def dumbencode(s, cmd):
96 return s.replace('\r\n', '\n') 99 return s.replace('\r\n', '\n')
100
97 101
98 def macdumbdecode(s, cmd, **kwargs): 102 def macdumbdecode(s, cmd, **kwargs):
99 checknewline(s, '\r', **kwargs) 103 checknewline(s, '\r', **kwargs)
100 return s.replace('\n', '\r') 104 return s.replace('\n', '\r')
101 105
106
102 def macdumbencode(s, cmd): 107 def macdumbencode(s, cmd):
103 return s.replace('\r', '\n') 108 return s.replace('\r', '\n')
104 109
110
105 def cleverdecode(s, cmd, **kwargs): 111 def cleverdecode(s, cmd, **kwargs):
106 if not stringutil.binary(s): 112 if not stringutil.binary(s):
107 return dumbdecode(s, cmd, **kwargs) 113 return dumbdecode(s, cmd, **kwargs)
108 return s 114 return s
109 115
116
110 def cleverencode(s, cmd): 117 def cleverencode(s, cmd):
111 if not stringutil.binary(s): 118 if not stringutil.binary(s):
112 return dumbencode(s, cmd) 119 return dumbencode(s, cmd)
113 return s 120 return s
114 121
122
115 def macdecode(s, cmd, **kwargs): 123 def macdecode(s, cmd, **kwargs):
116 if not stringutil.binary(s): 124 if not stringutil.binary(s):
117 return macdumbdecode(s, cmd, **kwargs) 125 return macdumbdecode(s, cmd, **kwargs)
118 return s 126 return s
119 127
128
120 def macencode(s, cmd): 129 def macencode(s, cmd):
121 if not stringutil.binary(s): 130 if not stringutil.binary(s):
122 return macdumbencode(s, cmd) 131 return macdumbencode(s, cmd)
123 return s 132 return s
133
124 134
125 _filters = { 135 _filters = {
126 'dumbdecode:': dumbdecode, 136 'dumbdecode:': dumbdecode,
127 'dumbencode:': dumbencode, 137 'dumbencode:': dumbencode,
128 'cleverdecode:': cleverdecode, 138 'cleverdecode:': cleverdecode,
129 'cleverencode:': cleverencode, 139 'cleverencode:': cleverencode,
130 'macdumbdecode:': macdumbdecode, 140 'macdumbdecode:': macdumbdecode,
131 'macdumbencode:': macdumbencode, 141 'macdumbencode:': macdumbencode,
132 'macdecode:': macdecode, 142 'macdecode:': macdecode,
133 'macencode:': macencode, 143 'macencode:': macencode,
134 } 144 }
145
135 146
136 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs): 147 def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
137 halt = False 148 halt = False
138 seen = set() 149 seen = set()
139 # we try to walk changesets in reverse order from newest to 150 # we try to walk changesets in reverse order from newest to
140 # oldest, so that if we see a file multiple times, we take the 151 # oldest, so that if we see a file multiple times, we take the
141 # newest version as canonical. this prevents us from blocking a 152 # newest version as canonical. this prevents us from blocking a
142 # changegroup that contains an unacceptable commit followed later 153 # changegroup that contains an unacceptable commit followed later
143 # by a commit that fixes the problem. 154 # by a commit that fixes the problem.
144 tip = repo['tip'] 155 tip = repo['tip']
145 for rev in pycompat.xrange(repo.changelog.tiprev(), 156 for rev in pycompat.xrange(
146 repo[node].rev() - 1, -1): 157 repo.changelog.tiprev(), repo[node].rev() - 1, -1
158 ):
147 c = repo[rev] 159 c = repo[rev]
148 for f in c.files(): 160 for f in c.files():
149 if f in seen or f not in tip or f not in c: 161 if f in seen or f not in tip or f not in c:
150 continue 162 continue
151 seen.add(f) 163 seen.add(f)
152 data = c[f].data() 164 data = c[f].data()
153 if not stringutil.binary(data) and newline in data: 165 if not stringutil.binary(data) and newline in data:
154 if not halt: 166 if not halt:
155 ui.warn(_('attempt to commit or push text file(s) ' 167 ui.warn(
156 'using %s line endings\n') % 168 _(
157 newlinestr[newline]) 169 'attempt to commit or push text file(s) '
170 'using %s line endings\n'
171 )
172 % newlinestr[newline]
173 )
158 ui.warn(_('in %s: %s\n') % (short(c.node()), f)) 174 ui.warn(_('in %s: %s\n') % (short(c.node()), f))
159 halt = True 175 halt = True
160 if halt and hooktype == 'pretxnchangegroup': 176 if halt and hooktype == 'pretxnchangegroup':
161 crlf = newlinestr[newline].lower() 177 crlf = newlinestr[newline].lower()
162 filter = filterstr[newline] 178 filter = filterstr[newline]
163 ui.warn(_('\nTo prevent this mistake in your local repository,\n' 179 ui.warn(
164 'add to Mercurial.ini or .hg/hgrc:\n' 180 _(
165 '\n' 181 '\nTo prevent this mistake in your local repository,\n'
166 '[hooks]\n' 182 'add to Mercurial.ini or .hg/hgrc:\n'
167 'pretxncommit.%s = python:hgext.win32text.forbid%s\n' 183 '\n'
168 '\n' 184 '[hooks]\n'
169 'and also consider adding:\n' 185 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
170 '\n' 186 '\n'
171 '[extensions]\n' 187 'and also consider adding:\n'
172 'win32text =\n' 188 '\n'
173 '[encode]\n' 189 '[extensions]\n'
174 '** = %sencode:\n' 190 'win32text =\n'
175 '[decode]\n' 191 '[encode]\n'
176 '** = %sdecode:\n') % (crlf, crlf, filter, filter)) 192 '** = %sencode:\n'
193 '[decode]\n'
194 '** = %sdecode:\n'
195 )
196 % (crlf, crlf, filter, filter)
197 )
177 return halt 198 return halt
199
178 200
179 def forbidcrlf(ui, repo, hooktype, node, **kwargs): 201 def forbidcrlf(ui, repo, hooktype, node, **kwargs):
180 return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs) 202 return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs)
181 203
204
182 def forbidcr(ui, repo, hooktype, node, **kwargs): 205 def forbidcr(ui, repo, hooktype, node, **kwargs):
183 return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs) 206 return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs)
207
184 208
185 def reposetup(ui, repo): 209 def reposetup(ui, repo):
186 if not repo.local(): 210 if not repo.local():
187 return 211 return
188 for name, fn in _filters.iteritems(): 212 for name, fn in _filters.iteritems():
189 repo.adddatafilter(name, fn) 213 repo.adddatafilter(name, fn)
190 214
215
191 def extsetup(ui): 216 def extsetup(ui):
192 # deprecated config: win32text.warn 217 # deprecated config: win32text.warn
193 if ui.configbool('win32text', 'warn'): 218 if ui.configbool('win32text', 'warn'):
194 ui.warn(_("win32text is deprecated: " 219 ui.warn(
195 "https://mercurial-scm.org/wiki/Win32TextExtension\n")) 220 _(
221 "win32text is deprecated: "
222 "https://mercurial-scm.org/wiki/Win32TextExtension\n"
223 )
224 )