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