hgbook

view en/cmdref.py @ 265:d9a1faa45c30

added a space between -m and the commit message.
author bab@draketo.de
date Fri Aug 31 11:36:14 2007 +0200 (2007-08-31)
parents
children
line source
1 #!/usr/bin/env python
3 import getopt
4 import itertools
5 import os
6 import re
7 import sys
9 def usage(exitcode):
10 print >> sys.stderr, ('usage: %s [-H|--hidden] hg_repo' %
11 os.path.basename(sys.argv[0]))
12 sys.exit(exitcode)
14 try:
15 opts, args = getopt.getopt(sys.argv[1:], 'AHh?', ['all', 'help', 'hidden'])
16 opt_all = False
17 opt_hidden = False
18 for o, a in opts:
19 if o in ('-h', '-?', '--help'):
20 usage(0)
21 if o in ('-A', '--all'):
22 opt_all = True
23 if o in ('-H', '--hidden'):
24 opt_hidden = True
25 except getopt.GetoptError, err:
26 print >> sys.stderr, 'error:', err
27 usage(1)
29 try:
30 hg_repo, ltx_file = args
31 except ValueError:
32 usage(1)
34 if not os.path.isfile(os.path.join(hg_repo, 'mercurial', 'commands.py')):
35 print >> sys.stderr, ('error: %r does not contain mercurial code' %
36 hg_repo)
37 sys.exit(1)
39 sys.path.insert(0, hg_repo)
41 from mercurial import commands
43 def get_commands():
44 seen = {}
45 for name, info in sorted(commands.table.iteritems()):
46 aliases = name.split('|', 1)
47 name = aliases.pop(0).lstrip('^')
48 function, options, synopsis = info
49 seen[name] = {}
50 for shortopt, longopt, arg, desc in options:
51 seen[name][longopt] = shortopt
52 return seen
54 def cmd_filter((name, aliases, options)):
55 if opt_all:
56 return True
57 if opt_hidden:
58 return name.startswith('debug')
59 return not name.startswith('debug')
61 def scan(ltx_file):
62 cmdref_re = re.compile(r'^\\cmdref{(?P<cmd>\w+)}')
63 optref_re = re.compile(r'^\\l?optref{(?P<cmd>\w+)}'
64 r'(?:{(?P<short>[^}])})?'
65 r'{(?P<long>[^}]+)}')
67 seen = {}
68 locs = {}
69 for lnum, line in enumerate(open(ltx_file)):
70 m = cmdref_re.match(line)
71 if m:
72 d = m.groupdict()
73 cmd = d['cmd']
74 seen[cmd] = {}
75 locs[cmd] = lnum + 1
76 continue
77 m = optref_re.match(line)
78 if m:
79 d = m.groupdict()
80 seen[d['cmd']][d['long']] = d['short']
81 continue
82 return seen, locs
84 documented, locs = scan(ltx_file)
85 known = get_commands()
87 doc_set = set(documented)
88 known_set = set(known)
90 errors = 0
92 for nonexistent in sorted(doc_set.difference(known_set)):
93 print >> sys.stderr, ('%s:%d: %r command does not exist' %
94 (ltx_file, locs[nonexistent], nonexistent))
95 errors += 1
97 def optcmp(a, b):
98 la, sa = a
99 lb, sb = b
100 sc = cmp(sa, sb)
101 if sc:
102 return sc
103 return cmp(la, lb)
105 for cmd in doc_set.intersection(known_set):
106 doc_opts = documented[cmd]
107 known_opts = known[cmd]
109 do_set = set(doc_opts)
110 ko_set = set(known_opts)
112 for nonexistent in sorted(do_set.difference(ko_set)):
113 print >> sys.stderr, ('%s:%d: %r option to %r command does not exist' %
114 (ltx_file, locs[cmd], nonexistent, cmd))
115 errors += 1
117 def mycmp(la, lb):
118 sa = known_opts[la]
119 sb = known_opts[lb]
120 return optcmp((la, sa), (lb, sb))
122 for undocumented in sorted(ko_set.difference(do_set), cmp=mycmp):
123 print >> sys.stderr, ('%s:%d: %r option to %r command not documented' %
124 (ltx_file, locs[cmd], undocumented, cmd))
125 shortopt = known_opts[undocumented]
126 if shortopt:
127 print '\optref{%s}{%s}{%s}' % (cmd, shortopt, undocumented)
128 else:
129 print '\loptref{%s}{%s}' % (cmd, undocumented)
130 errors += 1
131 sys.stdout.flush()
133 if errors:
134 sys.exit(1)
136 sorted_locs = sorted(locs.iteritems(), key=lambda x:x[1])
138 def next_loc(cmd):
139 for i, (name, loc) in enumerate(sorted_locs):
140 if name >= cmd:
141 return sorted_locs[i-1][1] + 1
142 return loc
144 for undocumented in sorted(known_set.difference(doc_set)):
145 print >> sys.stderr, ('%s:%d: %r command not documented' %
146 (ltx_file, next_loc(undocumented), undocumented))
147 print '\cmdref{%s}' % undocumented
148 for longopt, shortopt in sorted(known[undocumented].items(), cmp=optcmp):
149 if shortopt:
150 print '\optref{%s}{%s}{%s}' % (undocumented, shortopt, longopt)
151 else:
152 print '\loptref{%s}{%s}' % (undocumented, longopt)
153 sys.stdout.flush()
154 errors += 1
156 sys.exit(errors and 1 or 0)