Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions 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 @@ -85,8 +86,8 @@ def get_cli_version(self):

def show_version(self):
from azure.cli.core.util import get_az_version_string
from azure.cli.core.commands.constants import SURVEY_PROMPT
import colorama
from azure.cli.core.commands.constants import SURVEY_PROMPT, SURVEY_PROMPT_COLOR

ver_string, updates_available = get_az_version_string()
print(ver_string)
if updates_available == -1:
Expand All @@ -98,9 +99,7 @@ def show_version(self):
else:
print('Your CLI is up-to-date.')

colorama.init() # This could be removed when knack fix is released
print('\n' + SURVEY_PROMPT)
colorama.deinit() # This could be removed when knack fix is released
print('\n' + (SURVEY_PROMPT_COLOR if self.enable_color else SURVEY_PROMPT))

def exception_handler(self, ex): # pylint: disable=no-self-use
from azure.cli.core.util import handle_exception
Expand Down Expand Up @@ -162,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 +449,13 @@ def command_group(self, group_name, command_type=None, **kwargs):
kwargs['deprecate_info'].target = group_name
if kwargs.get('is_preview', False):
kwargs['preview_info'] = PreviewItem(
cli_ctx=self.cli_ctx,
target=group_name,
object_type='command group'
)
if kwargs.get('is_experimental', False):
kwargs['experimental_info'] = ExperimentalItem(
cli_ctx=self.cli_ctx,
target=group_name,
object_type='command group'
)
Expand Down
19 changes: 12 additions & 7 deletions src/azure-cli-core/azure/cli/core/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import argparse

from azure.cli.core.commands import ExtensionCommandSource
from azure.cli.core.commands.constants import SURVEY_PROMPT
from azure.cli.core.commands.constants import SURVEY_PROMPT, SURVEY_PROMPT_COLOR

