hgkw/keyword.py
author Christian Ebert <blacktrash@gmx.net>
Sun, 14 Jan 2007 12:56:52 +0100
branchkwmap-templates
changeset 95 9e4cbe64fb4f
parent 93 9f70f953dd3b
child 97 9353e7ce6d9b
permissions -rw-r--r--
Implement custom keyword map templates in hgrc More expensive than hardcoded keywords. But, of course, more flexible. ATM templates can only be set in hgrc, and perhaps this is enough.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
48
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
     1
# keyword.py - keyword expansion for mercurial
82
9bf0f7db5928 Add keyword; comment backwards compatible import
Christian Ebert <blacktrash@gmx.net>
parents: 81
diff changeset
     2
# $Id$
48
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
     3
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
     4
'''keyword expansion hack against the grain of a DSCM
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
     5
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
     6
This extension lets you expand RCS/CVS-like keywords in a Mercurial
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
     7
repository.
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
     8
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
     9
There are many good reasons why this is not needed in a distributed
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    10
SCM, still it may be useful in very small projects based on single
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    11
files (like LaTeX packages), that are mostly addressed to an audience
52
7783eb22de30 Make inheritance clearer in size() and add()
Christian Ebert <blacktrash@gmx.net>
parents: 51
diff changeset
    12
not running a version control system.
48
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    13
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    14
You can either use the default cvs-like keywords or provide your
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    15
own in hgrc.
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    16
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    17
Default $keywords$ and their $keyword: substition $ are:
69
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    18
    Revision: changeset id
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    19
    Author:   username
90
2e930f842242 Very CVS-like format
Christian Ebert <blacktrash@gmx.net>
parents: 89
diff changeset
    20
    Date:     %Y/%m/%d %H:%M:%S [UTC]
69
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    21
    RCSFile:  basename,v
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    22
    Source:   /path/to/basename,v
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    23
    Id:       basename,v csetid %Y/%m/%d %H:%M:%S username
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    24
    Header:   /path/to/basename,v csetid %Y/%m/%d %H:%M:%S username
48
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    25
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    26
Simple setup in hgrc:
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    27
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    28
    # enable extension
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    29
    hgext.keyword = /full/path/to/script
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    30
    # or, if script in hgext folder:
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    31
    # hgext.keyword =
48
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    32
    
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    33
    # filename patterns for expansion are configured in this section
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    34
    [keyword]
69
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    35
    **.py = expand
48
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    36
    ...
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    37
    # in case you prefer you own keyword maps over the cvs-like defaults:
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    38
    [keywordmaps]
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    39
    hgdate = {date|rfc822date}
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    40
    lastlog = {desc}
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    41
    checked in by = {author}
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    42
    ...
48
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    43
'''
59fedb6b41da add header and start documentation
Christian Ebert <blacktrash@gmx.net>
parents: 47
diff changeset
    44
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    45
from mercurial import cmdutil, templater, util
90
2e930f842242 Very CVS-like format
Christian Ebert <blacktrash@gmx.net>
parents: 89
diff changeset
    46
import os.path, re, sys, time
47
0617e7d497f6 Branch standalone extension, including pretxncommit hook function
Christian Ebert <blacktrash@gmx.net>
parents: 44
diff changeset
    47
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    48
deftemplates = {
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    49
        'Revision': '{node|short}',
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    50
        'Author': '{author|user}',
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    51
        'Date': '{date|utcdate}',
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    52
        'RCSFile': '{file|basename},v',
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    53
        'Source': '{root}/{file},v',
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    54
        'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}',
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    55
        'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}',
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    56
        }
59
94b26168791d Only 1 all-purpose regex, compiled at load
Christian Ebert <blacktrash@gmx.net>
parents: 58
diff changeset
    57
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    58
def utcdate(date):
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    59
    '''Returns hgdate in cvs-like UTC format.'''
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    60
    return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0]))
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    61
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    62
templater.common_filters['utcdate'] = utcdate
47
0617e7d497f6 Branch standalone extension, including pretxncommit hook function
Christian Ebert <blacktrash@gmx.net>
parents: 44
diff changeset
    63
69
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    64
def kwfmatches(ui, repo, files):
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    65
    '''Selects candidates for keyword substitution
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    66
    configured in keyword section in hgrc.'''
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    67
    files = [f for f in files if not f.startswith('.hg')]
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    68
    if not files:
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    69
        return []
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    70
    candidates = []
83
05e50378c6e8 Cosmetics: var name kwfmatchers, remove some line continuations
Christian Ebert <blacktrash@gmx.net>
parents: 82
diff changeset
    71
    kwfmatchers = [util.matcher(repo.root, '', [pat], [], [])[1]
05e50378c6e8 Cosmetics: var name kwfmatchers, remove some line continuations
Christian Ebert <blacktrash@gmx.net>
parents: 82
diff changeset
    72
            for pat, opt in ui.configitems('keyword') if opt == 'expand']
69
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    73
    for f in files:
