Skip to content

Commit b682355

Browse files
committed
Enable support for passing global options
1 parent 44c1c1a commit b682355

File tree

3 files changed

+80
-24
lines changed

3 files changed

+80
-24
lines changed

flask_script/__init__.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -123,29 +123,39 @@ def create_app(self, **kwargs):
123123

124124
return self.app(**kwargs)
125125

126-
def create_parser(self, prog, parser=None):
126+
def create_parser(self, prog, parents=None):
127127

128128
"""
129129
Creates an ArgumentParser instance from options returned
130130
by get_options(), and a subparser for the given command.
131131
"""
132132
prog = os.path.basename(prog)
133133

134-
if parser is None:
135-
parser = argparse.ArgumentParser(prog=prog, usage=self.usage)
136-
137-
#parser.set_defaults(func_handle=self._handle)
138-
134+
option_parser = argparse.ArgumentParser(add_help=False)
139135
for option in self.get_options():
140-
parser.add_argument(*option.args, **option.kwargs)
136+
option_parser.add_argument(*option.args, **option.kwargs)
137+
138+
if parents is None:
139+
parents = [option_parser]
141140

142-
subparsers = parser.add_subparsers() # dest='subparser_'+prog)
143-
for name, command in self._commands.iteritems():
141+
def _create_command(item):
142+
name, command = item
144143
description = getattr(command, 'description',
145-
'Perform command ' + name)
146-
p = subparsers.add_parser(name, help=description, usage=description)
147-
p = command.create_parser(name, parser=p)
144+
command.__doc__)
145+
return name, command, description, \
146+
command.create_parser(name, parents=parents)
148147

148+
commands = map(_create_command, self._commands.iteritems())
149+
150+
parser = argparse.ArgumentParser(prog=prog, usage=self.usage,
151+
parents=parents)
152+
153+
#parser.set_defaults(func_handle=self._handle)
154+
155+
subparsers = parser.add_subparsers()
156+
for name, command, description, parent in commands:
157+
subparsers.add_parser(name, usage=description, help=description,
158+
parents=[parent], add_help=False)
149159
return parser
150160

151161
def get_options(self):
@@ -315,11 +325,16 @@ def _handle(self, app, *args, **kwargs):
315325

316326
def handle(self, prog, args=None):
317327

318-
args = list(args or [])
319-
320328
app_parser = self.create_parser(prog)
329+
330+
if args is None or len(args) == 0:
331+
app_parser.print_help()
332+
return 2
333+
334+
args = list(args or [])
321335
app_namespace, remaining_args = app_parser.parse_known_args(args)
322336

337+
## get the handle function and remove it from parsed options
323338
kwargs = app_namespace.__dict__
324339
handle = kwargs['func_handle']
325340
del kwargs['func_handle']

flask_script/commands.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,22 +113,22 @@ def get_options(self):
113113
"""
114114
return self.option_list
115115

116-
def create_parser(self, prog, parser=None):
117-
if parser is None:
118-
parser = argparse.ArgumentParser(prog=prog,
119-
description=self.description)
116+
def create_parser(self, prog, parents=None):
117+
118+
parser = argparse.ArgumentParser(prog=prog, parents=parents,
119+
description=self.description)
120120

121121
for option in self.get_options():
122122
if isinstance(option, Group):
123123
if option.exclusive:
124124
group = parser.add_mutually_exclusive_group(
125-
required=option.required,
126-
)
125+
required=option.required,
126+
)
127127
else:
128128
group = parser.add_argument_group(
129-
title=option.title,
130-
description=option.description,
131-
)
129+
title=option.title,
130+
description=option.description,
131+
)
132132
for opt in option.get_options():
133133
group.add_argument(*opt.args, **opt.kwargs)
134134
else:

tests.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ def run(command_line, manager_run, capture_stderr=False):
2525
exit_code = e.code
2626
finally:
2727
out = sys.stdout.getvalue()
28+
# clear the standard output buffer
29+
sys.stdout.truncate(0)
30+
assert len(sys.stdout.getvalue()) == 0
2831
if capture_stderr:
2932
out += sys.stderr.getvalue()
3033
sys.stderr = sys_stderr_orig
@@ -260,7 +263,7 @@ def hello_again(name, url=None):
260263
stdout, code = run('manage.py hello_again --name=joe --url=reddit.com', lambda: manager.run())
261264
assert 'hello joe from reddit.com' in stdout
262265

263-
def test_global_option_provided_before_command(self):
266+
def test_global_option_provided_before_and_after_command(self):
264267

265268
manager = Manager(self.app)
266269
manager.add_option('-c', '--config', dest='config_name', required=False, default='Development')
@@ -272,6 +275,44 @@ def test_global_option_provided_before_command(self):
272275
assert code == 0
273276
assert 'OK' in stdout
274277

278+
stdout, code = run('manage.py simple -c Development', lambda: manager.run())
279+
assert code == 0
280+
assert 'OK' in stdout
281+
282+
def test_global_option_value(self):
283+
284+
def create_app(config_name='Empty'):
285+
print config_name
286+
return self.app
287+
288+
manager = Manager(create_app)
289+
manager.add_option('-c', '--config', dest='config_name', required=False, default='Development')
290+
manager.add_command('simple', SimpleCommand())
291+
292+
assert isinstance(manager._commands['simple'], SimpleCommand)
293+
294+
stdout, code = run('manage.py simple', lambda: manager.run())
295+
assert code == 0
296+
assert 'Empty' not in stdout # config_name is overwritten by default option value
297+
assert 'Development' in stdout
298+
assert 'OK' in stdout
299+
300+
stdout, code = run('manage.py -c Before simple', lambda: manager.run())
301+
assert code == 0
302+
assert 'Before' in stdout
303+
assert 'OK' in stdout
304+
305+
stdout, code = run('manage.py simple -c After', lambda: manager.run())
306+
assert code == 0
307+
assert 'After' in stdout
308+
assert 'OK' in stdout
309+
310+
stdout, code = run('manage.py -c DoNotShow simple -c NewValue', lambda: manager.run())
311+
assert code == 0
312+
assert 'DoNotShow' not in stdout # first parameter is ignored
313+
assert 'NewValue' in stdout # second on is printed
314+
assert 'OK' in stdout
315+
275316
def test_get_usage(self):
276317

277318
manager = Manager(self.app)

0 commit comments

Comments
 (0)