##// END OF EJS Templates
commands: better argument processing, per-command help...
mpm@selenic.com -
r212:48398a53 default
parent child Browse files
Show More
@@ -1,150 +1,169 b''
1 import os, re
1 import os, re, traceback, sys
2 2 from mercurial import fancyopts, ui, hg
3 3
4 4 class UnknownCommand(Exception): pass
5 5
6 6 def relpath(repo, args):
7 7 if os.getcwd() != repo.root:
8 8 p = os.getcwd()[len(repo.root) + 1: ]
9 9 return [ os.path.join(p, x) for x in args ]
10 10 return args
11 11
12 def help(ui, args):
12 def help(ui, cmd=None):
13 '''show help'''
14 if cmd:
15 try:
16 i = find(cmd)
17 ui.write("%s\n\n" % i[2])
18 ui.write(i[0].__doc__, "\n")
19 except UnknownCommand:
20 ui.warn("unknown command %s", cmd)
21 sys.exit(0)
22
13 23 ui.status("""\
14 24 hg commands:
15 25
16 26 add [files...] add the given files in the next commit
17 27 addremove add all new files, delete all missing files
18 28 annotate [files...] show changeset number per file line
19 29 branch <path> create a branch of <path> in this directory
20 30 checkout [changeset] checkout the latest or given changeset
21 31 commit commit all changes to the repository
22 32 diff [files...] diff working directory (or selected files)
23 33 dump <file> [rev] dump the latest or given revision of a file
24 34 dumpmanifest [rev] dump the latest or given revision of the manifest
25 35 export <rev> dump the changeset header and diffs for a revision
26 36 history show changeset history
27 37 init create a new repository in this directory
28 38 log <file> show revision history of a single file
29 39 merge <path> merge changes from <path> into local repository
30 40 recover rollback an interrupted transaction
31 41 remove [files...] remove the given files in the next commit
32 42 serve export the repository via HTTP
33 43 status show new, missing, and changed files in working dir
34 44 tags show current changeset tags
35 45 undo undo the last transaction
36 46 """)
37 47
38 def init(ui, args):
48 def init(ui):
39 49 """create a repository"""
40 50 hg.repository(ui, ".", create=1)
41 51
42 def checkout(u, repo, args):
52 def checkout(u, repo, changeset=None):
53 '''checkout a given changeset or the current tip'''
43 54 node = repo.changelog.tip()
44 if args:
45 node = repo.lookup(args[0])
55 if changeset:
56 node = repo.lookup(changeset)
46 57 repo.checkout(node)
47 58
48 def annotate(u, repo, args, **ops):
49 if not args:
50 return
51
59 def annotate(u, repo, *args, **ops):
52 60 def getnode(rev):
53 61 return hg.short(repo.changelog.node(rev))
54 62
55 63 def getname(rev):
56 64 try:
57 65 return bcache[rev]
58 66 except KeyError:
59 67 cl = repo.changelog.read(repo.changelog.node(rev))
60 68 name = cl[1]
61 69 f = name.find('@')
62 70 if f >= 0:
63 71 name = name[:f]
64 72 bcache[rev] = name
65 73 return name
66 74
67 75 bcache = {}
68 76 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
69 77 if not ops['user'] and not ops['changeset']:
70 78 ops['number'] = 1
71 79
72 80 args = relpath(repo, args)
73 81 node = repo.current
74 82 if ops['revision']:
75 83 node = repo.changelog.lookup(ops['revision'])
76 84 change = repo.changelog.read(node)
77 85 mmap = repo.manifest.read(change[0])
78 86 maxuserlen = 0
79 87 maxchangelen = 0
80 88 for f in args:
81 89 lines = repo.file(f).annotate(mmap[f])
82 90 pieces = []
83 91
84 92 for o, f in opmap:
85 93 if ops[o]:
86 94 l = [ f(n) for n,t in lines ]
87 95 m = max(map(len, l))
88 96 pieces.append([ "%*s" % (m, x) for x in l])
89 97
90 98 for p,l in zip(zip(*pieces), lines):
91 99 u.write(" ".join(p) + ": " + l[1])
92 100
93 def undo(ui, repo, args):
101 def undo(ui, repo):
94 102 repo.undo()
95 103
96 104 table = {
97 105 "init": (init, [], 'hg init'),
98 "help": (help, [], 'hg help'),
99 "checkout|co": (checkout, [], 'hg checkout'),
106 "help": (help, [], 'hg help [command]'),
107 "checkout|co": (checkout, [], 'hg checkout [changeset]'),
100 108 "ann|annotate": (annotate,
101 109 [('r', 'revision', '', 'revision'),
102 110 ('u', 'user', None, 'show user'),
103 111 ('n', 'number', None, 'show revision number'),
104 112 ('c', 'changeset', None, 'show changeset')],
105 113 'hg annotate [-u] [-c] [-n] [-r id] [files]'),
106 114 "undo": (undo, [], 'hg undo'),
107 115 }
108 116
109 117 norepo = "init branch help"
110 118
119 def find(cmd):
120 i = None
121 for e in table.keys():
122 if re.match(e + "$", cmd):
123 return table[e]
124
125 raise UnknownCommand(cmd)
126
111 127 def dispatch(args):
112 128 options = {}
113 129 opts = [('v', 'verbose', None, 'verbose'),
114 130 ('d', 'debug', None, 'debug'),
115 131 ('q', 'quiet', None, 'quiet'),
116 132 ('y', 'noninteractive', None, 'run non-interactively'),
117 133 ]
118 134
119 135 args = fancyopts.fancyopts(args, opts, options,
120 136 'hg [options] <command> [options] [files]')
121 137
122 138 if not args:
123 139 cmd = "help"
124 140 else:
125 141 cmd, args = args[0], args[1:]
126 142
127 143 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
128 144 not options["noninteractive"])
129 145
130 i = None
131 for e in table.keys():
132 if re.match(e + "$", cmd):
133 i = table[e]
134
135 # deal with this internally later
136 if not i: raise UnknownCommand(cmd)
146 # deal with unfound commands later
147 i = find(cmd)
137 148
138 149 cmdoptions = {}
139 150 args = fancyopts.fancyopts(args, i[1], cmdoptions, i[2])
140 151
141 152 if cmd not in norepo.split():
142 153 repo = hg.repository(ui = u)
143 d = lambda: i[0](u, repo, args, **cmdoptions)
154 d = lambda: i[0](u, repo, *args, **cmdoptions)
144 155 else:
145 d = lambda: i[0](u, args, **cmdoptions)
156 d = lambda: i[0](u, *args, **cmdoptions)
146 157
147 158 try:
148 159 d()
149 160 except KeyboardInterrupt:
150 161 u.warn("interrupted!\n")
162 except TypeError, inst:
163 # was this an argument error?
164 tb = traceback.extract_tb(sys.exc_info()[2])
165 if len(tb) > 2: # no
166 raise
167 u.warn("%s: invalid arguments\n" % i[0].__name__)
168 u.warn("syntax: %s\n" % i[2])
169 sys.exit(-1)
General Comments 0
You need to be logged in to leave comments. Login now