hgext/win32text.py
author Matt Mackall <mpm@selenic.com>
Thu, 14 Feb 2008 10:28:27 -0600
changeset 6096 d8477881ee0f
parent 5967 f8ad3b76e923
child 6211 f89fd07fc51d
permissions -rw-r--r--
hgweb: add new logos
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5675
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
     1
# win32text.py - LF <-> CRLF translation utilities for Windows users
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
     2
#
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
     3
# This software may be used and distributed according to the terms
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
     4
# of the GNU General Public License, incorporated herein by reference.
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
     5
#
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
     6
# To perform automatic newline conversion, use:
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
     7
#
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
     8
# [extensions]
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
     9
# hgext.win32text =
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    10
# [encode]
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    11
# ** = cleverencode:
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    12
# [decode]
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    13
# ** = cleverdecode:
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    14
#
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    15
# If not doing conversion, to make sure you do not commit CRLF by accident:
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    16
#
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    17
# [hooks]
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    18
# pretxncommit.crlf = python:hgext.win32text.forbidcrlf
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    19
#
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    20
# To do the same check on a server to prevent CRLF from being pushed or pulled:
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    21
#
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    22
# [hooks]
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    23
# pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    24
4859
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    25
from mercurial import util, ui
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    26
from mercurial.i18n import gettext as _
5675
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    27
from mercurial.node import *
4859
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    28
import re
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    29
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    30
# regexp for single LF without CR preceding.
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    31
re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    32
5967
f8ad3b76e923 Provide better context for custom Python encode/decode filters.
Jesse Glick <jesse.glick@sun.com>
parents: 5966
diff changeset
    33
def dumbdecode(s, cmd, ui=None, repo=None, filename=None, **kwargs):
4859
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    34
    # warn if already has CRLF in repository.
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    35
    # it might cause unexpected eol conversion.
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    36
    # see issue 302:
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    37
    #   http://www.selenic.com/mercurial/bts/issue302
5967
f8ad3b76e923 Provide better context for custom Python encode/decode filters.
Jesse Glick <jesse.glick@sun.com>
parents: 5966
diff changeset
    38
    if '\r\n' in s and ui and filename and repo:
f8ad3b76e923 Provide better context for custom Python encode/decode filters.
Jesse Glick <jesse.glick@sun.com>
parents: 5966
diff changeset
    39
        ui.warn(_('WARNING: %s already has CRLF line endings\n'
f8ad3b76e923 Provide better context for custom Python encode/decode filters.
Jesse Glick <jesse.glick@sun.com>
parents: 5966
diff changeset
    40
                  'and does not need EOL conversion by the win32text plugin.\n'
f8ad3b76e923 Provide better context for custom Python encode/decode filters.
Jesse Glick <jesse.glick@sun.com>
parents: 5966
diff changeset
    41
                  'Before your next commit, please reconsider your '
f8ad3b76e923 Provide better context for custom Python encode/decode filters.
Jesse Glick <jesse.glick@sun.com>
parents: 5966
diff changeset
    42
                  'encode/decode settings in \nMercurial.ini or %s.\n') %
f8ad3b76e923 Provide better context for custom Python encode/decode filters.
Jesse Glick <jesse.glick@sun.com>
parents: 5966
diff changeset
    43
                (filename, repo.join('hgrc')))
4859
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    44
    # replace single LF to CRLF
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    45
    return re_single_lf.sub('\\1\r\n', s)
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    46
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    47
def dumbencode(s, cmd):
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    48
    return s.replace('\r\n', '\n')
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    49
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    50
def clevertest(s, cmd):
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    51
    if '\0' in s: return False
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    52
    return True
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    53
5967
f8ad3b76e923 Provide better context for custom Python encode/decode filters.
Jesse Glick <jesse.glick@sun.com>
parents: 5966
diff changeset
    54
def cleverdecode(s, cmd, **kwargs):
4859
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    55
    if clevertest(s, cmd):
5967
f8ad3b76e923 Provide better context for custom Python encode/decode filters.
Jesse Glick <jesse.glick@sun.com>
parents: 5966
diff changeset
    56
        return dumbdecode(s, cmd, **kwargs)
4859
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    57
    return s
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    58
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    59
def cleverencode(s, cmd):
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    60
    if clevertest(s, cmd):
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    61
        return dumbencode(s, cmd)
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    62
    return s
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    63
5966
11af38a592ae Register data filters in a localrepo instead of util
Patrick Mezard <pmezard@gmail.com>
parents: 5675
diff changeset
    64
_filters = {
4859
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    65
    'dumbdecode:': dumbdecode,
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    66
    'dumbencode:': dumbencode,
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    67
    'cleverdecode:': cleverdecode,
8c5aca855b5d Correct inadvertent line ending change.
Lee Cantey <lcantey@gmail.com>
parents: 4858
diff changeset
    68
    'cleverencode:': cleverencode,
5966
11af38a592ae Register data filters in a localrepo instead of util
Patrick Mezard <pmezard@gmail.com>
parents: 5675
diff changeset
    69
    }
5675
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    70
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    71
def forbidcrlf(ui, repo, hooktype, node, **kwargs):
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    72
    halt = False
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    73
    for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    74
        c = repo.changectx(rev)
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    75
        for f in c.files():
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    76
            if f not in c:
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    77
                continue
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    78
            data = c[f].data()
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    79
            if '\0' not in data and '\r\n' in data:
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    80
                if not halt:
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    81
                    ui.warn(_('Attempt to commit or push text file(s) '
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    82
                              'using CRLF line endings\n'))
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    83
                ui.warn(_('in %s: %s\n') % (short(c.node()), f))
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    84
                halt = True
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    85
    if halt and hooktype == 'pretxnchangegroup':
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    86
        ui.warn(_('\nTo prevent this mistake in your local repository,\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    87
                  'add to Mercurial.ini or .hg/hgrc:\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    88
                  '\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    89
                  '[hooks]\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    90
                  'pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    91
                  '\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    92
                  'and also consider adding:\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    93
                  '\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    94
                  '[extensions]\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    95
                  'hgext.win32text =\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    96
                  '[encode]\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    97
                  '** = cleverencode:\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    98
                  '[decode]\n'
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
    99
                  '** = cleverdecode:\n'))
a5fe27b83a4a Issue 882: add standard hook to reject text files with CRLF.
Jesse Glick <jesse.glick@sun.com>
parents: 4859
diff changeset
   100
    return halt
5966
11af38a592ae Register data filters in a localrepo instead of util
Patrick Mezard <pmezard@gmail.com>
parents: 5675
diff changeset
   101
11af38a592ae Register data filters in a localrepo instead of util
Patrick Mezard <pmezard@gmail.com>
parents: 5675
diff changeset
   102
def reposetup(ui, repo):
11af38a592ae Register data filters in a localrepo instead of util
Patrick Mezard <pmezard@gmail.com>
parents: 5675
diff changeset
   103
    if not repo.local():
11af38a592ae Register data filters in a localrepo instead of util
Patrick Mezard <pmezard@gmail.com>
parents: 5675
diff changeset
   104
        return
11af38a592ae Register data filters in a localrepo instead of util
Patrick Mezard <pmezard@gmail.com>
parents: 5675
diff changeset
   105
    for name, fn in _filters.iteritems():
11af38a592ae Register data filters in a localrepo instead of util
Patrick Mezard <pmezard@gmail.com>
parents: 5675
diff changeset
   106
        repo.adddatafilter(name, fn)
11af38a592ae Register data filters in a localrepo instead of util
Patrick Mezard <pmezard@gmail.com>
parents: 5675
diff changeset
   107