Merge lp:~aturriff/boots/boots-metacommands into lp:boots

Proposed by Andreas Turriff
Status: Merged
Merged at revision: 43
Proposed branch: lp:~aturriff/boots/boots-metacommands
Merge into: lp:boots
Diff against target: 169 lines (+72/-21)
3 files modified
src/boots/lib/console.py (+49/-14)
src/boots/lib/metacommands/metacommands.py (+22/-6)
src/boots/lib/ui/plain.py (+1/-1)
To merge this branch: bzr merge lp:~aturriff/boots/boots-metacommands
Reviewer Review Type Date Requested Status
Max Goodhart Approve
Review via email: mp+18770@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Andreas Turriff (aturriff) wrote :

This is the promised metacommand rewrite to use function references rather than strings. It also fixes a logic bug in console.disconnect() and adds a number of FIXMEs as well as two new metacommands to switch lingos and exit the console.

Revision history for this message
Max Goodhart (chromakode) wrote :

Merged, thanks. I made a couple code cleanups and tweaks. Check the diff.

review: Approve
Revision history for this message
Andreas Turriff (aturriff) wrote :

I think there's now a logic bug in the master list of metacommand names.
As discussed, the union of sets should be unconditional - there should
be a warning of set intersection, however.

~Andreas

On 2/6/2010 2:24 PM, Chromakode wrote:
> Review: Approve
> Merged, thanks. I made a couple code cleanups and tweaks. Check the diff.
>

Revision history for this message
Max Goodhart (chromakode) wrote :

