Skip to content

Commit

Permalink
Add experimental tag (#12543)
Browse files Browse the repository at this point in the history
  • Loading branch information
jiasli authored Mar 16, 2020
1 parent f0ac2de commit 0ce8289
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 23 deletions.
8 changes: 7 additions & 1 deletion src/azure-cli-core/azure/cli/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from knack.introspection import extract_args_from_signature, extract_full_summary_from_signature
from knack.log import get_logger
from knack.preview import PreviewItem
from knack.experimental import ExperimentalItem
from knack.util import CLIError
from knack.arguments import ArgumentsContext, CaseInsensitiveList # pylint: disable=unused-import

Expand Down Expand Up @@ -160,7 +161,7 @@ def _update_command_table_from_modules(args):
# Changing this error message requires updating CI script that checks for failed
# module loading.
import azure.cli.core.telemetry as telemetry
logger.error("Error loading command module '%s'", mod)
logger.error("Error loading command module '%s': %s", mod, ex)
telemetry.set_exception(exception=ex, fault_type='module-load-error-' + mod,
summary='Error loading module: {}'.format(mod))
logger.debug(traceback.format_exc())
Expand Down Expand Up @@ -450,6 +451,11 @@ def command_group(self, group_name, command_type=None, **kwargs):
target=group_name,
object_type='command group'
)
if kwargs.get('is_experimental', False):
kwargs['experimental_info'] = ExperimentalItem(
target=group_name,
object_type='command group'
)
return self._command_group_cls(self, group_name, **kwargs)

def argument_context(self, scope, **kwargs):
Expand Down
1 change: 1 addition & 0 deletions src/azure-cli-core/azure/cli/core/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ def __init__(self, help_ctx, delimiters, parser):
'name_source': [action.metavar or action.dest],
'deprecate_info': getattr(action, 'deprecate_info', None),
'preview_info': getattr(action, 'preview_info', None),
'experimental_info': getattr(action, 'experimental_info', None),
'description': action.help,
'choices': action.choices,
'required': False,
Expand Down
64 changes: 43 additions & 21 deletions src/azure-cli-core/azure/cli/core/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@
import azure.cli.core.telemetry as telemetry

from knack.arguments import CLICommandArgument
from knack.commands import CLICommand, CommandGroup
from knack.commands import CLICommand, CommandGroup, PREVIEW_EXPERIMENTAL_CONFLICT_ERROR
from knack.deprecation import ImplicitDeprecated, resolve_deprecate_info
from knack.invocation import CommandInvoker
from knack.preview import ImplicitPreviewItem, PreviewItem, resolve_preview_info
from knack.experimental import ImplicitExperimentalItem, ExperimentalItem, resolve_experimental_info
from knack.log import get_logger
from knack.util import CLIError, CommandResultItem, todict
from knack.events import EVENT_INVOKER_TRANSFORM_RESULT
Expand Down Expand Up @@ -722,11 +723,31 @@ def _resolve_preview_and_deprecation_warnings(self, cmd, parsed_args):
del preview_kwargs['_get_message']
previews.append(ImplicitPreviewItem(**preview_kwargs))

experimentals = [] + getattr(parsed_args, '_argument_experimentals', [])
if cmd.experimental_info:
experimentals.append(cmd.experimental_info)
else:
# search for implicit command experimental status
path_comps = cmd.name.split()[:-1]
implicit_experimental_info = None
while path_comps and not implicit_experimental_info:
implicit_experimental_info = resolve_experimental_info(self.cli_ctx, ' '.join(path_comps))
del path_comps[-1]

if implicit_experimental_info:
experimental_kwargs = implicit_experimental_info.__dict__.copy()
experimental_kwargs['object_type'] = 'command'
del experimental_kwargs['_get_tag']
del experimental_kwargs['_get_message']
experimentals.append(ImplicitExperimentalItem(**experimental_kwargs))

if not self.cli_ctx.only_show_errors:
for d in deprecations:
print(d.message, file=sys.stderr)
for p in previews:
print(p.message, file=sys.stderr)
for e in experimentals:
print(e.message, file=sys.stderr)

def _resolve_extension_override_warning(self, cmd): # pylint: disable=no-self-use
if isinstance(cmd.command_source, ExtensionCommandSource) and cmd.command_source.overrides_command:
Expand Down Expand Up @@ -1147,11 +1168,8 @@ def custom_command(self, name, method_name=None, **kwargs):
def _command(self, name, method_name, custom_command=False, **kwargs):
self._check_stale()
merged_kwargs = self._flatten_kwargs(kwargs, get_command_type_kwarg(custom_command))
# don't inherit deprecation or preview info from command group
merged_kwargs['deprecate_info'] = kwargs.get('deprecate_info', None)
merged_kwargs['preview_info'] = None
if kwargs.get('is_preview', False):
merged_kwargs['preview_info'] = PreviewItem(self.command_loader.cli_ctx, object_type='command')
self._apply_tags(merged_kwargs, kwargs, name)