from knack.help import (HelpFile as KnackHelpFile, CommandHelpFile as KnackCommandHelpFile,
GroupHelpFile as KnackGroupHelpFile, ArgumentGroupRegistry as KnackArgumentGroupRegistry,
Expand Down Expand Up @@ -64,6 +64,7 @@ def _print_header(self, cli_name, help_file):
def _print_detailed_help(self, cli_name, help_file):
CLIPrintMixin._print_extensions_msg(help_file)
super(CLIPrintMixin, self)._print_detailed_help(cli_name, help_file)
self._print_az_find_message(help_file.command, self.cli_ctx.enable_color)

@staticmethod
def _get_choices_defaults_sources_str(p):
Expand All @@ -75,7 +76,6 @@ def _get_choices_defaults_sources_str(p):

@staticmethod
def _print_examples(help_file):
from colorama import Style
indent = 0
_print_indent('Examples', indent)
for e in help_file.examples:
Expand All @@ -86,9 +86,15 @@ def _print_examples(help_file):
_print_indent(u'{0}'.format(e.long_summary), indent)
_print_indent(u'{0}'.format(e.command), indent)
print('')

@staticmethod
def _print_az_find_message(command, enable_color):
from colorama import Style
indent = 0
message = 'For more specific examples, use: az find "az {}"'.format(help_file.command)
_print_indent(Style.BRIGHT + message + Style.RESET_ALL + '\n', indent)
message = 'For more specific examples, use: az find "az {}"'.format(command)
if enable_color:
message = Style.BRIGHT + message + Style.RESET_ALL
_print_indent(message + '\n', indent)

@staticmethod
def _process_value_sources(p):
Expand Down Expand Up @@ -153,8 +159,6 @@ def new_normalize_text(s):
def show_help(self, cli_name, nouns, parser, is_group):
self.update_loaders_with_help_file_contents(nouns)

import colorama
colorama.init(autoreset=True)
delimiters = ' '.join(nouns)
help_file = self.command_help_cls(self, delimiters, parser) if not is_group \
else self.group_help_cls(self, delimiters, parser)
Expand All @@ -165,7 +169,7 @@ def show_help(self, cli_name, nouns, parser, is_group):
AzCliHelp.update_examples(help_file)
self._print_detailed_help(cli_name, help_file)

print(SURVEY_PROMPT)
print(SURVEY_PROMPT_COLOR if self.cli_ctx.enable_color else SURVEY_PROMPT)

def _register_help_loaders(self):
import azure.cli.core._help_loaders as help_loaders
Expand Down Expand Up @@ -288,6 +292,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
28 changes: 0 additions & 28 deletions src/azure-cli-core/azure/cli/core/_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,6 @@


class AzOutputProducer(knack.output.OutputProducer):
def __init__(self, cli_ctx=None):
super(AzOutputProducer, self).__init__(cli_ctx)
additional_formats = {
'yaml': self.format_yaml,
'yamlc': self.format_yaml_color,
'none': self.format_none
}
super(AzOutputProducer, self)._FORMAT_DICT.update(additional_formats)

@staticmethod
def format_yaml(obj):
from yaml import (safe_dump, representer)
import json

try:
return safe_dump(obj.result, default_flow_style=False)
except representer.RepresenterError:
# yaml.safe_dump fails when obj.result is an OrderedDict. knack's --query implementation converts the result to an OrderedDict. https://github.com/microsoft/knack/blob/af674bfea793ff42ae31a381a21478bae4b71d7f/knack/query.py#L46. # pylint: disable=line-too-long
return safe_dump(json.loads(json.dumps(obj.result)), default_flow_style=False)

@staticmethod
def format_yaml_color(obj):
from pygments import highlight, lexers, formatters
return highlight(AzOutputProducer.format_yaml(obj), lexers.YamlLexer(), formatters.TerminalFormatter()) # pylint: disable=no-member

@staticmethod
def format_none(_):
return ""

def check_valid_format_type(self, format_type):
return format_type in self._FORMAT_DICT
Expand Down
82 changes: 48 additions & 34 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 @@ -686,8 +687,6 @@ def resolve_warnings(self, cmd, parsed_args):
self._resolve_extension_override_warning(cmd)

def _resolve_preview_and_deprecation_warnings(self, cmd, parsed_args):
import colorama

deprecations = [] + getattr(parsed_args, '_argument_deprecations', [])
if cmd.deprecate_info:
deprecations.append(cmd.deprecate_info)
Expand Down Expand Up @@ -724,12 +723,31 @@ def _resolve_preview_and_deprecation_warnings(self, cmd, parsed_args):
del preview_kwargs['_get_message']
previews.append(ImplicitPreviewItem(**preview_kwargs))

colorama.init()
for d in deprecations:
print(d.message, file=sys.stderr)
for p in previews:
print(p.message, file=sys.stderr)
colorama.deinit()
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 @@ -864,12 +882,8 @@ def _generate_template_progress(self, correlation_id): # pylint: disable=no-sel
logger.info(result)

def __call__(self, poller):
import colorama
from msrest.exceptions import ClientException

# https://github.com/azure/azure-cli/issues/3555
colorama.init()

correlation_message = ''
self.cli_ctx.get_progress_controller().begin()
correlation_id = None
Expand Down Expand Up @@ -910,7 +924,6 @@ def __call__(self, poller):
handle_long_running_operation_exception(client_exception)

self.cli_ctx.get_progress_controller().end()
colorama.deinit()

return result

Expand Down Expand Up @@ -1162,11 +1175,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 @@ -1206,11 +1216,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 @@ -1241,11 +1247,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 @@ -1263,18 +1265,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
8 changes: 5 additions & 3 deletions 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 All @@ -31,5 +32,6 @@

BLACKLISTED_MODS = ['context', 'shell', 'documentdb', 'component']

SURVEY_PROMPT = Fore.YELLOW + Style.BRIGHT + 'Please let us know how we are doing: ' + Fore.BLUE \
+ 'https://aka.ms/clihats' + Style.RESET_ALL
SURVEY_PROMPT = 'Please let us know how we are doing: https://aka.ms/clihats'
SURVEY_PROMPT_COLOR = Fore.YELLOW + Style.BRIGHT + 'Please let us know how we are doing: ' + Fore.BLUE + \
'https://aka.ms/clihats' + Style.RESET_ALL
7 changes: 1 addition & 6 deletions src/azure-cli-core/azure/cli/core/extension/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ def _validate_whl_extension(ext_file):


def _add_whl_ext(cmd, source, ext_sha256=None, pip_extra_index_urls=None, pip_proxy=None): # pylint: disable=too-many-statements
import colorama
colorama.init() # Required for displaying the spinner correctly on windows issue #9140
cmd.cli_ctx.get_progress_controller().add(message='Analyzing')
if not source.endswith('.whl'):
raise ValueError('Unknown extension type. Only Python wheels are supported.')
Expand Down Expand Up @@ -158,7 +156,7 @@ def _add_whl_ext(cmd, source, ext_sha256=None, pip_extra_index_urls=None, pip_pr
dst = os.path.join(extension_path, whl_filename)
shutil.copyfile(ext_file, dst)
logger.debug('Saved the whl to %s', dst)
colorama.deinit()

return extension_name


Expand Down Expand Up @@ -205,10 +203,7 @@ def add_extension(cmd, source=None, extension_name=None, index_url=None, yes=Non
pip_extra_index_urls=None, pip_proxy=None):
ext_sha256 = None
if extension_name:
import colorama
colorama.init() # Required for displaying the spinner correctly on windows issue #9140
cmd.cli_ctx.get_progress_controller().add(message='Searching')
colorama.deinit()
ext = None
try:
ext = get_extension(extension_name)
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
2 changes: 1 addition & 1 deletion src/azure-cli-core/azure/cli/core/tests/test_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_yaml_output_with_ordered_dict(self):
}

output_producer = AzOutputProducer(DummyCli())
yaml_output = output_producer.format_yaml(CommandResultItem(result=OrderedDict(account_dict)))
yaml_output = output_producer.get_formatter('yaml')(CommandResultItem(result=OrderedDict(account_dict)))
self.assertEqual(account_dict, yaml.safe_load(yaml_output))


Expand Down
2 changes: 1 addition & 1 deletion src/azure-cli-core/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
'colorama>=0.3.9',
'humanfriendly~=4.7',
'jmespath',
'knack~=0.6.2',
'knack==0.7.0rc1',
'msrest>=0.4.4',
'msrestazure>=0.6.2',
'paramiko>=2.0.8,<3.0.0',
Expand Down
Loading