hgbook

annotate en/cmdref.py @ 1114:527b86d55d4a

inotify: update installation information

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