83
05e50378c6e8 Cosmetics: var name kwfmatchers, remove some line continuations
Christian Ebert <blacktrash@gmx.net>
parents: 82
diff changeset
    74
        for mf in kwfmatchers:
69
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    75
            if mf(f):
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    76
                candidates.append(f)
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    77
                break
4c5d9635b517 Pure extension by inserting keyword expansion localrepo.localrepository.commit
Christian Ebert <blacktrash@gmx.net>
parents: 68
diff changeset
    78
    return candidates
65
188849659487 Unify obtaining filename matchers; only debug messages
Christian Ebert <blacktrash@gmx.net>
parents: 64
diff changeset
    79
92
3c7c187e4001 Init context.filectx only once per file with class kwfilectx
Christian Ebert <blacktrash@gmx.net>
parents: 90
diff changeset
    80
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    81
class kwtemplater(object):
92
3c7c187e4001 Init context.filectx only once per file with class kwfilectx
Christian Ebert <blacktrash@gmx.net>
parents: 90
diff changeset
    82
    '''
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    83
    Sets up keyword templates, corresponding keyword regex, and
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    84
    provides keyword expansion function.
92
3c7c187e4001 Init context.filectx only once per file with class kwfilectx
Christian Ebert <blacktrash@gmx.net>
parents: 90
diff changeset
    85
    '''
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    86
    def __init__(self, ui, repo, node=None):
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    87
        self.ui = ui
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    88
        self.repo = repo
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    89
        self.node = node 
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    90
        templates = {}
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    91
        for k, v in self.ui.configitems('keywordmaps'):
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    92
            templates[k] = v
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    93
        self.templates = templates or deftemplates
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    94
        self.re_kw = re.compile(r'\$(%s)[^$]*?\$' %
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    95
                '|'.join(re.escape(k) for k in self.templates.keys()))
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    96
        self.t = cmdutil.changeset_templater(self.ui, self.repo,
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    97
                False, '', False)
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    98
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
    99
    def expand(self, mobj, path):
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   100
        kw = mobj.group(1)
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   101
        template = templater.parsestring(self.templates[kw], quoted=False)
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   102
        self.t.use_template(template)
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   103
        self.ui.pushbuffer()
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   104
        self.t.show(changenode=self.node,
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   105
                changes=self.repo.changelog.read(self.node),
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   106
                root=self.repo.root, file=path)
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   107
        return '$%s: %s $' % (kw, self.ui.popbuffer())
92
3c7c187e4001 Init context.filectx only once per file with class kwfilectx
Christian Ebert <blacktrash@gmx.net>
parents: 90
diff changeset
   108
42
ba000e29ecf3 Implement near CVS compability with more than one keyword
Christian Ebert <blacktrash@gmx.net>
parents: 41
diff changeset
   109
33
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   110
def reposetup(ui, repo):
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   111
    from mercurial import context, filelog, revlog
33
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   112
    if not repo.local():
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   113
        return
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   114
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   115
    class kwrepo(repo.__class__):
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   116
        def file(self, f):
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   117
            if f[0] == '/':
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   118
                f = f[1:]
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   119
            return filelog.filelog(self.sopener, f, self, self.revlogversion)
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   120
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   121
    class kwfilelog(filelog.filelog):
78
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   122
        '''
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   123
        Superclass over filelog to customize it's read, add, cmp methods.
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   124
        Keywords are "stored" unexpanded, and expanded on reading.
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   125
        '''
33
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   126
        def __init__(self, opener, path, repo,
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   127
                     defversion=revlog.REVLOG_DEFAULT_VERSION):
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   128
            super(kwfilelog, self).__init__(opener, path, defversion)
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   129
            self._repo = repo
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   130
            self._path = path
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   131
            self.kwt = kwtemplater(ui, self._repo)
36
b3ace8cc5a33 Change config opt "expand" to accept filename patterns
Christian Ebert <blacktrash@gmx.net>
parents: 34
diff changeset
   132
78
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   133
        def iskwcandidate(self, data):
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   134
            '''Decides whether to act on keywords.'''
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   135
            return (kwfmatches(ui, self._repo, [self._path])
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   136
                    and not util.binary(data))
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   137
33
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   138
        def read(self, node):
78
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   139
            '''Substitutes keywords when reading filelog.'''
42
ba000e29ecf3 Implement near CVS compability with more than one keyword
Christian Ebert <blacktrash@gmx.net>
parents: 41
diff changeset
   140
            data = super(kwfilelog, self).read(node)
78
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   141
            if self.iskwcandidate(data):
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   142
                c = context.filectx(self._repo, self._path,
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   143
                         fileid=node, filelog=self)
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   144
                self.kwt.node = c.node()
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   145
                return self.kwt.re_kw.sub(lambda m:
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   146
                        self.kwt.expand(m, self._path), data)
51
1ecb6ec5d16b Reintroduce simpler kwfilelog.add(); simplify kwfilelog.read()
Christian Ebert <blacktrash@gmx.net>
parents: 50
diff changeset
   147
            return data
42
ba000e29ecf3 Implement near CVS compability with more than one keyword
Christian Ebert <blacktrash@gmx.net>
parents: 41
diff changeset
   148
