hgbook

diff en/cmdref.py @ 926:730d912ef843

Work in progress on translating the introduction chapter. I also added a non exhaustive list of major Open Source projet using Mercurial. This list still needs to be 'linked' with the appropriate URLs, and also to be 'backported' into the english and spanish version of hgbooks.
author Romain PELISSE <romain.pelisse@atosorigin.com>
date Sun Feb 08 14:17:16 2009 +0100 (2009-02-08)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/en/cmdref.py	Sun Feb 08 14:17:16 2009 +0100
     1.3 @@ -0,0 +1,156 @@
     1.4 +#!/usr/bin/env python
     1.5 +
     1.6 +import getopt
     1.7 +import itertools
     1.8 +import os
     1.9 +import re
    1.10 +import sys
    1.11 +
    1.12 +def usage(exitcode):
    1.13 +    print >> sys.stderr, ('usage: %s [-H|--hidden] hg_repo' % 
    1.14 +                          os.path.basename(sys.argv[0]))
    1.15 +    sys.exit(exitcode)
    1.16 +
    1.17 +try:
    1.18 +    opts, args = getopt.getopt(sys.argv[1:], 'AHh?', ['all', 'help', 'hidden'])
    1.19 +    opt_all = False
    1.20 +    opt_hidden = False
    1.21 +    for o, a in opts:
    1.22 +        if o in ('-h', '-?', '--help'):
    1.23 +            usage(0)
    1.24 +        if o in ('-A', '--all'):
    1.25 +            opt_all = True
    1.26 +        if o in ('-H', '--hidden'):
    1.27 +            opt_hidden = True
    1.28 +except getopt.GetoptError, err:
    1.29 +    print >> sys.stderr, 'error:', err
    1.30 +    usage(1)
    1.31 +
    1.32 +try:
    1.33 +    hg_repo, ltx_file = args
    1.34 +except ValueError:
    1.35 +    usage(1)
    1.36 +
    1.37 +if not os.path.isfile(os.path.join(hg_repo, 'mercurial', 'commands.py')):
    1.38 +    print >> sys.stderr, ('error: %r does not contain mercurial code' %
    1.39 +                          hg_repo)
    1.40 +    sys.exit(1)
    1.41 +
    1.42 +sys.path.insert(0, hg_repo)
    1.43 +
    1.44 +from mercurial import commands
    1.45 +
    1.46 +def get_commands():
    1.47 +    seen = {}
    1.48 +    for name, info in sorted(commands.table.iteritems()):
    1.49 +        aliases = name.split('|', 1)
    1.50 +        name = aliases.pop(0).lstrip('^')
    1.51 +        function, options, synopsis = info
    1.52 +        seen[name] = {}
    1.53 +        for shortopt, longopt, arg, desc in options:
    1.54 +            seen[name][longopt] = shortopt
    1.55 +    return seen
    1.56 +
    1.57 +def cmd_filter((name, aliases, options)):
    1.58 +    if opt_all:
    1.59 +        return True
    1.60 +    if opt_hidden:
    1.61 +        return name.startswith('debug')
    1.62 +    return not name.startswith('debug')
    1.63 +
    1.64 +def scan(ltx_file):
    1.65 +    cmdref_re = re.compile(r'^\\cmdref{(?P<cmd>\w+)}')
    1.66 +    optref_re = re.compile(r'^\\l?optref{(?P<cmd>\w+)}'
    1.67 +                           r'(?:{(?P<short>[^}])})?'
    1.68 +                           r'{(?P<long>[^}]+)}')
    1.69 +
    1.70 +    seen = {}
    1.71 +    locs = {}
    1.72 +    for lnum, line in enumerate(open(ltx_file)):
    1.73 +        m = cmdref_re.match(line)
    1.74 +        if m:
    1.75 +            d = m.groupdict()
    1.76 +            cmd = d['cmd']
    1.77 +            seen[cmd] = {}
    1.78 +            locs[cmd] = lnum + 1
    1.79 +            continue
    1.80 +        m = optref_re.match(line)
    1.81 +        if m:
    1.82 +            d = m.groupdict()
    1.83 +            seen[d['cmd']][d['long']] = d['short']
    1.84 +            continue
    1.85 +    return seen, locs
    1.86 +    
    1.87 +documented, locs = scan(ltx_file)
    1.88 +known = get_commands()
    1.89 +
    1.90 +doc_set = set(documented)
    1.91 +known_set = set(known)
    1.92 +
    1.93 +errors = 0
    1.94 +
    1.95 +for nonexistent in sorted(doc_set.difference(known_set)):
    1.96 +    print >> sys.stderr, ('%s:%d: %r command does not exist' %
    1.97 +                          (ltx_file, locs[nonexistent], nonexistent))
    1.98 +    errors += 1
    1.99 +
   1.100 +def optcmp(a, b):
   1.101 +    la, sa = a
   1.102 +    lb, sb = b
   1.103 +    sc = cmp(sa, sb)
   1.104 +    if sc:
   1.105 +        return sc
   1.106 +    return cmp(la, lb)
   1.107 +
   1.108 +for cmd in doc_set.intersection(known_set):
   1.109 +    doc_opts = documented[cmd]
   1.110 +    known_opts = known[cmd]
   1.111 +    
   1.112 +    do_set = set(doc_opts)
   1.113 +    ko_set = set(known_opts)
   1.114 +
   1.115 +    for nonexistent in sorted(do_set.difference(ko_set)):
   1.116 +        print >> sys.stderr, ('%s:%d: %r option to %r command does not exist' %
   1.117 +                              (ltx_file, locs[cmd], nonexistent, cmd))
   1.118 +        errors += 1
   1.119 +
   1.120 +    def mycmp(la, lb):
   1.121 +        sa = known_opts[la]
   1.122 +        sb = known_opts[lb]
   1.123 +        return optcmp((la, sa), (lb, sb))
   1.124 +
   1.125 +    for undocumented in sorted(ko_set.difference(do_set), cmp=mycmp):
   1.126 +        print >> sys.stderr, ('%s:%d: %r option to %r command not documented' %
   1.127 +                              (ltx_file, locs[cmd], undocumented, cmd))
   1.128 +        shortopt = known_opts[undocumented]
   1.129 +        if shortopt:
   1.130 +            print '\optref{%s}{%s}{%s}' % (cmd, shortopt, undocumented)
   1.131 +        else:
   1.132 +            print '\loptref{%s}{%s}' % (cmd, undocumented)
   1.133 +        errors += 1
   1.134 +    sys.stdout.flush()
   1.135 +
   1.136 +if errors:
   1.137 +    sys.exit(1)
   1.138 +
   1.139 +sorted_locs = sorted(locs.iteritems(), key=lambda x:x[1])
   1.140 +
   1.141 +def next_loc(cmd):
   1.142 +    for i, (name, loc) in enumerate(sorted_locs):
   1.143 +        if name >= cmd:
   1.144 +            return sorted_locs[i-1][1] + 1
   1.145 +    return loc
   1.146 +
   1.147 +for undocumented in sorted(known_set.difference(doc_set)):
   1.148 +    print >> sys.stderr, ('%s:%d: %r command not documented' %
   1.149 +                          (ltx_file, next_loc(undocumented), undocumented))
   1.150 +    print '\cmdref{%s}' % undocumented
   1.151 +    for longopt, shortopt in sorted(known[undocumented].items(), cmp=optcmp):
   1.152 +        if shortopt:
   1.153 +            print '\optref{%s}{%s}{%s}' % (undocumented, shortopt, longopt)
   1.154 +        else:
   1.155 +            print '\loptref{%s}{%s}' % (undocumented, longopt)
   1.156 +    sys.stdout.flush()
   1.157 +    errors += 1
   1.158 +
   1.159 +sys.exit(errors and 1 or 0)