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