Merge lp:~jml/quickly/commands-cleanup into lp:quickly
- commands-cleanup
- Merge into trunk
Proposed by
Jonathan Lange
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~jml/quickly/commands-cleanup |
Merge into: | lp:quickly |
Diff against target: |
493 lines (+185/-106) 2 files modified
quickly/builtincommands.py (+3/-3) quickly/commands.py (+182/-103) |
To merge this branch: | bzr merge lp:~jml/quickly/commands-cleanup |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Didier Roche-Tolomelli | Approve | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jonathan Lange (jml) wrote : | # |
lp:~jml/quickly/commands-cleanup
updated
- 363. By Jonathan Lange
-
Remove lots of XXXs, mostly by adding more verbose comments.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Didier Roche-Tolomelli (didrocks) wrote : | # |
Thanks for your patch.
Again, do not hesitate to share your 7 years of python experience with a stupid C/C++/shell programmer but beginner in python :)
I added a replacement for get_command_
Merged now, thanks.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'quickly/builtincommands.py' | |||
2 | --- quickly/builtincommands.py 2009-11-15 15:18:26 +0000 | |||
3 | +++ quickly/builtincommands.py 2009-11-19 00:25:20 +0000 | |||
4 | @@ -146,17 +146,17 @@ | |||
5 | 146 | if template is None: | 146 | if template is None: |
6 | 147 | template = "builtins" | 147 | template = "builtins" |
7 | 148 | try: | 148 | try: |
9 | 149 | command = commands_module.get_command_by_criteria(name=command_name, template=template)[0] | 149 | command = commands_module.get_commands_by_criteria(name=command_name, template=template)[0] |
10 | 150 | except IndexError: | 150 | except IndexError: |
11 | 151 | # check if a builtin commands corresponds | 151 | # check if a builtin commands corresponds |
12 | 152 | template = "builtins" | 152 | template = "builtins" |
13 | 153 | try: | 153 | try: |
15 | 154 | command = commands_module.get_command_by_criteria(name=command_name, template=template)[0] | 154 | command = commands_module.get_commands_by_criteria(name=command_name, template=template)[0] |
16 | 155 | except IndexError: | 155 | except IndexError: |
17 | 156 | # there is really not such command | 156 | # there is really not such command |
18 | 157 | if template == "builtins": | 157 | if template == "builtins": |
19 | 158 | # to help the user, we can search if this command_name corresponds to a command in a template | 158 | # to help the user, we can search if this command_name corresponds to a command in a template |
21 | 159 | list_possible_commands = commands_module.get_command_by_criteria(name=command_name, followed_by_template=True) | 159 | list_possible_commands = commands_module.get_commands_by_criteria(name=command_name, followed_by_template=True) |
22 | 160 | if list_possible_commands: | 160 | if list_possible_commands: |
23 | 161 | print _("ERROR: help command must be followed by a template name for getting help from templates commands like %s." % command_name) | 161 | print _("ERROR: help command must be followed by a template name for getting help from templates commands like %s." % command_name) |
24 | 162 | print _("Candidates template are: %s") % ", ".join([command.template for command in list_possible_commands]) | 162 | print _("Candidates template are: %s") % ", ".join([command.template for command in list_possible_commands]) |
25 | 163 | 163 | ||
26 | === modified file 'quickly/commands.py' | |||
27 | --- quickly/commands.py 2009-11-15 23:06:02 +0000 | |||
28 | +++ quickly/commands.py 2009-11-19 00:25:20 +0000 | |||
29 | @@ -4,16 +4,16 @@ | |||
30 | 4 | # | 4 | # |
31 | 5 | # This file is part of Quickly | 5 | # This file is part of Quickly |
32 | 6 | # | 6 | # |
35 | 7 | #This program is free software: you can redistribute it and/or modify it | 7 | #This program is free software: you can redistribute it and/or modify it |
36 | 8 | #under the terms of the GNU General Public License version 3, as published | 8 | #under the terms of the GNU General Public License version 3, as published |
37 | 9 | #by the Free Software Foundation. | 9 | #by the Free Software Foundation. |
38 | 10 | 10 | ||
42 | 11 | #This program is distributed in the hope that it will be useful, but | 11 | #This program is distributed in the hope that it will be useful, but |
43 | 12 | #WITHOUT ANY WARRANTY; without even the implied warranties of | 12 | #WITHOUT ANY WARRANTY; without even the implied warranties of |
44 | 13 | #MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | 13 | #MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
45 | 14 | #PURPOSE. See the GNU General Public License for more details. | 14 | #PURPOSE. See the GNU General Public License for more details. |
46 | 15 | 15 | ||
48 | 16 | #You should have received a copy of the GNU General Public License along | 16 | #You should have received a copy of the GNU General Public License along |
49 | 17 | #with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | #with this program. If not, see <http://www.gnu.org/licenses/>. |
50 | 18 | 18 | ||
51 | 19 | import os | 19 | import os |
52 | @@ -29,16 +29,19 @@ | |||
53 | 29 | 29 | ||
54 | 30 | gettext.textdomain('quickly') | 30 | gettext.textdomain('quickly') |
55 | 31 | 31 | ||
57 | 32 | # double depths tabular : template (or "builtin"), name | 32 | # A dictionary with keys either 'builtins' or the names of templates. Values |
58 | 33 | # are another dictionary mapping command names to their command objects. This | ||
59 | 34 | # is used as a cache of all commands that we've found in templates. | ||
60 | 33 | __commands = {} | 35 | __commands = {} |
61 | 34 | 36 | ||
62 | 35 | 37 | ||
63 | 36 | def get_all_commands(): | 38 | def get_all_commands(): |
64 | 37 | """Load all commands | 39 | """Load all commands |
69 | 38 | 40 | ||
70 | 39 | First, load template command and then builtins one. Push right parameters depending | 41 | First, load template command and then builtins one. Push right parameters |
71 | 40 | if hooks are available, or if the command execution is special | 42 | depending if hooks are available, or if the command execution is special |
72 | 41 | You can note that create command is automatically overloaded atm""" | 43 | You can note that create command is automatically overloaded atm. |
73 | 44 | """ | ||
74 | 42 | 45 | ||
75 | 43 | if len(__commands) > 0: | 46 | if len(__commands) > 0: |
76 | 44 | return __commands | 47 | return __commands |
77 | @@ -57,21 +60,32 @@ | |||
78 | 57 | launch_outside_project_command_list = [] | 60 | launch_outside_project_command_list = [] |
79 | 58 | command_followed_by_command_list = [] | 61 | command_followed_by_command_list = [] |
80 | 59 | try: | 62 | try: |
84 | 60 | files_command_parameters = file(os.path.join(template_path, "commandsconfig"), 'rb') | 63 | files_command_parameters = file( |
85 | 61 | for line in files_command_parameters: | 64 | os.path.join(template_path, "commandsconfig"), 'rb') |
86 | 62 | fields = line.split('#')[0] # Suppress commentary after the value in configuration file and in full line | 65 | for line in files_command_parameters: |
87 | 66 | # Suppress commentary after the value in configuration | ||
88 | 67 | # file and in full line. | ||
89 | 68 | fields = line.split('#')[0] | ||
90 | 63 | fields = fields.split('=') # Separate variable from value | 69 | fields = fields.split('=') # Separate variable from value |
91 | 64 | # normally, we have two fields in "fields" | 70 | # normally, we have two fields in "fields" |
92 | 65 | if len(fields) == 2: | 71 | if len(fields) == 2: |
93 | 66 | targeted_property = fields[0].strip() | 72 | targeted_property = fields[0].strip() |
100 | 67 | command_list = [command.strip() for command in fields[1].split(';')] | 73 | command_list = [ |
101 | 68 | if targeted_property == 'COMMANDS_LAUNCHED_IN_OR_OUTSIDE_PROJECT': | 74 | command.strip() |
102 | 69 | launch_inside_project_command_list.extend(command_list) | 75 | for command in fields[1].split(';')] |
103 | 70 | launch_outside_project_command_list.extend(command_list) | 76 | if (targeted_property |
104 | 71 | if targeted_property == 'COMMANDS_LAUNCHED_OUTSIDE_PROJECT_ONLY': | 77 | == 'COMMANDS_LAUNCHED_IN_OR_OUTSIDE_PROJECT'): |
105 | 72 | launch_outside_project_command_list.extend(command_list) | 78 | launch_inside_project_command_list.extend( |
106 | 79 | command_list) | ||
107 | 80 | launch_outside_project_command_list.extend( | ||
108 | 81 | command_list) | ||
109 | 82 | if (targeted_property | ||
110 | 83 | == 'COMMANDS_LAUNCHED_OUTSIDE_PROJECT_ONLY'): | ||
111 | 84 | launch_outside_project_command_list.extend( | ||
112 | 85 | command_list) | ||
113 | 73 | if targeted_property == 'COMMANDS_FOLLOWED_BY_COMMAND': | 86 | if targeted_property == 'COMMANDS_FOLLOWED_BY_COMMAND': |
115 | 74 | command_followed_by_command_list.extend(command_list) | 87 | command_followed_by_command_list.extend( |
116 | 88 | command_list) | ||
117 | 75 | except (OSError, IOError): | 89 | except (OSError, IOError): |
118 | 76 | pass | 90 | pass |
119 | 77 | 91 | ||
120 | @@ -81,13 +95,20 @@ | |||
121 | 81 | if "." in command_name: | 95 | if "." in command_name: |
122 | 82 | command_name = ".".join(command_name.split('.')[0:-1]) | 96 | command_name = ".".join(command_name.split('.')[0:-1]) |
123 | 83 | 97 | ||
126 | 84 | if os.path.isfile(file_path) and os.access(file_path, os.X_OK): # add the command to the list if is executable | 98 | # add the command to the list if is executable |
127 | 85 | hooks = {'pre': None, 'post':None} | 99 | # XXX: It's generally a bad idea to check if you can read to a |
128 | 100 | # file. Instead, you should just read it. The file might | ||
129 | 101 | # become unreadable between here and when you actually read | ||
130 | 102 | # it. -- jml, 2009-11-18 | ||
131 | 103 | if os.path.isfile(file_path) and os.access(file_path, os.X_OK): | ||
132 | 104 | hooks = {'pre': None, 'post': None} | ||
133 | 86 | for event in ('pre', 'post'): | 105 | for event in ('pre', 'post'): |
138 | 87 | if hasattr(builtincommands, event + '_' + command_name): | 106 | event_hook = getattr( |
139 | 88 | hooks[event] = getattr(builtincommands, event + '_' + command_name) | 107 | builtincommands, event + '_' + command_name, None) |
140 | 89 | 108 | if event_hook is not None: | |
141 | 90 | # define special options for command | 109 | hooks[event] = event_hook |
142 | 110 | |||
143 | 111 | # define special options for command | ||
144 | 91 | launch_inside_project = False | 112 | launch_inside_project = False |
145 | 92 | launch_outside_project = False | 113 | launch_outside_project = False |
146 | 93 | followed_by_template = False | 114 | followed_by_template = False |
147 | @@ -99,18 +120,25 @@ | |||
148 | 99 | followed_by_template = True | 120 | followed_by_template = True |
149 | 100 | if command_name in builtincommands.followed_by_command: | 121 | if command_name in builtincommands.followed_by_command: |
150 | 101 | followed_by_command = True | 122 | followed_by_command = True |
153 | 102 | # default for commands: if not inside nor outside, and it's a template command, make it launch inside a project only | 123 | # default for commands: if not inside nor outside, and |
154 | 103 | if not launch_inside_project and not launch_outside_project: | 124 | # it's a template command, make it launch inside a project |
155 | 125 | # only | ||
156 | 126 | if not (launch_inside_project or launch_outside_project): | ||
157 | 104 | launch_inside_project = True | 127 | launch_inside_project = True |
162 | 105 | 128 | ||
163 | 106 | __commands[template][command_name] = Command(command_name, file_path, template, launch_inside_project, launch_outside_project, followed_by_template, followed_by_command, hooks['pre'], hooks['post']) | 129 | __commands[template][command_name] = Command( |
164 | 107 | 130 | command_name, file_path, template, | |
165 | 108 | 131 | launch_inside_project, launch_outside_project, | |
166 | 132 | followed_by_template, followed_by_command, | ||
167 | 133 | hooks['pre'], hooks['post']) | ||
168 | 134 | |||
169 | 135 | |||
170 | 109 | # add builtin commands (avoiding gettext and hooks) | 136 | # add builtin commands (avoiding gettext and hooks) |
171 | 110 | __commands['builtins'] = {} | 137 | __commands['builtins'] = {} |
172 | 111 | for elem in dir(builtincommands): | 138 | for elem in dir(builtincommands): |
173 | 112 | command = getattr(builtincommands, elem) | 139 | command = getattr(builtincommands, elem) |
175 | 113 | if callable(command) and not command.__name__.startswith(('pre_', 'post_', 'gettext')): | 140 | if (callable(command) |
176 | 141 | and not command.__name__.startswith(('pre_', 'post_', 'gettext'))): | ||
177 | 114 | command_name = command.__name__ | 142 | command_name = command.__name__ |
178 | 115 | # here, special case for some commands | 143 | # here, special case for some commands |
179 | 116 | launch_inside_project = False | 144 | launch_inside_project = False |
180 | @@ -127,51 +155,73 @@ | |||
181 | 127 | if command_name in builtincommands.followed_by_command: | 155 | if command_name in builtincommands.followed_by_command: |
182 | 128 | followed_by_command = True | 156 | followed_by_command = True |
183 | 129 | 157 | ||
185 | 130 | # default for commands: if not inside nor outside only, and it's a builtin command, make it launch wherever | 158 | # default for commands: if not inside nor outside only, and it's a |
186 | 159 | # builtin command, make it launch wherever | ||
187 | 131 | if not launch_inside_project and not launch_outside_project: | 160 | if not launch_inside_project and not launch_outside_project: |
188 | 132 | launch_inside_project = True | 161 | launch_inside_project = True |
189 | 133 | launch_outside_project = True | 162 | launch_outside_project = True |
190 | 134 | 163 | ||
192 | 135 | hooks = {'pre': None, 'post':None} | 164 | hooks = {'pre': None, 'post': None} |
193 | 136 | for event in ('pre', 'post'): | 165 | for event in ('pre', 'post'): |
194 | 137 | if hasattr(builtincommands, event + '_' + command_name): | 166 | if hasattr(builtincommands, event + '_' + command_name): |
199 | 138 | hooks[event] = getattr(builtincommands, event + '_' + command_name) | 167 | hooks[event] = getattr( |
200 | 139 | 168 | builtincommands, event + '_' + command_name) | |
201 | 140 | __commands['builtins'][command_name] = Command(command_name, command, None, launch_inside_project, launch_outside_project, followed_by_template, followed_by_command, hooks['pre'], hooks['post']) | 169 | |
202 | 141 | 170 | __commands['builtins'][command_name] = Command( | |
203 | 171 | command_name, command, None, launch_inside_project, | ||
204 | 172 | launch_outside_project, followed_by_template, | ||
205 | 173 | followed_by_command, hooks['pre'], hooks['post']) | ||
206 | 174 | |||
207 | 142 | return __commands | 175 | return __commands |
211 | 143 | 176 | ||
212 | 144 | 177 | ||
213 | 145 | def get_command_by_criteria(**criterias): | 178 | def get_commands_by_criteria(**criterias): |
214 | 146 | """Get a list of all commands corresponding to criterias | 179 | """Get a list of all commands corresponding to criterias |
219 | 147 | 180 | ||
220 | 148 | Criterias correponds to Command object properties""" | 181 | Criterias correponds to Command object properties. |
221 | 149 | 182 | """ | |
222 | 150 | # all criterias are None by default, which means, don't care about the value | 183 | |
223 | 184 | # all criterias are None by default, which means, don't care about the | ||
224 | 185 | # value. | ||
225 | 151 | matched_commands = [] | 186 | matched_commands = [] |
226 | 152 | all_commands = get_all_commands() | 187 | all_commands = get_all_commands() |
227 | 153 | 188 | ||
228 | 154 | for template_available in all_commands: | 189 | for template_available in all_commands: |
230 | 155 | if criterias.has_key('template') and criterias['template'] != template_available: | 190 | if ('template' in criterias |
231 | 191 | and criterias['template'] != template_available): | ||
232 | 192 | # XXX: I'm sure this speeds up the search, but what exactly is it | ||
233 | 193 | # that we're skipping and why is it ok to skip this? -- jml, | ||
234 | 194 | # 2009-11-18. | ||
235 | 156 | continue # to speed up the search | 195 | continue # to speed up the search |
236 | 157 | for candidate_command_name in all_commands[template_available]: | 196 | for candidate_command_name in all_commands[template_available]: |
238 | 158 | candidate_command = all_commands[template_available][candidate_command_name] | 197 | candidate_command = all_commands[ |
239 | 198 | template_available][candidate_command_name] | ||
240 | 159 | command_ok = True | 199 | command_ok = True |
241 | 160 | # check all criterias (template has already been checked) | 200 | # check all criterias (template has already been checked) |
242 | 161 | for elem in criterias: | 201 | for elem in criterias: |
244 | 162 | if elem is not 'template' and getattr(candidate_command, elem) != criterias[elem]: | 202 | if (elem is not 'template' |
245 | 203 | and getattr(candidate_command, elem) != criterias[elem]): | ||
246 | 163 | command_ok = False | 204 | command_ok = False |
247 | 164 | continue # no need to check other criterias | 205 | continue # no need to check other criterias |
248 | 165 | if command_ok: | 206 | if command_ok: |
251 | 166 | matched_commands.append(candidate_command) | 207 | matched_commands.append(candidate_command) |
252 | 167 | 208 | ||
253 | 168 | return matched_commands | 209 | return matched_commands |
254 | 169 | 210 | ||
255 | 170 | 211 | ||
256 | 212 | def get_command_names_by_criteria(**criteria): | ||
257 | 213 | """Get a list of all command names corresponding to criteria. | ||
258 | 214 | |||
259 | 215 | 'criteria' correponds to Command object properties. | ||
260 | 216 | """ | ||
261 | 217 | return (command.name for command in get_commands_by_criteria(**criteria)) | ||
262 | 218 | |||
263 | 219 | |||
264 | 171 | def get_all_templates(): | 220 | def get_all_templates(): |
265 | 172 | """Get a list of all templates""" | 221 | """Get a list of all templates""" |
268 | 173 | 222 | return [ | |
269 | 174 | return [template for template in get_all_commands().keys() if template != "builtins"] | 223 | template for template in get_all_commands().keys() |
270 | 224 | if template != "builtins"] | ||
271 | 175 | 225 | ||
272 | 176 | 226 | ||
273 | 177 | class Command: | 227 | class Command: |
274 | @@ -181,7 +231,10 @@ | |||
275 | 181 | print _("Aborting") | 231 | print _("Aborting") |
276 | 182 | sys.exit(return_code) | 232 | sys.exit(return_code) |
277 | 183 | 233 | ||
279 | 184 | def __init__(self, command_name, command, template=None, inside_project=True, outside_project=False, followed_by_template=False, followed_by_command=False, prehook=None, posthook=None): | 234 | def __init__(self, command_name, command, template=None, |
280 | 235 | inside_project=True, outside_project=False, | ||
281 | 236 | followed_by_template=False, followed_by_command=False, | ||
282 | 237 | prehook=None, posthook=None): | ||
283 | 185 | self.command = command | 238 | self.command = command |
284 | 186 | self.template = template | 239 | self.template = template |
285 | 187 | self.prehook = prehook | 240 | self.prehook = prehook |
286 | @@ -194,10 +247,12 @@ | |||
287 | 194 | 247 | ||
288 | 195 | def shell_completion(self, template_in_cli, args): | 248 | def shell_completion(self, template_in_cli, args): |
289 | 196 | """Smart completion of a command | 249 | """Smart completion of a command |
294 | 197 | 250 | ||
295 | 198 | This command try to see if the command is followed by a template and present template | 251 | This command try to see if the command is followed by a template and |
296 | 199 | if it's the case. Otherwise, it calls the corresponding command argument""" | 252 | present template if it's the case. Otherwise, it calls the |
297 | 200 | 253 | corresponding command argument. | |
298 | 254 | """ | ||
299 | 255 | |||
300 | 201 | completion = [] | 256 | completion = [] |
301 | 202 | 257 | ||
302 | 203 | if len(args) == 1: | 258 | if len(args) == 1: |
303 | @@ -205,101 +260,127 @@ | |||
304 | 205 | if self.followed_by_template: # template completion | 260 | if self.followed_by_template: # template completion |
305 | 206 | if not self.template: # builtins command case | 261 | if not self.template: # builtins command case |
306 | 207 | completion.extend(get_all_templates()) | 262 | completion.extend(get_all_templates()) |
308 | 208 | else: # complete with current template (which != from template_in_cli: ex create command (multiple templates)) | 263 | else: |
309 | 264 | # complete with current template (which != from | ||
310 | 265 | # template_in_cli: ex create command (multiple | ||
311 | 266 | # templates)) | ||
312 | 209 | completion.extend([self.template]) | 267 | completion.extend([self.template]) |
313 | 210 | else: # there is a template, add template commands | 268 | else: # there is a template, add template commands |
314 | 211 | if self.followed_by_command: # template command completion | 269 | if self.followed_by_command: # template command completion |
316 | 212 | completion.extend([command.name for command in get_command_by_criteria(template=template_in_cli)]) | 270 | completion.extend( |
317 | 271 | get_command_names_by_criteria( | ||
318 | 272 | template=template_in_cli)) | ||
319 | 213 | if self.followed_by_command: # builtin command completion | 273 | if self.followed_by_command: # builtin command completion |
321 | 214 | completion.extend([command.name for command in get_command_by_criteria(template="builtins")]) | 274 | completion.extend( |
322 | 275 | get_command_names_by_criteria(template="builtins")) | ||
323 | 215 | 276 | ||
324 | 216 | elif len(args) == 2: | 277 | elif len(args) == 2: |
325 | 217 | if not template_in_cli and self.followed_by_template: | 278 | if not template_in_cli and self.followed_by_template: |
326 | 218 | template_in_cli = args[0] | 279 | template_in_cli = args[0] |
330 | 219 | if self.followed_by_command: # template command completion and builtins command | 280 | # template command completion and builtins command. |
331 | 220 | completion.extend([command.name for command in get_command_by_criteria(template=template_in_cli)]) | 281 | if self.followed_by_command: |
332 | 221 | completion.extend([command.name for command in get_command_by_criteria(template="builtins")]) | 282 | completion.extend( |
333 | 283 | get_command_names_by_criteria( | ||
334 | 284 | template=template_in_cli)) | ||
335 | 285 | completion.extend( | ||
336 | 286 | get_command_names_by_criteria(template="builtins")) | ||
337 | 222 | 287 | ||
339 | 223 | # give to the command the opportunity of giving some shell-completion features | 288 | # give to the command the opportunity of giving some shell-completion |
340 | 289 | # features | ||
341 | 224 | if template_in_cli == self.template and len(completion) == 0: | 290 | if template_in_cli == self.template and len(completion) == 0: |
342 | 225 | if callable(self.command): # Internal function | 291 | if callable(self.command): # Internal function |
344 | 226 | completion.extend(self.command(template_in_cli, "", args, True)) | 292 | completion.extend( |
345 | 293 | self.command(template_in_cli, "", args, True)) | ||
346 | 227 | else: # External command | 294 | else: # External command |
348 | 228 | instance = subprocess.Popen([self.command, "shell-completion"] + args, stdout=subprocess.PIPE) | 295 | instance = subprocess.Popen( |
349 | 296 | [self.command, "shell-completion"] + args, | ||
350 | 297 | stdout=subprocess.PIPE) | ||
351 | 229 | command_return_completion, err = instance.communicate() | 298 | command_return_completion, err = instance.communicate() |
352 | 230 | if instance.returncode != 0: | 299 | if instance.returncode != 0: |
353 | 231 | print err | 300 | print err |
355 | 232 | sys.exit(1) | 301 | sys.exit(1) |
356 | 233 | completion.extend(command_return_completion.split(',')) | 302 | completion.extend(command_return_completion.split(',')) |
357 | 234 | 303 | ||
359 | 235 | return(" ".join(completion)) | 304 | return " ".join(completion) |
360 | 236 | 305 | ||
362 | 237 | def help(self, dest_path,command_args): | 306 | def help(self, dest_path, command_args): |
363 | 238 | """Print help of the current command""" | 307 | """Print help of the current command""" |
364 | 239 | 308 | ||
366 | 240 | return_code = 0 | 309 | return_code = 0 |
367 | 241 | if callable(self.command): # intern function, return __doc__ | 310 | if callable(self.command): # intern function, return __doc__ |
368 | 242 | print (self.command.__doc__) | 311 | print (self.command.__doc__) |
369 | 243 | else: # launch command with "help" parameter | 312 | else: # launch command with "help" parameter |
371 | 244 | return_code = subprocess.call([self.command, "help"] + command_args, cwd=dest_path) | 313 | return_code = subprocess.call( |
372 | 314 | [self.command, "help"] + command_args, cwd=dest_path) | ||
373 | 245 | 315 | ||
375 | 246 | return(return_code) | 316 | return return_code |
376 | 247 | 317 | ||
377 | 248 | def is_right_context(self, dest_path, verbose=True): | 318 | def is_right_context(self, dest_path, verbose=True): |
382 | 249 | """Check if we are in the right context for launching the command""" | 319 | """Check if we are in the right context for launching the command. |
383 | 250 | 320 | ||
384 | 251 | # verbose à false pour l'introspection des commandes dispos | 321 | If you are using this to introspect available commands, then set |
385 | 252 | 322 | verbose to False. | |
386 | 323 | """ | ||
387 | 253 | # check if dest_path check outside or inside only project :) | 324 | # check if dest_path check outside or inside only project :) |
388 | 254 | if self.inside_project and not self.outside_project: | 325 | if self.inside_project and not self.outside_project: |
389 | 255 | try: | 326 | try: |
390 | 256 | project_path = tools.get_root_project_path(dest_path) | 327 | project_path = tools.get_root_project_path(dest_path) |
391 | 257 | except tools.project_path_not_found: | 328 | except tools.project_path_not_found: |
392 | 258 | if verbose: | 329 | if verbose: |
394 | 259 | print _("ERROR: Can't find project in %s.\nEnsure you launch this command from a quickly project directory.") % dest_path | 330 | print (_( |
395 | 331 | "ERROR: Can't find project in %s.\nEnsure you launch " | ||
396 | 332 | "this command from a quickly project directory.") | ||
397 | 333 | % dest_path) | ||
398 | 260 | print _("Aborting") | 334 | print _("Aborting") |
399 | 261 | return False | 335 | return False |
400 | 262 | if self.outside_project and not self.inside_project: | 336 | if self.outside_project and not self.inside_project: |
401 | 263 | try: | 337 | try: |
402 | 264 | project_path = tools.get_root_project_path(dest_path) | 338 | project_path = tools.get_root_project_path(dest_path) |
403 | 265 | if verbose: | 339 | if verbose: |
406 | 266 | print _("ERROR: %s is a project. You can't launch %s command within a project. " \ | 340 | print _( |
407 | 267 | "Please choose another path." % (project_path, self.command)) | 341 | "ERROR: %s is a project. You can't launch %s command " |
408 | 342 | "within a project. Please choose another path." | ||
409 | 343 | % (project_path, self.command)) | ||
410 | 268 | print _("Aborting") | 344 | print _("Aborting") |
411 | 269 | return False | 345 | return False |
412 | 270 | except tools.project_path_not_found: | 346 | except tools.project_path_not_found: |
413 | 271 | pass | 347 | pass |
415 | 272 | 348 | ||
416 | 273 | return True | 349 | return True |
417 | 274 | 350 | ||
418 | 275 | |||
419 | 276 | def launch(self, current_dir, command_args, template=None): | 351 | def launch(self, current_dir, command_args, template=None): |
420 | 277 | """Launch command and hooks for it | 352 | """Launch command and hooks for it |
429 | 278 | 353 | ||
430 | 279 | This command will perform the right action (insider function or script execution) after having | 354 | This command will perform the right action (insider function or script |
431 | 280 | checked the context""" | 355 | execution) after having checked the context. |
432 | 281 | 356 | """ | |
433 | 282 | # template is current template (it will be useful for builtin commands) | 357 | |
434 | 283 | 358 | # template is current template (it will be useful for builtin | |
435 | 284 | # if template not specified, take the one for the command | 359 | # commands) |
436 | 285 | # the template argument is useful when builtin commands which behavior take into account the template name | 360 | |
437 | 361 | # if template not specified, take the one for the command the template | ||
438 | 362 | # argument is useful when builtin commands which behavior take into | ||
439 | 363 | # account the template name | ||
440 | 286 | if template is None: | 364 | if template is None: |
442 | 287 | template = self.template # (which can be None if it's a builtin command launched outside a project) | 365 | # (which can be None if it's a builtin command launched outside a |
443 | 366 | # project) | ||
444 | 367 | template = self.template | ||
445 | 288 | 368 | ||
446 | 289 | if not self.is_right_context(current_dir): # check in verbose mode | 369 | if not self.is_right_context(current_dir): # check in verbose mode |
448 | 290 | return(1) | 370 | return 1 |
449 | 291 | 371 | ||
450 | 292 | # get root project dir | 372 | # get root project dir |
451 | 293 | try: | 373 | try: |
452 | 294 | project_path = tools.get_root_project_path(current_dir) | 374 | project_path = tools.get_root_project_path(current_dir) |
454 | 295 | except tools.project_path_not_found: | 375 | except tools.project_path_not_found: |
455 | 296 | # launch in current project | 376 | # launch in current project |
456 | 297 | project_path = current_dir | 377 | project_path = current_dir |
457 | 298 | 378 | ||
458 | 299 | # transition if needed | 379 | # transition if needed |
459 | 300 | if self.inside_project and self.name != "upgrade": | 380 | if self.inside_project and self.name != "upgrade": |
460 | 301 | try: | 381 | try: |
462 | 302 | get_all_commands()[self.template]['upgrade'].launch(current_dir, [], template) | 382 | get_all_commands()[self.template]['upgrade'].launch( |
463 | 383 | current_dir, [], template) | ||
464 | 303 | except KeyError: # if KeyError, no upgrade command. | 384 | except KeyError: # if KeyError, no upgrade command. |
465 | 304 | pass | 385 | pass |
466 | 305 | 386 | ||
467 | @@ -307,20 +388,18 @@ | |||
468 | 307 | return_code = self.prehook(template, project_path, command_args) | 388 | return_code = self.prehook(template, project_path, command_args) |
469 | 308 | if return_code != 0: | 389 | if return_code != 0: |
470 | 309 | self._die(self.prehook.__name__, return_code) | 390 | self._die(self.prehook.__name__, return_code) |
472 | 310 | 391 | ||
473 | 311 | if callable(self.command): # Internal function | 392 | if callable(self.command): # Internal function |
474 | 312 | return_code = self.command(template, project_path, command_args) | 393 | return_code = self.command(template, project_path, command_args) |
475 | 313 | else: # External command | 394 | else: # External command |
477 | 314 | return_code = subprocess.call([self.command] + command_args, cwd=project_path) | 395 | return_code = subprocess.call( |
478 | 396 | [self.command] + command_args, cwd=project_path) | ||
479 | 315 | if return_code != 0: | 397 | if return_code != 0: |
481 | 316 | self._die(self.name,return_code) | 398 | self._die(self.name, return_code) |
482 | 317 | 399 | ||
483 | 318 | if self.posthook: | 400 | if self.posthook: |
484 | 319 | return_code = self.posthook(template, project_path, command_args) | 401 | return_code = self.posthook(template, project_path, command_args) |
485 | 320 | if return_code != 0: | 402 | if return_code != 0: |
486 | 321 | self._die(self.posthook.__name__, return_code) | 403 | self._die(self.posthook.__name__, return_code) |
492 | 322 | 404 | ||
493 | 323 | return(0) | 405 | return 0 |
489 | 324 | |||
490 | 325 | |||
491 | 326 |
This script makes quickly/commands.py follow PEP 8. It also adds a wrapper around get_command_ by_criteria to return the command names, since that's the only way it's used.
I've also added some XXX comments for things I don't understand.