Skip to content

Commit e76bcc7

Browse files
committed
Correctly output usage errors as click does
Fixes #4
1 parent 98576d6 commit e76bcc7

File tree

4 files changed

+50
-7
lines changed

4 files changed

+50
-7
lines changed

djclick/adapter.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,13 @@ def run_from_argv(self, argv):
5050
"""
5151
Called when run from the command line.
5252
"""
53-
return self.main(args=argv[2:], standalone_mode=False)
53+
try:
54+
return self.main(args=argv[2:], standalone_mode=False)
55+
except click.ClickException as e:
56+
if getattr(e.ctx, 'traceback', False):
57+
raise
58+
e.show()
59+
sys.exit(e.exit_code)
5460

5561
def create_parser(self, progname, subcommand):
5662
"""
@@ -69,6 +75,10 @@ def map_names(self):
6975
for opt in param.opts:
7076
yield opt.lstrip('--').replace('-', '_'), param.name
7177

78+
def collect_usage_pieces(self, ctx):
79+
pieces = super(DjangoCommandMixin, self).collect_usage_pieces(ctx)
80+
return [self.name] + pieces
81+
7282
def execute(self, *args, **kwargs):
7383
"""
7484
Called when run through `call_command`. `args` are passed through,

djclick/test/conftest.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@
88

99
@pytest.fixture(scope='session')
1010
def manage():
11-
def call(*args):
11+
def call(*args, **kwargs):
12+
ignore_errors = kwargs.pop('ignore_errors', False)
13+
assert not kwargs
1214
cmd = [
1315
sys.executable,
1416
os.path.join(os.path.dirname(__file__), 'testprj', 'manage.py'),
1517
] + list(args)
16-
return subprocess.check_output(cmd, stderr=subprocess.STDOUT)
18+
try:
19+
return subprocess.check_output(cmd, stderr=subprocess.STDOUT)
20+
except subprocess.CalledProcessError as e:
21+
if not ignore_errors:
22+
raise
23+
return e.output
1724

1825
return call
1926

djclick/test/test_adapter.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,21 @@ def test_call_command_args():
6060
call_command('testcmd', '--raise')
6161

6262

63+
def test_call_command_required_args():
64+
call_command('requiredargcmd', 'arg1')
65+
with pytest.raises(click.MissingParameter):
66+
call_command('requiredargcmd')
67+
68+
69+
def test_call_command_required_args_cli(manage):
70+
out = manage('requiredargcmd', ignore_errors=True)
71+
assert out == (
72+
b'Usage: manage.py requiredargcmd [OPTIONS] ARG\n'
73+
b'\n'
74+
b'Error: Missing argument "arg".\n'
75+
)
76+
77+
6378
def test_call_command_kwargs():
6479
call_command('testcmd', raise_when_called=False)
6580
with pytest.raises(RuntimeError):
@@ -84,7 +99,7 @@ def test_call_directly():
8499
command(**{'raise': True})
85100

86101

87-
def test_django_verbosity(capsys):
102+
def test_django_verbosity(capsys, manage):
88103
# Make sure any command can be called, even if it does not explictly
89104
# accept the --verbosity option
90105
with pytest.raises(RuntimeError):
@@ -104,9 +119,13 @@ def test_django_verbosity(capsys):
104119
assert out == '2'
105120

106121
# Invalid
107-
with pytest.raises(click.BadParameter):
108-
execute_from_command_line([
109-
'./manage.py', 'ctxverbositycmd', '--verbosity', '4'])
122+
out = manage('ctxverbositycmd', '--verbosity', '4', ignore_errors=True)
123+
assert out == (
124+
b'Usage: manage.py ctxverbositycmd [OPTIONS]\n'
125+
b'\n'
126+
b'Error: Invalid value for "-v" / "--verbosity": 4 is not in the '
127+
b'valid range of 0 to 3.\n'
128+
)
110129

111130
# Default (option)
112131
execute_from_command_line([
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import djclick as click
2+
3+
4+
@click.command()
5+
@click.argument('arg')
6+
def command(arg):
7+
click.echo(arg)

0 commit comments

Comments
 (0)