78
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   149
        def add(self, text, meta, tr, link, p1=None, p2=None):
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   150
            '''Removes keyword substitutions when adding to filelog.'''
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   151
            if self.iskwcandidate(text):
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   152
                text = self.kwt.re_kw.sub(r'$\1$', text)
78
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   153
            return super(kwfilelog, self).add(text,
93
9f70f953dd3b Clean keyword arg assignment in kwfilelog.add; rename utc() to utcdate()
Christian Ebert <blacktrash@gmx.net>
parents: 92
diff changeset
   154
                    meta, tr, link, p1=p1, p2=p2)
78
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   155
49
5acfe7dc3086 Override filelog's size(), cmp() as well; remove add()
Christian Ebert <blacktrash@gmx.net>
parents: 48
diff changeset
   156
        def cmp(self, node, text):
78
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   157
            '''Removes keyword substitutions for comparison.'''
474b415433a1 Unexpanded storage hopefully covered now by adding kwfilelog.add (again!)
Christian Ebert <blacktrash@gmx.net>
parents: 77
diff changeset
   158
            if self.iskwcandidate(text):
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   159
                text = self.kwt.re_kw.sub(r'$\1$', text)
71
f7a2a246740c No keyword substitution in cmp(); no overriding of size() ATM
Christian Ebert <blacktrash@gmx.net>
parents: 69
diff changeset
   160
            return super(kwfilelog, self).cmp(node, text)
33
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   161
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   162
    filelog.filelog = kwfilelog
ebb39c6a1476 Add original keyword extension by Thomas Arendsen Hain
Christian Ebert <blacktrash@gmx.net>
parents:
diff changeset
   163
    repo.__class__ = kwrepo
87
c193da9eb3e4 Only extend sys.path if needed
Christian Ebert <blacktrash@gmx.net>
parents: 86
diff changeset
   164
    # make pretxncommit hook import kwmodule regardless of where it's located
88
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   165
    for k, v in sys.modules.iteritems():
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   166
        if v is None:
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   167
            continue
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   168
        if not hasattr(v, '__file__'):
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   169
            continue
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   170
        if v.__file__.startswith(__file__):
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   171
            mod = k
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   172
            break
87
c193da9eb3e4 Only extend sys.path if needed
Christian Ebert <blacktrash@gmx.net>
parents: 86
diff changeset
   173
    else:
88
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   174
        sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   175
        mod = os.path.splitext(os.path.basename(__file__))[0]
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   176
    ui.setconfig('hooks', 'pretxncommit.keyword', 'python:%s.pretxnkw' % mod)
ffec227fced3 Module detection cleaner and more reliable
Christian Ebert <blacktrash@gmx.net>
parents: 87
diff changeset
   177
    del mod
81
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   178
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   179
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   180
def pretxnkw(ui, repo, hooktype, **args):
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   181
    '''pretxncommit hook that collects candidates for keyword expansion
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   182
    on commit and expands keywords in working dir.'''
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   183
    from mercurial.i18n import gettext as _
82
9bf0f7db5928 Add keyword; comment backwards compatible import
Christian Ebert <blacktrash@gmx.net>
parents: 81
diff changeset
   184
    # above line for backwards compatibility; can be changed to
9bf0f7db5928 Add keyword; comment backwards compatible import
Christian Ebert <blacktrash@gmx.net>
parents: 81
diff changeset
   185
    #   from mercurial.i18n import _
9bf0f7db5928 Add keyword; comment backwards compatible import
Christian Ebert <blacktrash@gmx.net>
parents: 81
diff changeset
   186
    # some day
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   187
    from mercurial import commands
81
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   188
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   189
    if hooktype != 'pretxncommit':
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   190
        return True
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   191
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   192
    cmd, sysargs, globalopts, cmdopts = commands.parse(ui, sys.argv[1:])[1:]
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   193
    if repr(cmd).split()[1] in ('tag', 'import_'):
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   194
        return False
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   195
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   196
    files, match, anypats = cmdutil.matchpats(repo, sysargs, cmdopts)
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   197
    modified, added = repo.status(files=files, match=match)[:2]
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   198
    candidates = kwfmatches(ui, repo, modified+added)
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   199
    if not candidates:
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   200
        return False
81
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   201
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   202
    kwt = kwtemplater(ui, repo, node=repo.changelog.tip())
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   203
    for f in candidates:
81
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   204
        data = repo.wfile(f).read()
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   205
        if not util.binary(data):
95
9e4cbe64fb4f Implement custom keyword map templates in hgrc
Christian Ebert <blacktrash@gmx.net>
parents: 93
diff changeset
   206
            data, kwct = kwt.re_kw.subn(lambda m: kwt.expand(m, f), data)
81
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   207
            if kwct:
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   208
                ui.debug(_('overwriting %s expanding keywords\n' % f))
fd5d3a974ea7 Implement self initializing pretxncommit hook
Christian Ebert <blacktrash@gmx.net>
parents: 80
diff changeset
   209
                repo.wfile(f, 'w').write(data)