From 2b974959c3fafc44f8e70cc4805aae34927988e8 Mon Sep 17 00:00:00 2001 From: Ganesh Nalawade Date: Tue, 11 May 2021 08:05:58 +0530 Subject: [PATCH] Add --help-doc subcommand for doc in stdout mode (#225) Add --help-doc subcommand for doc in stdout mode Reviewed-by: https://github.com/apps/ansible-zuul --- ansible_navigator/actions/doc.py | 14 +- .../configuration_subsystem/definitions.py | 1 + .../navigator_configuration.py | 11 +- .../navigator_post_processor.py | 13 +- .../configuration_subsystem/parser.py | 6 +- docs/settings.rst | 20 +- .../test/lookup_doc_with_ee/0.json | 53 +++++ .../test/lookup_doc_without_ee/0.json | 53 +++++ .../test/module_doc_with_ee/0.json | 65 ++++++ .../test/module_doc_without_ee/0.json | 65 ++++++ .../ansible-navigator.yml | 1 + tests/integration/_common.py | 32 ++- tests/integration/actions/doc/base.py | 25 +-- tests/integration/actions/doc/test_stdout.py | 203 ++++++++++++++++++ tests/unit/configuration_subsystem/data.py | 1 + .../test_invalid_params.py | 9 +- utilities/doc_updater.py | 9 +- 17 files changed, 549 insertions(+), 32 deletions(-) create mode 100644 tests/fixtures/integration/actions/doc/test_stdout.py/test/lookup_doc_with_ee/0.json create mode 100644 tests/fixtures/integration/actions/doc/test_stdout.py/test/lookup_doc_without_ee/0.json create mode 100644 tests/fixtures/integration/actions/doc/test_stdout.py/test/module_doc_with_ee/0.json create mode 100644 tests/fixtures/integration/actions/doc/test_stdout.py/test/module_doc_without_ee/0.json create mode 100644 tests/integration/actions/doc/test_stdout.py diff --git a/ansible_navigator/actions/doc.py b/ansible_navigator/actions/doc.py index 01956e733..fda89373c 100644 --- a/ansible_navigator/actions/doc.py +++ b/ansible_navigator/actions/doc.py @@ -90,6 +90,8 @@ def run(self, interaction: Interaction, app: AppPublic) -> Union[Interaction, No except (KeyError, AttributeError, TypeError): self._logger.info("No plugin name found in current content") return None + else: + return None elif plugin_name_source is not C.NOT_SET: self._plugin_name = self._args.plugin_name self._plugin_type = self._args.plugin_type @@ -127,6 +129,7 @@ def run_stdout(self) -> None: self._run_runner() def _run_runner(self) -> Union[dict, None]: + # pylint: disable=too-many-branches """spin up runner""" plugin_doc_response: Optional[Dict[Any, Any]] = None @@ -174,7 +177,16 @@ def _run_runner(self) -> Union[dict, None]: return None ansible_doc_path = exec_path - pass_through_arg = [self._plugin_name, "-t", self._plugin_type] + pass_through_arg = [] + if self._plugin_name is not C.NOT_SET: + pass_through_arg.append(self._plugin_name) + + if self._plugin_type is not C.NOT_SET: + pass_through_arg.extend(["-t", self._plugin_type]) + + if self._args.help_doc is True: + pass_through_arg.append("--help") + if isinstance(self._args.cmdline, list): pass_through_arg.extend(self._args.cmdline) diff --git a/ansible_navigator/configuration_subsystem/definitions.py b/ansible_navigator/configuration_subsystem/definitions.py index 49b53ef82..b112f2e9e 100644 --- a/ansible_navigator/configuration_subsystem/definitions.py +++ b/ansible_navigator/configuration_subsystem/definitions.py @@ -22,6 +22,7 @@ class CliParameters(SimpleNamespace): nargs: Union[None, Dict] = None positional: bool = False short: Union[None, str] = None + metavar: Union[None, str] = None class Constants(Enum): diff --git a/ansible_navigator/configuration_subsystem/navigator_configuration.py b/ansible_navigator/configuration_subsystem/navigator_configuration.py index fe7c03df3..bb44716e9 100644 --- a/ansible_navigator/configuration_subsystem/navigator_configuration.py +++ b/ansible_navigator/configuration_subsystem/navigator_configuration.py @@ -168,6 +168,14 @@ class Internals(SimpleNamespace): short_description="Specify the name of the execution environment image", value=EntryValue(default="quay.io/ansible/ansible-runner:devel"), ), + Entry( + name="help_doc", + choices=[True, False], + cli_parameters=CliParameters(short="--hd", action="store_true"), + short_description="Help options for ansible-doc command in stdout mode", + subcommands=["doc"], + value=EntryValue(default=False), + ), Entry( name="inventory", cli_parameters=CliParameters(action="append", nargs="+", short="-i"), @@ -239,7 +247,8 @@ class Internals(SimpleNamespace): choices=[True, False], cli_parameters=CliParameters(short="--pae"), settings_file_path_override="playbook-artifact.enable", - short_description="Enable or disable the creation of artifacts for completed playbooks", + short_description="Enable or disable the creation of artifacts for" + " completed playbooks", subcommands=["run"], value=EntryValue(default=True), ), diff --git a/ansible_navigator/configuration_subsystem/navigator_post_processor.py b/ansible_navigator/configuration_subsystem/navigator_post_processor.py index f370b30aa..1ade7ad27 100644 --- a/ansible_navigator/configuration_subsystem/navigator_post_processor.py +++ b/ansible_navigator/configuration_subsystem/navigator_post_processor.py @@ -109,6 +109,17 @@ def execution_environment(self, entry, config) -> PostProcessorReturn: errors.append(error) return messages, errors + @_post_processor + def help_doc(self, entry: Entry, config: ApplicationConfiguration) -> PostProcessorReturn: + # pylint: disable=unused-argument + """Post process help_doc""" + messages, errors = self._true_or_false(entry, config) + if all((entry.value.current is True, config.app == "doc", config.mode == "interactive")): + error = "--help-doc or --hd is valid only when 'mode' argument is set to 'stdout'" + errors.append(error) + return messages, errors + return messages, errors + @staticmethod @_post_processor def inventory(entry: Entry, config: ApplicationConfiguration) -> PostProcessorReturn: @@ -232,7 +243,7 @@ def plugin_name(entry: Entry, config: ApplicationConfiguration) -> PostProcessor """Post process plugin_name""" messages: List[LogMessage] = [] errors: List[str] = [] - if config.app == "doc" and entry.value.current is C.NOT_SET: + if all((config.app == "doc", entry.value.current is C.NOT_SET, config.help_doc is False)): error = "An plugin name is required when using the doc subcommand" errors.append(error) return messages, errors diff --git a/ansible_navigator/configuration_subsystem/parser.py b/ansible_navigator/configuration_subsystem/parser.py index 1b8920c01..316dc1d87 100644 --- a/ansible_navigator/configuration_subsystem/parser.py +++ b/ansible_navigator/configuration_subsystem/parser.py @@ -34,7 +34,6 @@ def generate_argument(entry) -> Tuple[Any, Union[Any, str, None], Dict[str, Any] if entry.value.default is not C.NOT_SET: kwargs["help"] += f" (default: {entry.value.default})" kwargs["default"] = SUPPRESS - kwargs["metavar"] = "" if entry.cli_parameters.positional: long = None @@ -45,9 +44,12 @@ def generate_argument(entry) -> Tuple[Any, Union[Any, str, None], Dict[str, Any] else: long = entry.cli_parameters.long_override or f"--{entry.name_dashed}" kwargs["dest"] = entry.name - if entry.cli_parameters.nargs is None: + if entry.cli_parameters.nargs is not None: kwargs["nargs"] = entry.cli_parameters.nargs + if entry.cli_parameters.metavar is not None: + kwargs["metavar"] = entry.cli_parameters.metavar + if entry.cli_parameters.action is not None: kwargs["action"] = entry.cli_parameters.action diff --git a/docs/settings.rst b/docs/settings.rst index ebea6729c..fbedc8fb0 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -61,6 +61,7 @@ You can copy the example settings file below into one of those paths to start yo # KEY2: VALUE2 # KEY3: VALUE3 # image: test_image + # help-doc: True # inventories: # - /tmp/test_inventory.yml # inventory-columns: @@ -159,7 +160,7 @@ The following table describes all available settings. * - editor-console - Specify if the editor is console based - | **Choices:** 'True' or 'False' - | **Default:** No default value set + | **Default:** True | **CLI:** `--econ` or `--editor-console` | **ENV:** ANSIBLE_NAVIGATOR_EDITOR_CONSOLE | **Settings file:** @@ -173,7 +174,7 @@ The following table describes all available settings. * - execution-environment - Enable or disable the use of an execution environment - | **Choices:** 'True' or 'False' - | **Default:** No default value set + | **Default:** True | **CLI:** `--ee` or `--execution-environment` | **ENV:** ANSIBLE_NAVIGATOR_EXECUTION_ENVIRONMENT | **Settings file:** @@ -289,6 +290,19 @@ The following table describes all available settings. * - Name - Description - Settings + * - help-doc + - Help options for ansible-doc command in stdout mode + - | **Choices:** 'True' or 'False' + | **Default:** False + | **CLI:** `--hd` or `--help-doc` + | **ENV:** ANSIBLE_NAVIGATOR_HELP_DOC + | **Settings file:** + + .. code-block:: yaml + + ansible-navigator: + help-doc: + * - plugin-name - Specify the plugin name - | **Default:** No default value set @@ -424,7 +438,7 @@ The following table describes all available settings. * - playbook-artifact-enable - Enable or disable the creation of artifacts for completed playbooks - | **Choices:** 'True' or 'False' - | **Default:** No default value set + | **Default:** True | **CLI:** `--pae` or `--playbook-artifact-enable` | **ENV:** ANSIBLE_NAVIGATOR_PLAYBOOK_ARTIFACT_ENABLE | **Settings file:** diff --git a/tests/fixtures/integration/actions/doc/test_stdout.py/test/lookup_doc_with_ee/0.json b/tests/fixtures/integration/actions/doc/test_stdout.py/test/lookup_doc_with_ee/0.json new file mode 100644 index 000000000..729a9daf2 --- /dev/null +++ b/tests/fixtures/integration/actions/doc/test_stdout.py/test/lookup_doc_with_ee/0.json @@ -0,0 +1,53 @@ +{ + "name": "test[0-ansible-navigator doc testorg.coll_1.lookup_1 -t lookup -m stdout -j --execution-environment true --ce podman-ansible-navigator lookup doc in stdout mode with EE-lookup_doc_with_ee-None]", + "index": 0, + "comment": "ansible-navigator lookup doc in stdout mode with EE", + "output": [ + "{", + " \"testorg.coll_1.lookup_1\": {", + " \"doc\": {", + " \"author\": \"test\",", + " \"collection\": \"testorg.coll_1\",", + " \"description\": [", + " \"This is test lookup plugin\"", + " ],", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + " \"name\": \"lookup_1\",", + " \"notes\": [", + " \"This is a dummy lookup plugin\"", + " ],", + " \"options\": {", + " \"bar\": {", + " \"default\": \"candidate\",", + " \"description\": [", + " \"Dummy option I(bar)\"", + " ],", + " \"type\": \"str\"", + " },", + " \"foo\": {", + " \"description\": [", + " \"Dummy option I(foo)\"", + " ],", + " \"required\": true,", + " \"type\": \"str\"", + " }", + " },", + " \"plugin_type\": \"lookup\",", + " \"short_description\": \"This is test lookup plugin\",", + " \"version_added\": \"1.0.0\",", + " \"version_added_collection\": \"testorg.coll_1\"", + " },", + " \"examples\": \"\\n - name: Retrieve a value deep inside a using a path\\n ansible.builtin.set_fact:\\n value: \\\"{{ lookup('testorg.coll_1.lookup_1', var1, var2) }}\\\"\\n \",", + " \"metadata\": null,", + " \"return\": {", + " \"_raw\": {", + " \"description\": [", + " \"One or more zero-based indices of the matching list items.\"", + " ]", + " }", + " }", + " }", + "}", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + ] +} \ No newline at end of file diff --git a/tests/fixtures/integration/actions/doc/test_stdout.py/test/lookup_doc_without_ee/0.json b/tests/fixtures/integration/actions/doc/test_stdout.py/test/lookup_doc_without_ee/0.json new file mode 100644 index 000000000..57fdf0f71 --- /dev/null +++ b/tests/fixtures/integration/actions/doc/test_stdout.py/test/lookup_doc_without_ee/0.json @@ -0,0 +1,53 @@ +{ + "name": "test[0-ansible-navigator doc testorg.coll_1.lookup_1 -t lookup -m stdout -j --execution-environment false-ansible-navigator lookup doc in stdout mode without EE-lookup_doc_without_ee-None]", + "index": 0, + "comment": "ansible-navigator lookup doc in stdout mode without EE", + "output": [ + "{", + " \"testorg.coll_1.lookup_1\": {", + " \"doc\": {", + " \"author\": \"test\",", + " \"collection\": \"testorg.coll_1\",", + " \"description\": [", + " \"This is test lookup plugin\"", + " ],", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + " \"name\": \"lookup_1\",", + " \"notes\": [", + " \"This is a dummy lookup plugin\"", + " ],", + " \"options\": {", + " \"bar\": {", + " \"default\": \"candidate\",", + " \"description\": [", + " \"Dummy option I(bar)\"", + " ],", + " \"type\": \"str\"", + " },", + " \"foo\": {", + " \"description\": [", + " \"Dummy option I(foo)\"", + " ],", + " \"required\": true,", + " \"type\": \"str\"", + " }", + " },", + " \"plugin_type\": \"lookup\",", + " \"short_description\": \"This is test lookup plugin\",", + " \"version_added\": \"1.0.0\",", + " \"version_added_collection\": \"testorg.coll_1\"", + " },", + " \"examples\": \"\\n - name: Retrieve a value deep inside a using a path\\n ansible.builtin.set_fact:\\n value: \\\"{{ lookup('testorg.coll_1.lookup_1', var1, var2) }}\\\"\\n \",", + " \"metadata\": null,", + " \"return\": {", + " \"_raw\": {", + " \"description\": [", + " \"One or more zero-based indices of the matching list items.\"", + " ]", + " }", + " }", + " }", + "}", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + ] +} \ No newline at end of file diff --git a/tests/fixtures/integration/actions/doc/test_stdout.py/test/module_doc_with_ee/0.json b/tests/fixtures/integration/actions/doc/test_stdout.py/test/module_doc_with_ee/0.json new file mode 100644 index 000000000..73a96df1b --- /dev/null +++ b/tests/fixtures/integration/actions/doc/test_stdout.py/test/module_doc_with_ee/0.json @@ -0,0 +1,65 @@ +{ + "name": "test[0-ansible-navigator doc testorg.coll_1.mod_1 -m stdout -j --execution-environment true --ce podman-ansible-navigator doc in stdout mode with EE-module_doc_with_ee-None]", + "index": 0, + "comment": "ansible-navigator doc in stdout mode with EE", + "output": [ + "{", + " \"testorg.coll_1.mod_1\": {", + " \"doc\": {", + " \"author\": [", + " \"test\"", + " ],", + " \"collection\": \"testorg.coll_1\",", + " \"description\": [", + " \"This is a test module\"", + " ],", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + " \"has_action\": false,", + " \"module\": \"mod_1\",", + " \"notes\": [", + " \"This is a dummy module\"", + " ],", + " \"options\": {", + " \"bar\": {", + " \"aliases\": [", + " \"bam\"", + " ],", + " \"choices\": [", + " \"candidate\",", + " \"running\"", + " ],", + " \"default\": \"candidate\",", + " \"description\": [", + " \"Dummy option I(bar)\"", + " ],", + " \"type\": \"str\"", + " },", + " \"foo\": {", + " \"description\": [", + " \"Dummy option I(foo)\"", + " ],", + " \"type\": \"str\"", + " }", + " },", + " \"short_description\": \"This is a test module\",", + " \"version_added\": \"1.0.0\",", + " \"version_added_collection\": \"testorg.coll_1\"", + " },", + " \"examples\": \"\\n- name: test task-1\\n testorg.coll_1.mod_1:\\n foo: somevalue\\n bar: candidate\\n\",", + " \"metadata\": null,", + " \"return\": {", + " \"baz\": {", + " \"description\": \"test return 1\",", + " \"returned\": \"success\",", + " \"sample\": [", + " \"a\",", + " \"b\"", + " ],", + " \"type\": \"list\"", + " }", + " }", + " }", + "}", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + ] +} \ No newline at end of file diff --git a/tests/fixtures/integration/actions/doc/test_stdout.py/test/module_doc_without_ee/0.json b/tests/fixtures/integration/actions/doc/test_stdout.py/test/module_doc_without_ee/0.json new file mode 100644 index 000000000..7883e10ff --- /dev/null +++ b/tests/fixtures/integration/actions/doc/test_stdout.py/test/module_doc_without_ee/0.json @@ -0,0 +1,65 @@ +{ + "name": "test[0-ansible-navigator doc testorg.coll_1.mod_1 -m stdout -j --execution-environment false-ansible-navigator doc in stdout mode without EE-module_doc_without_ee-None]", + "index": 0, + "comment": "ansible-navigator doc in stdout mode without EE", + "output": [ + "{", + " \"testorg.coll_1.mod_1\": {", + " \"doc\": {", + " \"author\": [", + " \"test\"", + " ],", + " \"collection\": \"testorg.coll_1\",", + " \"description\": [", + " \"This is a test module\"", + " ],", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + " \"has_action\": false,", + " \"module\": \"mod_1\",", + " \"notes\": [", + " \"This is a dummy module\"", + " ],", + " \"options\": {", + " \"bar\": {", + " \"aliases\": [", + " \"bam\"", + " ],", + " \"choices\": [", + " \"candidate\",", + " \"running\"", + " ],", + " \"default\": \"candidate\",", + " \"description\": [", + " \"Dummy option I(bar)\"", + " ],", + " \"type\": \"str\"", + " },", + " \"foo\": {", + " \"description\": [", + " \"Dummy option I(foo)\"", + " ],", + " \"type\": \"str\"", + " }", + " },", + " \"short_description\": \"This is a test module\",", + " \"version_added\": \"1.0.0\",", + " \"version_added_collection\": \"testorg.coll_1\"", + " },", + " \"examples\": \"\\n- name: test task-1\\n testorg.coll_1.mod_1:\\n foo: somevalue\\n bar: candidate\\n\",", + " \"metadata\": null,", + " \"return\": {", + " \"baz\": {", + " \"description\": \"test return 1\",", + " \"returned\": \"success\",", + " \"sample\": [", + " \"a\",", + " \"b\"", + " ],", + " \"type\": \"list\"", + " }", + " }", + " }", + "}", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + ] +} \ No newline at end of file diff --git a/tests/fixtures/unit/configuration_subsystem/ansible-navigator.yml b/tests/fixtures/unit/configuration_subsystem/ansible-navigator.yml index 3f0a4dd2d..c4c013a14 100644 --- a/tests/fixtures/unit/configuration_subsystem/ansible-navigator.yml +++ b/tests/fixtures/unit/configuration_subsystem/ansible-navigator.yml @@ -23,6 +23,7 @@ ansible-navigator: KEY2: VALUE2 KEY3: VALUE3 image: test_image + help-doc: True inventories: - /tmp/test_inventory.yml inventory-columns: diff --git a/tests/integration/_common.py b/tests/integration/_common.py index bb6bf6dee..024dbd86d 100644 --- a/tests/integration/_common.py +++ b/tests/integration/_common.py @@ -209,6 +209,8 @@ def __enter__(self): set_up_command = " && ".join(set_up_commands) self._pane.send_keys(set_up_command) + # get the cli prompt from pane + self._cli_prompt = self._get_cli_prompt() return self def __exit__(self, exc_type, exc_value, exc_traceback): @@ -221,6 +223,7 @@ def interaction( wait_on_help=True, wait_on_playbook_status=False, wait_on_collection_fetch_prompt=None, + wait_on_cli_prompt=False, ): """interact with the tmux session""" self._pane.send_keys(value, suppress_history=False) @@ -231,14 +234,31 @@ def interaction( while not showing: time.sleep(0.1) showing = self._pane.capture_pane() - if wait_on_help: - ok_to_return.append(any(":help help" in line for line in showing)) - if wait_on_playbook_status: - ok_to_return.append(showing[-1].endswith(wait_on_playbook_status)) - if wait_on_collection_fetch_prompt: - ok_to_return.append(wait_on_collection_fetch_prompt not in showing[0]) + if wait_on_cli_prompt: + # handle command sent but pane not updated + if len(showing) > 1: + ok_to_return.append(self._cli_prompt in showing[-1]) + else: + ok_to_return.append(False) + else: + if wait_on_help: + ok_to_return.append(any(":help help" in line for line in showing)) + if wait_on_playbook_status: + ok_to_return.append(showing[-1].endswith(wait_on_playbook_status)) + if wait_on_collection_fetch_prompt: + ok_to_return.append(wait_on_collection_fetch_prompt not in showing[0]) return showing + def _get_cli_prompt(self): + """get cli prompt""" + self._pane.send_keys("clear") + showing = [] + while len(showing) != 1: + showing = self._pane.capture_pane() + time.sleep(0.1) + + return showing[0] + def update_fixtures(request, index, received_output, comment, testname=None): """Used by action plugins to generate the fixtures""" diff --git a/tests/integration/actions/doc/base.py b/tests/integration/actions/doc/base.py index 53070c4ac..84c44eccb 100644 --- a/tests/integration/actions/doc/base.py +++ b/tests/integration/actions/doc/base.py @@ -18,10 +18,7 @@ class BaseClass: """base class for interactive config tests""" UPDATE_FIXTURES = False - - def setup_class(self): - self.expected_in_output: List = [] - self.assert_operator = "==" + WAIT_ON_CLI_PROMPT = False @staticmethod @pytest.fixture(scope="module", name="tmux_config_session") @@ -47,12 +44,16 @@ def test( # pylint: disable=too-few-public-methods # pylint: disable=too-many-arguments """test interactive config""" - received_output = tmux_config_session.interaction(user_input) + received_output = tmux_config_session.interaction( + user_input, wait_on_cli_prompt=self.WAIT_ON_CLI_PROMPT + ) updated_received_output = [] mask = "X" * 50 for line in received_output: - if "filename" in line or "│warnings:" in line: + if tmux_config_session._cli_prompt in line: + updated_received_output.append(mask) + elif "filename" in line or "│warnings:" in line: updated_received_output.append(mask) else: for value in ["time=", "skipping entry", "failed:", "permission denied"]: @@ -61,16 +62,16 @@ def test( else: updated_received_output.append(line) - if self.UPDATE_FIXTURES: - update_fixtures(request, index, updated_received_output, comment, testname=testname) - dir_path, file_name = fixture_path_from_request(request, index, testname=testname) - with open(f"{dir_path}/{file_name}", encoding="utf-8") as infile: - expected_output = json.load(infile)["output"] - if expected_in_output: for out in expected_in_output: assert any(out in line for line in received_output), (out, received_output) else: + if self.UPDATE_FIXTURES: + update_fixtures(request, index, updated_received_output, comment, testname=testname) + + dir_path, file_name = fixture_path_from_request(request, index, testname=testname) + with open(f"{dir_path}/{file_name}", encoding="utf-8") as infile: + expected_output = json.load(infile)["output"] assert expected_output == updated_received_output, "\n" + "\n".join( difflib.unified_diff( expected_output, updated_received_output, "expected", "received" diff --git a/tests/integration/actions/doc/test_stdout.py b/tests/integration/actions/doc/test_stdout.py new file mode 100644 index 000000000..69ab47150 --- /dev/null +++ b/tests/integration/actions/doc/test_stdout.py @@ -0,0 +1,203 @@ +""" doc direct from cli interactive w/ ee +""" +from typing import List + +import pytest + +from .base import BaseClass + +from ..._common import container_runtime_or_fail +from ..._common import get_executable_path + +# ansible-doc help with EE +CLI_DOC_HELP_WITH_EE = ( + "ansible-navigator doc testorg.coll_1.mod_1 --help-doc -m stdout" + " --execution-environment true --ce " + container_runtime_or_fail() +) + +testdata_1: List = [ + ( + 0, + CLI_DOC_HELP_WITH_EE, + "ansible-navigator doc help with ee", + "doc_help_with_ee", + ["usage: ansible-doc [-h]"], + ), +] + + +@pytest.mark.parametrize("index, user_input, comment, testname, expected_in_output", testdata_1) +class TestDocHelpWithEE(BaseClass): + """run the tests""" + + WAIT_ON_CLI_PROMPT = True + + +# ansible-doc help without EE +CLI_DOC_HELP_WITH_EE = ( + "ansible-navigator doc testorg.coll_1.mod_1 --help-doc -m stdout --execution-environment false" +) + +testdata_2: List = [ + ( + 0, + CLI_DOC_HELP_WITH_EE, + "ansible-navigator doc help without ee", + "doc_help_without_ee", + ["usage: ansible-doc [-h]"], + ), +] + + +@pytest.mark.parametrize("index, user_input, comment, testname, expected_in_output", testdata_2) +class TestDocHelpWithoutEE(BaseClass): + """run the tests""" + + WAIT_ON_CLI_PROMPT = True + + +# ansible-doc help failed check in interactive mode +CLI_DOC_HELP_WITH_EE_WRONG_MODE = ( + "ansible-navigator doc testorg.coll_1.mod_1 --help-doc -m interactive" + " --execution-environment true --ce " + container_runtime_or_fail() +) + +testdata_3: List = [ + ( + 0, + CLI_DOC_HELP_WITH_EE_WRONG_MODE, + "ansible-navigator doc help with ee in wrong mode", + "doc_help_with_ee_wrong_mode", + ["--help-doc or --hd is valid only when 'mode' argument is set to 'stdout'"], + ), +] + + +@pytest.mark.parametrize("index, user_input, comment, testname, expected_in_output", testdata_3) +class TestDocHelpWithEEWrongMode(BaseClass): + """run the tests""" + + WAIT_ON_CLI_PROMPT = True + + +# ansible-doc help failed check in interactive mode +CLI_DOC_HELP_WITHOUT_EE_WRONG_MODE = ( + "ansible-navigator doc testorg.coll_1.mod_1 --help-doc -m interactive" + " --execution-environment false" +) + +testdata_4: List = [ + ( + 0, + CLI_DOC_HELP_WITHOUT_EE_WRONG_MODE, + "ansible-navigator doc help without ee in wrong mode", + "doc_help_with_ee_wrong_mode", + ["--help-doc or --hd is valid only when 'mode' argument is set to 'stdout'"], + ), +] + + +@pytest.mark.parametrize("index, user_input, comment, testname, expected_in_output", testdata_4) +class TestDocHelpWithoutEEWrongMode(BaseClass): + """run the tests""" + + WAIT_ON_CLI_PROMPT = True + + +# doc command run in stdout mode without EE +CLI_MODULE_DOC_WITHOUT_EE = ( + "ansible-navigator doc testorg.coll_1.mod_1 -m stdout -j" " --execution-environment false" +) + +testdata_5: List = [ + ( + 0, + CLI_MODULE_DOC_WITHOUT_EE, + "ansible-navigator doc in stdout mode without EE", + "module_doc_without_ee", + None, + ), +] + + +@pytest.mark.parametrize("index, user_input, comment, testname, expected_in_output", testdata_5) +class TestModuleDocWithoutEE(BaseClass): + """run the tests""" + + WAIT_ON_CLI_PROMPT = True + UPDATE_FIXTURES = False + + +# doc command run in stdout mode with EE +CLI_MODULE_DOC_WITH_EE = ( + "ansible-navigator doc testorg.coll_1.mod_1 -m stdout -j" + " --execution-environment true --ce " + container_runtime_or_fail() +) + +testdata_6: List = [ + ( + 0, + CLI_MODULE_DOC_WITH_EE, + "ansible-navigator doc in stdout mode with EE", + "module_doc_with_ee", + None, + ), +] + + +@pytest.mark.parametrize("index, user_input, comment, testname, expected_in_output", testdata_6) +class TestModuleDocWithEE(BaseClass): + """run the tests""" + + WAIT_ON_CLI_PROMPT = True + UPDATE_FIXTURES = False + + +# doc command run in stdout mode without EE +CLI_LOOKUP_DOC_WITHOUT_EE = ( + "ansible-navigator doc testorg.coll_1.lookup_1 -t lookup -m stdout -j" + " --execution-environment false" +) + +testdata_7: List = [ + ( + 0, + CLI_LOOKUP_DOC_WITHOUT_EE, + "ansible-navigator lookup doc in stdout mode without EE", + "lookup_doc_without_ee", + None, + ), +] + + +@pytest.mark.parametrize("index, user_input, comment, testname, expected_in_output", testdata_7) +class TestLookUpDocWithoutEE(BaseClass): + """run the tests""" + + WAIT_ON_CLI_PROMPT = True + UPDATE_FIXTURES = False + + +# doc command run in stdout mode with EE +CLI_LOOKUP_DOC_WITH_EE = ( + "ansible-navigator doc testorg.coll_1.lookup_1 -t lookup -m stdout -j" + " --execution-environment true --ce " + container_runtime_or_fail() +) + +testdata_8: List = [ + ( + 0, + CLI_LOOKUP_DOC_WITH_EE, + "ansible-navigator lookup doc in stdout mode with EE", + "lookup_doc_with_ee", + None, + ), +] + + +@pytest.mark.parametrize("index, user_input, comment, testname, expected_in_output", testdata_8) +class TestLookUpDocWithEE(BaseClass): + """run the tests""" + + WAIT_ON_CLI_PROMPT = True + UPDATE_FIXTURES = False diff --git a/tests/unit/configuration_subsystem/data.py b/tests/unit/configuration_subsystem/data.py index 261ed8bc9..2428d6f52 100644 --- a/tests/unit/configuration_subsystem/data.py +++ b/tests/unit/configuration_subsystem/data.py @@ -190,6 +190,7 @@ def cli_data(): ("editor_console", "false", False), ("execution_environment", "false", False), ("execution_environment_image", "test_image", "test_image"), + ("help_doc", "false", False), ("inventory", "/tmp/test1.yaml,/tmp/test2.yml", ["/tmp/test1.yaml", "/tmp/test2.yml"]), ("inventory_column", "t1,t2,t3", ["t1", "t2", "t3"]), ("log_file", "/tmp/app.log", "/tmp/app.log"), diff --git a/tests/unit/configuration_subsystem/test_invalid_params.py b/tests/unit/configuration_subsystem/test_invalid_params.py index 296ba4952..318e10550 100644 --- a/tests/unit/configuration_subsystem/test_invalid_params.py +++ b/tests/unit/configuration_subsystem/test_invalid_params.py @@ -124,13 +124,16 @@ def test(subcommand, param, look_for): else: subcommand = None - if entry.cli_parameters: + if entry.cli_parameters and entry.cli_parameters.action == "store_true": + pass + elif entry.cli_parameters: + look_for = "must be one of" # ansible-navigator choice error - test(subcommand, entry.cli_parameters.short, "must be one of") + test(subcommand, entry.cli_parameters.short, look_for) test( subcommand, entry.cli_parameters.long_override or f"--{entry.name_dashed}", - "must be one of", + look_for, ) else: # argparse choice error diff --git a/utilities/doc_updater.py b/utilities/doc_updater.py index 257b8b770..af3ffa66d 100644 --- a/utilities/doc_updater.py +++ b/utilities/doc_updater.py @@ -22,6 +22,7 @@ from ansible_navigator.configuration_subsystem import NavigatorConfiguration +from ansible_navigator.configuration_subsystem import Constants as C from ansible_navigator.configuration_subsystem.definitions import Entry from ansible_navigator.utils import oxfordcomma @@ -92,11 +93,13 @@ def _params_generate_tables(param_details: Dict) -> List: tables.extend(table) tables.extend(["", "|", "|", ""]) for subcommand in NavigatorConfiguration.subcommands: + logger.debug("Processing subcommand: %s", subcommand.name) entries = [ entry for entry in NavigatorConfiguration.entries if isinstance(entry.subcommands, list) and subcommand.name in entry.subcommands ] + logger.debug(" params %s", tuple(entry.name for entry in entries)) if entries: table = copy(PARAM_TABLE_HEADER) table[0] = table[0].format(f"**Subcommand: {subcommand.name}**") @@ -154,10 +157,10 @@ def _params_row_for_entry(entry: Entry, param_details: Dict) -> Tuple: if isinstance(default_override, str): default = default_override else: - if isinstance(entry.value.default, str): - default = entry.value.default - else: + if entry.value.default is C.NOT_SET: default = "No default value set" + else: + default = entry.value.default choices = oxfordcomma(entry.choices, "or") envvar = entry.environment_variable(APP.replace("-", "_"))