| 247 | |
| 248 | |
| 249 | class CommandValidator: |
| 250 | def __init__(self, driver): |
| 251 | self.driver = driver |
| 252 | help_command = self.driver.create_help_command() |
| 253 | self._service_command_table = help_command.command_table |
| 254 | self._global_arg_table = help_command.arg_table |
| 255 | self._main_parser = MainArgParser( |
| 256 | self._service_command_table, |
| 257 | driver.session.user_agent(), |
| 258 | 'Some description', |
| 259 | self._global_arg_table, |
| 260 | prog="aws", |
| 261 | ) |
| 262 | |
| 263 | def validate_cli_command(self, command, filename): |
| 264 | """ |
| 265 | Validates the syntax of a CLI command by actually parsing it, which catches: |
| 266 | - Invalid service names |
| 267 | - Invalid operation names |
| 268 | - Missing required arguments |
| 269 | - Invalid argument names |
| 270 | - Malformed argument syntax |
| 271 | """ |
| 272 | try: |
| 273 | command_parts = shlex.split(command)[1:] |
| 274 | # Strip newlines from arguments that may have been included due to |
| 275 | # backslash line continuations in the RST examples |
| 276 | command_parts = [part.lstrip('\n') for part in command_parts] |
| 277 | except Exception as e: |
| 278 | raise AssertionError( |
| 279 | "Failed to parse this example as shell command: %s\n\n" |
| 280 | "Error:\n%s\n" % (command, e) |
| 281 | ) |
| 282 | |
| 283 | # TODO - for now skip validation if command uses |
| 284 | # --cli-input-json, --cli-input-yaml, or --generate-cli-skeleton |
| 285 | if any( |
| 286 | arg.startswith('--cli-input-json') |
| 287 | or arg.startswith('--cli-input-yaml') |
| 288 | or arg == '--generate-cli-skeleton' |
| 289 | for arg in command_parts |
| 290 | ): |
| 291 | return |
| 292 | |
| 293 | try: |
| 294 | # Parse global args |
| 295 | parsed_args, remaining = self._main_parser.parse_known_args( |
| 296 | command_parts |
| 297 | ) |
| 298 | service_name = parsed_args.command |
| 299 | |
| 300 | # Get the service command |
| 301 | service_cmd = self._service_command_table[service_name] |
| 302 | |
| 303 | # Create the service parser |
| 304 | cmd_table = service_cmd.create_help_command().command_table |
| 305 | if not cmd_table: |
| 306 | # Top-level commands without sub-operations (e.g. login) |
no outgoing calls