diff --git a/src/azure-cli-core/azure/cli/core/_help.py b/src/azure-cli-core/azure/cli/core/_help.py index 990191782d5..1ef05aaed91 100644 --- a/src/azure-cli-core/azure/cli/core/_help.py +++ b/src/azure-cli-core/azure/cli/core/_help.py @@ -77,7 +77,7 @@ def _print_examples(help_file): from colorama import Style indent = 0 _print_indent('Examples', indent) - for e in help_file.examples: + for e in AzCliHelp.example_provider(help_file): indent = 1 _print_indent(u'{0}'.format(e.short_summary), indent) indent = 2 @@ -188,6 +188,11 @@ def update_loaders_with_help_file_contents(self, nouns): file_contents[name] = self._name_to_content[name] self.versioned_loaders[ldr_cls_name].update_file_contents(file_contents) + # This method is meant to be a hook that can be overridden by an extension or module. + @staticmethod + def example_provider(help_file): + return help_file.examples + class CliHelpFile(KnackHelpFile): diff --git a/src/azure-cli/azure/cli/command_modules/find/custom.py b/src/azure-cli/azure/cli/command_modules/find/custom.py index ab1b97f5391..85f90a18927 100644 --- a/src/azure-cli/azure/cli/command_modules/find/custom.py +++ b/src/azure-cli/azure/cli/command_modules/find/custom.py @@ -4,6 +4,7 @@ # -------------------------------------------------------------------------------------------- from __future__ import print_function +from collections import namedtuple import random import json import re @@ -24,12 +25,13 @@ EXTENSION_NAME = 'find' +Example = namedtuple("Example", "title snippet") + + def process_query(cli_term): if not cli_term: logger.error('Please provide a search term e.g. az find "vm"') else: - response = call_aladdin_service(cli_term) - print(random.choice(WAIT_MESSAGE), file=sys.stderr) response = call_aladdin_service(cli_term) @@ -50,23 +52,25 @@ def process_query(cli_term): print("\nHere are the most common ways to use [" + cli_term + "]: \n", file=sys.stderr) for answer in answer_list: - current_title = answer['title'].strip() - current_snippet = answer['snippet'].strip() - if current_title.startswith("az "): - current_title, current_snippet = current_snippet, current_title - current_title = current_title.split('\r\n')[0] - elif '```azurecli\r\n' in current_snippet: - start_index = current_snippet.index('```azurecli\r\n') + len('```azurecli\r\n') - current_snippet = current_snippet[start_index:] - current_snippet = current_snippet.replace('```', '').replace(current_title, '').strip() - current_snippet = re.sub(r'\[.*\]', '', current_snippet).strip() - print(style_message(current_title)) - print(current_snippet + '\n') + cleaned_answer = clean_from_http_answer(answer) + print(style_message(cleaned_answer.title)) + print(cleaned_answer.snippet + '\n') if has_pruned_answer: print(style_message("More commands and examples are available in the latest version of the CLI. " "Please update for the best experience.\n")) +def get_generated_examples(cli_term): + examples = [] + response = call_aladdin_service(cli_term) + + if response.status_code == 200: + for answer in json.loads(response.content): + examples.append(clean_from_http_answer(answer)) + + return examples + + def style_message(msg): if should_enable_styling(): try: @@ -118,3 +122,17 @@ def call_aladdin_service(query): headers=headers) return response + + +def clean_from_http_answer(http_answer): + current_title = http_answer['title'].strip() + current_snippet = http_answer['snippet'].strip() + if current_title.startswith("az "): + current_title, current_snippet = current_snippet, current_title + current_title = current_title.split('\r\n')[0] + elif '```azurecli\r\n' in current_snippet: + start_index = current_snippet.index('```azurecli\r\n') + len('```azurecli\r\n') + current_snippet = current_snippet[start_index:] + current_snippet = current_snippet.replace('```', '').replace(current_title, '').strip() + current_snippet = re.sub(r'\[.*\]', '', current_snippet).strip() + return Example(current_title, current_snippet) diff --git a/src/azure-cli/azure/cli/command_modules/find/tests/latest/test_find.py b/src/azure-cli/azure/cli/command_modules/find/tests/latest/test_find.py index 5589081956c..be3d2f2590d 100644 --- a/src/azure-cli/azure/cli/command_modules/find/tests/latest/test_find.py +++ b/src/azure-cli/azure/cli/command_modules/find/tests/latest/test_find.py @@ -3,22 +3,79 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -import contextlib +import json import unittest import mock -import sys -import six -from six import StringIO +import requests -from azure.cli.command_modules.find.custom import call_aladdin_service -from azure.cli.core.mock import DummyCli +from azure.cli.command_modules.find.custom import (Example, call_aladdin_service, + get_generated_examples, clean_from_http_answer) + + +def create_valid_http_response(): + mock_response = requests.Response() + mock_response.status_code = 200 + data = [{ + 'title': 'RunTestAutomation', + 'snippet': 'az find' + }, { + 'title': 'az test', + 'snippet': 'The title' + }] + mock_response._content = json.dumps(data) + return mock_response + + +def create_empty_http_response(): + mock_response = requests.Response() + mock_response.status_code = 200 + data = [] + mock_response._content = json.dumps(data) + return mock_response class FindCustomCommandTest(unittest.TestCase): def test_call_aladdin_service(self): - response = call_aladdin_service("RunTestAutomation") - self.assertEqual(200, response.status_code) + mock_response = create_valid_http_response() + + with mock.patch('requests.get', return_value=(mock_response)): + response = call_aladdin_service('RunTestAutomation') + self.assertEqual(200, response.status_code) + self.assertEqual(2, len(json.loads(response.content))) + + def test_example_clean_from_http_answer(self): + cleaned_responses = [] + mock_response = create_valid_http_response() + + for response in json.loads(mock_response.content): + cleaned_responses.append(clean_from_http_answer(response)) + + self.assertEqual('RunTestAutomation', cleaned_responses[0].title) + self.assertEqual('az find', cleaned_responses[0].snippet) + self.assertEqual('The title', cleaned_responses[1].title) + self.assertEqual('az test', cleaned_responses[1].snippet) + + def test_get_generated_examples_full(self): + examples = [] + mock_response = create_valid_http_response() + + with mock.patch('requests.get', return_value=(mock_response)): + examples = get_generated_examples('RunTestAutomation') + + self.assertEqual('RunTestAutomation', examples[0].title) + self.assertEqual('az find', examples[0].snippet) + self.assertEqual('The title', examples[1].title) + self.assertEqual('az test', examples[1].snippet) + + def test_get_generated_examples_empty(self): + examples = [] + mock_response = create_empty_http_response() + + with mock.patch('requests.get', return_value=(mock_response)): + examples = get_generated_examples('RunTestAutomation') + + self.assertEqual(0, len(examples)) if __name__ == '__main__':