operations_tmpl = merged_kwargs['operations_tmpl']
command_name = '{} {}'.format(self.group_name, name) if self.group_name else name
self.command_loader._cli_command(command_name, # pylint: disable=protected-access
Expand Down Expand Up @@ -1191,11 +1209,7 @@ def generic_update_command(self, name, getter_name='get', getter_type=None,
self._check_stale()
merged_kwargs = self._flatten_kwargs(kwargs, get_command_type_kwarg())
merged_kwargs_custom = self._flatten_kwargs(kwargs, get_command_type_kwarg(custom_command=True))
# don't inherit deprecation or preview info from command group
merged_kwargs['deprecate_info'] = kwargs.get('deprecate_info', None)
merged_kwargs['preview_info'] = None
if kwargs.get('is_preview', False):
merged_kwargs['preview_info'] = PreviewItem(self.command_loader.cli_ctx, object_type='command')
self._apply_tags(merged_kwargs, kwargs, name)

getter_op = self._resolve_operation(merged_kwargs, getter_name, getter_type)
setter_op = self._resolve_operation(merged_kwargs, setter_name, setter_type)
Expand Down Expand Up @@ -1226,11 +1240,7 @@ def _wait_command(self, name, getter_name='get', getter_type=None, custom_comman
from azure.cli.core.commands.arm import _cli_wait_command
self._check_stale()
merged_kwargs = self._flatten_kwargs(kwargs, get_command_type_kwarg(custom_command))
# don't inherit deprecation or preview info from command group
merged_kwargs['deprecate_info'] = kwargs.get('deprecate_info', None)
merged_kwargs['preview_info'] = None
if kwargs.get('is_preview', False):
merged_kwargs['preview_info'] = PreviewItem(self.command_loader.cli_ctx, object_type='command')
self._apply_tags(merged_kwargs, kwargs, name)

if getter_type:
merged_kwargs = _merge_kwargs(getter_type.settings, merged_kwargs, CLI_COMMAND_KWARGS)
Expand All @@ -1248,18 +1258,30 @@ def _show_command(self, name, getter_name='get', getter_type=None, custom_comman
from azure.cli.core.commands.arm import _cli_show_command
self._check_stale()
merged_kwargs = self._flatten_kwargs(kwargs, get_command_type_kwarg(custom_command))
# don't inherit deprecation or preview info from command group
merged_kwargs['deprecate_info'] = kwargs.get('deprecate_info', None)
merged_kwargs['preview_info'] = None
if kwargs.get('is_preview', False):
merged_kwargs['preview_info'] = PreviewItem(self.command_loader.cli_ctx, object_type='command')
self._apply_tags(merged_kwargs, kwargs, name)

if getter_type:
merged_kwargs = _merge_kwargs(getter_type.settings, merged_kwargs, CLI_COMMAND_KWARGS)
getter_op = self._resolve_operation(merged_kwargs, getter_name, getter_type, custom_command=custom_command)
_cli_show_command(self.command_loader, '{} {}'.format(self.group_name, name), getter_op=getter_op,
custom_command=custom_command, **merged_kwargs)

def _apply_tags(self, merged_kwargs, kwargs, command_name):
# don't inherit deprecation or preview info from command group
merged_kwargs['deprecate_info'] = kwargs.get('deprecate_info', None)

# transform is_preview and is_experimental to StatusTags
merged_kwargs['preview_info'] = None
merged_kwargs['experimental_info'] = None
is_preview = kwargs.get('is_preview', False)
is_experimental = kwargs.get('is_experimental', False)
if is_preview and is_experimental:
raise CLIError(PREVIEW_EXPERIMENTAL_CONFLICT_ERROR.format("command", self.group_name + " " + command_name))
if is_preview:
merged_kwargs['preview_info'] = PreviewItem(self.command_loader.cli_ctx,object_type='command')
if is_experimental:
merged_kwargs['experimental_info'] = ExperimentalItem(self.command_loader.cli_ctx,object_type='command')


def register_cache_arguments(cli_ctx):
from knack import events
Expand Down
1 change: 1 addition & 0 deletions src/azure-cli-core/azure/cli/core/commands/arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ def add_ids_arguments(_, **kwargs): # pylint: disable=unused-argument
'dest': 'ids' if id_arg else '_ids',
'deprecate_info': deprecate_info,
'is_preview': id_arg.settings.get('is_preview', None) if id_arg else None,
'is_experimental': id_arg.settings.get('is_experimental', None) if id_arg else None,
'nargs': '+',
'arg_group': group_name
}
Expand Down
3 changes: 2 additions & 1 deletion src/azure-cli-core/azure/cli/core/commands/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@


CLI_COMMON_KWARGS = ['min_api', 'max_api', 'resource_type', 'operation_group',
'custom_command_type', 'command_type', 'is_preview', 'preview_info']
'custom_command_type', 'command_type', 'is_preview', 'preview_info',
'is_experimental', 'experimental_info']

CLI_COMMAND_KWARGS = ['transform', 'table_transformer', 'confirmation', 'exception_handler',
'client_factory', 'operations_tmpl', 'no_wait_param', 'supports_no_wait', 'validator',
Expand Down
1 change: 1 addition & 0 deletions src/azure-cli-core/azure/cli/core/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ def load_command_table(self, command_loader):
param.completer = arg.completer
param.deprecate_info = arg.deprecate_info
param.preview_info = arg.preview_info
param.experimental_info = arg.experimental_info
command_parser.set_defaults(
func=metadata,
command=command_name,
Expand Down

0 comments on commit 0ce8289

Please sign in to comment.