Whoops-- good catch. Thanks for looking it over, Andreas.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/boots/lib/console.py'
2--- src/boots/lib/console.py 2010-02-01 20:46:55 +0000
3+++ src/boots/lib/console.py 2010-02-06 20:03:14 +0000
4@@ -35,6 +35,7 @@
5 from boots.lib.lingos.lisp import lisp
6 from boots.lib.lingos import python
7 from boots.lib.lingos import sql
8+import sys
9
10 # Utility function.
11 def iterable(obj):
12@@ -53,29 +54,55 @@
13 self.servers = [api.Server(self.config["host"], self.config["port"],
14 {"database": self.config["database"]})]
15 self.ui = PlainUI(self.config["prompt"])
16- #Instead of an empty set, the set of console metacommands should be
17- #listed here. Also, the metacommand dictionary to be passed into
18- #self.metacommands needs to be set up somewhere.
19- self.metacommands=metacommands.MetaCommands({'\connect' : 'connect', '\disconnect' : 'disconnect'}, self)
20+ metadict = {}
21+ metadict['\connect'] = self.meta_connect
22+ metadict['\disconnect'] = self.meta_disconnect
23+ metadict['\lingo'] = self.meta_switchlingo
24+ metadict['\quit'] = self.meta_quit
25+ self.metacommands=metacommands.MetaCommands(metadict)
26 self.metacommandset=set(self.metacommands.commands.keys())
27- #self.ui.metacommands needs to be replaced with a reference to self.ui's metacommand object. We need a definition
28- #for how these variables and methods are named.
29 if not self.metacommandset.isdisjoint(set(self.ui.metacommands.commands.keys())):
30 # FIXME: Issue warning through the UI using ui.print
31- print('warning, conflicts between metacommands detected')
32+ # FIXME: Determine the offending command(s) (set.intersect?)
33+ # FIXME: Print offending commands
34+ print('warning, conflicts between metacommands detected.')
35 self.metacommandset = self.metacommandset | set(self.ui.metacommands.commands.keys())
36
37 def run(self, command, lingo_name="sql"):
38 return lingo.get(lingo_name).execute(command)
39
40- def connect(self, host = None, port = None, database = None):
41- if host == None:
42+ def meta_quit(self):
43+ # Print a trailing newline.
44+ self.ui.present('')
45+ self.disconnect(None, None)
46+
47+ sys.exit(0)
48+
49+ #FIXME: Is there / can there be a list of available lingos?
50+ #If so, we could implement dynaming registration of lingos through this
51+ #interface: Register the lingo used in main(), and register lingos
52+ #switched to here.
53+ def meta_switchlingo(self, lingo = None):
54+ if lingo is None:
55+ return False
56+
57+ lingo = str(lingo)
58+ self.switchlingo(lingo)
59+
60+ def switchlingo(self, lingo):
61+ self.lingo = lingo
62+
63+ def meta_connect(self, host = None, port = None, database = None):
64+ if host is None:
65 host = self.config["host"]
66- if port == None:
67+ if port is None:
68 port = self.config["port"]
69- if database == None:
70+ if database is None:
71 database = self.config["database"]
72
73+ self.connect(host, port, database)
74+
75+ def connect(self, host, port, database):
76 server = api.Server(host, port, {"database": database})
77 server.connect()
78 if server.is_connected:
79@@ -85,13 +112,21 @@
80 print("Could not connect to", host, port, database)
81 return False
82
83- def disconnect(self, host = None, port = None):
84+ def meta_disconnect(self, host = None, port = None):
85+ if host is not None:
86+ host=str(host)
87+ if port is not None:
88+ port=str(port)
89+
90+ self.disconnect(host,port)
91+
92+ def disconnect(self, host, port):
93 found = False
94 for server in self.servers:
95 if not host or server.host == host and not port or server.port == port:
96 server.disconnect()
97 self.servers.remove(server)
98- found = True
99+ found = True
100 return found
101
102 def main(self):
103@@ -117,4 +152,4 @@
104
105 # Print a trailing newline.
106 self.ui.present('')
107- self.disconnect()
108+ self.disconnect(None, None)
109
110=== modified file 'src/boots/lib/metacommands/metacommands.py'
111--- src/boots/lib/metacommands/metacommands.py 2010-02-01 20:32:54 +0000
112+++ src/boots/lib/metacommands/metacommands.py 2010-02-06 20:03:14 +0000
113@@ -29,21 +29,37 @@
114 # ##### END LICENSE BLOCK #####
115
116 def parse(commandstring):
117+ """This function wraps str.split() for metacommands
118+
119+This function takes a string as argument and calls str.split() on that string
120+to return a list of substrings, using whitespace as separator. The metacommand
121+object uses this list to call a metacommand function and pass parameters."""
122 return commandstring.split()
123
124 class MetaCommands(object):
125- """Class used for handling metacommands."""
126+ """Class used for handling metacommands.
127+
128+The MetaCommands class provides a mapping of command strings to function
129+references. Its functions are the constructor, parse() (a function not bound
130+to a MetaCommands object) and execute().
131+
132+The constructor accepts one parameter, a dictionary of string to function
133+reference mappings. It stores this parameter in the member variable commands."""
134 commands = {}
135
136- def __init__(self, commanddict, inparent):
137- """Constructor for class."""
138+ def __init__(self, commanddict):
139 self.commands = commanddict
140- self.parent = inparent
141
142 def execute(self, commandlist):
143- """Parse and execute a metacommand string."""
144+ """Parse and execute a metacommand string.
145+
146+The execute() function takes a list of strings, with the first being the name
147+of the metacommand to be executed and the others being the required parameters.
148+It performs a dictionary lookup on the name and calls the function it finds,
149+or returns False if no function is found."""
150 if len(commandlist) != 0 and commandlist[0] in self.commands:
151- getattr(self.parent, self.commands[commandlist[0]])(*commandlist[1:])
152+ self.commands[commandlist[0]](*commandlist[1:])
153+ #Do we need to pass metacommand return values back?
154 return True
155 else:
156 return False
157
158=== modified file 'src/boots/lib/ui/plain.py'
159--- src/boots/lib/ui/plain.py 2010-02-02 02:48:04 +0000
160+++ src/boots/lib/ui/plain.py 2010-02-06 20:03:14 +0000
161@@ -35,7 +35,7 @@
162
163 class PlainUI(StdinDriver, StdoutPresenter):
164 def __init__(self, prompt):
165- self.metacommands = metacommands.MetaCommands({}, self)
166+ self.metacommands = metacommands.MetaCommands({})
167 self.prompt = prompt
168 self.current_widths = None
169 self.buffer = []

Subscribers

People subscribed via source and target branches

to status/vote changes: