diff --git a/az b/az old mode 100755 new mode 100644 diff --git a/azure-cli.pyproj b/azure-cli.pyproj index 10e839a95da..f029358170c 100644 --- a/azure-cli.pyproj +++ b/azure-cli.pyproj @@ -12,11 +12,8 @@ . {888888a0-9f3d-457c-b088-3a5042f75d52} Standard Python launcher - {1dd9c42b-5980-42ce-a2c3-46d3bf0eede4} + {4ae3497d-f45c-4ec2-9e26-57476ef276a0} 3.5 - - - False @@ -28,34 +25,19 @@ - - - - Code - - Code - - - Code - + + + - - Code - - - Code - - - Code @@ -72,6 +54,28 @@ + + {83c20e12-84e3-4c10-a1ba-466d2b57483d} + {2af0f10d-7135-4994-9156-5d01c9c11b7e} + 2.7 + env27b (Python 2.7) + Scripts\python.exe + Scripts\pythonw.exe + Lib\ + PYTHONPATH + X86 + + + {4ae3497d-f45c-4ec2-9e26-57476ef276a0} + {2af0f10d-7135-4994-9156-5d01c9c11b7e} + 3.5 + env35d (Python 3.5) + Scripts\python.exe + Scripts\pythonw.exe + Lib\ + PYTHONPATH + X86 + {1dd9c42b-5980-42ce-a2c3-46d3bf0eede4} {2af0f10d-7135-4994-9156-5d01c9c11b7e} diff --git a/src/azure/cli/_argparse.py b/src/azure/cli/_argparse.py index 70abf3e3b56..bbd22236541 100644 --- a/src/azure/cli/_argparse.py +++ b/src/azure/cli/_argparse.py @@ -107,10 +107,10 @@ def add_command(self, m['$args'] = [] m['$kwargs'] = kw = {} m['$argdoc'] = ad = [] - for spec, desc in args or []: + for spec, desc, req in args or []: if not any(spec.startswith(p) for p in ARG_PREFIXES): m['$args'].append(spec.strip('<> ')) - ad.append((spec, desc)) + ad.append((spec, desc, req)) continue aliases = spec.split() @@ -119,10 +119,12 @@ def add_command(self, else: v = aliases.pop().strip('<> ') target, _ = _read_arg(aliases[0]) - kw.update({_read_arg(a)[0]: (target, v) for a in aliases}) - ad.append(('/'.join(aliases), desc)) - + kw.update({_read_arg(a)[0]: (target, v, req) for a in aliases}) + ad.append(('/'.join(aliases), desc, req)) + #pylint: disable=too-many-branches + #pylint: disable=too-many-statements + #pylint: disable=too-many-locals def execute(self, args, show_usage=False, @@ -209,6 +211,14 @@ def not_global(a): parsed.positional.append(n) n = next_n + required_args = [x for x, _, req in expected_kwargs.values() if req] + for a in required_args: + try: + parsed[a] + except KeyError: + print(L("Missing required argument {}".format(a))) + return self._display_usage(nouns, m, out) + old_stdout = sys.stdout try: sys.stdout = out @@ -236,9 +246,10 @@ def _display_usage(self, nouns, noun_map, out=sys.stdout): argdoc = noun_map.get('$argdoc') if argdoc: print('Arguments', file=out) - maxlen = max(len(a) for a, d in argdoc) - for a, d in argdoc: - print(' {0:<{1}} - {2}'.format(a, maxlen, d), file=out) + maxlen = max(len(a) for a, d, r in argdoc) + for a, d, r in argdoc: + print(' {0:<{1}} - {2} {3}'.format(a, maxlen, d, L("[Required]") if r else ""), + file=out) print(file=out) out.flush() diff --git a/src/azure/cli/commands/__init__.py b/src/azure/cli/commands/__init__.py index d27ce5d1570..23a6a8c9057 100644 --- a/src/azure/cli/commands/__init__.py +++ b/src/azure/cli/commands/__init__.py @@ -28,9 +28,10 @@ def add_description(handler): return handler return add_description -def option(spec, description_text=None): +def option(spec, description_text=None, required=False): def add_option(handler): - _COMMANDS.setdefault(handler, {}).setdefault('args', []).append((spec, description_text)) + _COMMANDS.setdefault(handler, {}).setdefault('args', []) \ + .append((spec, description_text, required)) logger.debug('Added option "%s" to %s', spec, handler) return handler return add_option diff --git a/src/azure/cli/tests/test_argparse.py b/src/azure/cli/tests/test_argparse.py index 99f6b7fa0e3..1ba3540800a 100644 --- a/src/azure/cli/tests/test_argparse.py +++ b/src/azure/cli/tests/test_argparse.py @@ -36,7 +36,7 @@ def set_n3(a, b): res[2] = True def test_args(self): p = ArgumentParser('test') - p.add_command(lambda a, b: (a, b), 'n1', args=[('--arg -a', ''), ('-b ', '')]) + p.add_command(lambda a, b: (a, b), 'n1', args=[('--arg -a', '', False), ('-b ', '', False)]) res, other = p.execute('n1 -a x'.split()) self.assertTrue(res.arg) @@ -69,7 +69,7 @@ def test_args(self): def test_unexpected_args(self): p = ArgumentParser('test') - p.add_command(lambda a, b: (a, b), 'n1', args=[('-a', '')]) + p.add_command(lambda a, b: (a, b), 'n1', args=[('-a', '', False)]) res, other = p.execute('n1 -b=2'.split()) self.assertFalse(res) @@ -84,5 +84,16 @@ def test_unexpected_args(self): self.assertEqual('2', other.b.c.d) self.assertEqual('3', other.b.c.e) + def test_required_args(self): + p = ArgumentParser('test') + p.add_command(lambda a, b: (a, b), 'n1', args=[('--arg -a', '', True), ('-b ', '', False)]) + + res, other = p.execute('n1 -a x'.split()) + self.assertTrue(res.arg) + self.assertSequenceEqual(res.positional, ['x']) + + self.assertIsNone(p.execute('n1 -b x'.split())) + + if __name__ == '__main__': unittest.main() diff --git a/src/azure/cli/tests/test_autocommand.py b/src/azure/cli/tests/test_autocommand.py index ee403cae0f0..7cc8fddabe2 100644 --- a/src/azure/cli/tests/test_autocommand.py +++ b/src/azure/cli/tests/test_autocommand.py @@ -47,7 +47,7 @@ def testfunc(): self.assertIsNotNone(registered_command) self.assertEqual(registered_command['name'], command_name) self.assertEqual(len(registered_command['args']), 1) - self.assertEqual(registered_command['args'][0], (spec, desc)) + self.assertEqual(registered_command['args'][0], (spec, desc, False)) def test_load_test_commands(self): import sys