From 5454c268f7fbd200d29c0a080309585319f57ae5 Mon Sep 17 00:00:00 2001 From: Roland Dobai Date: Thu, 12 Dec 2019 16:02:36 +0100 Subject: [PATCH] Docs: Omit kconfig configurations not available for the target --- components/bt/Kconfig | 2 + components/driver/Kconfig | 1 + docs/conf_common.py | 6 +- tools/ci/config/host-test.yml | 8 +- tools/ci/executable-list.txt | 3 +- tools/kconfig_new/confgen.py | 17 ++- tools/kconfig_new/gen_kconfig_doc.py | 137 ++++++++++++++++-- .../kconfig_new/test/{ => confserver}/Kconfig | 0 .../test/{ => confserver}/README.md | 0 .../test/{ => confserver}/sdkconfig | 0 .../test/{ => confserver}/test_confserver.py | 12 +- .../test/{ => confserver}/testcases_v1.txt | 0 .../test/{ => confserver}/testcases_v2.txt | 0 .../kconfig_new/test/gen_kconfig_doc/Kconfig | 137 ++++++++++++++++++ .../test/gen_kconfig_doc/Kconfig.chipa | 19 +++ .../test/gen_kconfig_doc/Kconfig.chipb | 19 +++ .../gen_kconfig_doc/test_target_visibility.py | 111 ++++++++++++++ 17 files changed, 439 insertions(+), 33 deletions(-) rename tools/kconfig_new/test/{ => confserver}/Kconfig (100%) rename tools/kconfig_new/test/{ => confserver}/README.md (100%) rename tools/kconfig_new/test/{ => confserver}/sdkconfig (100%) rename tools/kconfig_new/test/{ => confserver}/test_confserver.py (93%) rename tools/kconfig_new/test/{ => confserver}/testcases_v1.txt (100%) rename tools/kconfig_new/test/{ => confserver}/testcases_v2.txt (100%) create mode 100644 tools/kconfig_new/test/gen_kconfig_doc/Kconfig create mode 100644 tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipa create mode 100644 tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipb create mode 100755 tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 2dc8dac9a..538fbaaf8 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -1,4 +1,5 @@ menu "Bluetooth" + visible if IDF_TARGET_ESP32 config BT_ENABLED bool "Bluetooth" @@ -432,6 +433,7 @@ endmenu menuconfig BLE_MESH bool "ESP BLE Mesh Support" + depends on BT_ENABLED help This option enables ESP BLE Mesh support. The specific features that are available may depend on other features that have been enabled in the diff --git a/components/driver/Kconfig b/components/driver/Kconfig index d30966f3e..32a773a88 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -83,6 +83,7 @@ menu "Driver configurations" endmenu # UART Configuration menu "RTCIO configuration" + visible if IDF_TARGET_ESP32 config RTCIO_SUPPORT_RTC_GPIO_DESC bool "Support array `rtc_gpio_desc` for ESP32" diff --git a/docs/conf_common.py b/docs/conf_common.py index 94dd72e4e..84cf86a3b 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -95,11 +95,6 @@ kconfigs = find_component_files("../../components", "Kconfig") kconfig_projbuilds = find_component_files("../../components", "Kconfig.projbuild") sdkconfig_renames = find_component_files("../../components", "sdkconfig.rename") -# trim the esp32s2 component, until we have proper multi-target support -kconfigs = [k for k in kconfigs if "esp32s2" not in k] -kconfig_projbuilds = [k for k in kconfig_projbuilds if "esp32s2" not in k] -sdkconfig_renames = [r for r in sdkconfig_renames if "esp32s2" not in r] - kconfigs_source_path = '{}/inc/kconfigs_source.in'.format(builddir) kconfig_projbuilds_source_path = '{}/inc/kconfig_projbuilds_source.in'.format(builddir) @@ -123,6 +118,7 @@ confgen_args = [sys.executable, "--env", "COMPONENT_KCONFIGS_SOURCE_FILE={}".format(kconfigs_source_path), "--env", "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE={}".format(kconfig_projbuilds_source_path), "--env", "IDF_PATH={}".format(idf_path), + "--env", "IDF_TARGET={}".format(os.environ.get('IDF_TARGET', 'esp32')), "--output", "docs", kconfig_inc_path + '.in' ] subprocess.check_call(confgen_args) diff --git a/tools/ci/config/host-test.yml b/tools/ci/config/host-test.yml index b56cf2332..928018b89 100644 --- a/tools/ci/config/host-test.yml +++ b/tools/ci/config/host-test.yml @@ -160,9 +160,15 @@ test_multi_heap_on_host: test_confserver: extends: .host_test_template script: - - cd tools/kconfig_new/test + - cd tools/kconfig_new/test/confserver - ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_confserver.py +test_gen_kconfig_doc: + extends: .host_test_template + script: + - cd tools/kconfig_new/test/gen_kconfig_doc/ + - ${IDF_PATH}/tools/ci/multirun_with_pyenv.sh ./test_target_visibility.py + test_idf_monitor: extends: .host_test_template artifacts: diff --git a/tools/ci/executable-list.txt b/tools/ci/executable-list.txt index 3d617d6bf..391d13eec 100644 --- a/tools/ci/executable-list.txt +++ b/tools/ci/executable-list.txt @@ -75,7 +75,8 @@ tools/kconfig/merge_config.sh tools/kconfig/streamline_config.pl tools/kconfig_new/confgen.py tools/kconfig_new/confserver.py -tools/kconfig_new/test/test_confserver.py +tools/kconfig_new/test/confserver/test_confserver.py +tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py tools/ldgen/ldgen.py tools/ldgen/test/test_fragments.py tools/ldgen/test/test_generation.py diff --git a/tools/kconfig_new/confgen.py b/tools/kconfig_new/confgen.py index 5d4b5041e..fd1f6a0df 100755 --- a/tools/kconfig_new/confgen.py +++ b/tools/kconfig_new/confgen.py @@ -7,7 +7,7 @@ # Used internally by the ESP-IDF build system. But designed to be # non-IDF-specific. # -# Copyright 2018 Espressif Systems (Shanghai) PTE LTD +# Copyright 2018-2020 Espressif Systems (Shanghai) PTE LTD # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -112,10 +112,10 @@ class DeprecatedOptions(object): print('{}:{} {} was replaced with {}'.format(sdkconfig_in, line_num, depr_opt, new_opt)) f_out.write(line) - def append_doc(self, config, path_output): + def append_doc(self, config, visibility, path_output): def option_was_written(opt): - return any(gen_kconfig_doc.node_should_write(node) for node in config.syms[opt].nodes) + return any(visibility.visible(node) for node in config.syms[opt].nodes) if len(self.r_dic) > 0: with open(path_output, 'a') as f_o: @@ -572,8 +572,15 @@ def write_json_menus(deprecated_options, config, filename): def write_docs(deprecated_options, config, filename): - gen_kconfig_doc.write_docs(config, filename) - deprecated_options.append_doc(config, filename) + try: + target = os.environ['IDF_TARGET'] + except KeyError: + print('IDF_TARGET environment variable must be defined!') + sys.exit(1) + + visibility = gen_kconfig_doc.ConfigTargetVisibility(config, target) + gen_kconfig_doc.write_docs(config, visibility, filename) + deprecated_options.append_doc(config, visibility, filename) def update_if_changed(source, destination): diff --git a/tools/kconfig_new/gen_kconfig_doc.py b/tools/kconfig_new/gen_kconfig_doc.py index f8d9687ee..9b614794c 100644 --- a/tools/kconfig_new/gen_kconfig_doc.py +++ b/tools/kconfig_new/gen_kconfig_doc.py @@ -7,7 +7,7 @@ # generated, allowing options to be referenced in other documents # (using :ref:`CONFIG_FOO`) # -# Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD +# Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -42,13 +42,126 @@ INITIAL_HEADING_LEVEL = 3 MAX_HEADING_LEVEL = len(HEADING_SYMBOLS) - 1 -def write_docs(config, filename): +class ConfigTargetVisibility(object): + """ + Determine the visibility of Kconfig options based on IDF targets. Note that other environment variables should not + imply invisibility and neither dependencies on visible options with default disabled state. This difference makes + it necessary to implement our own visibility and cannot use the visibility defined inside Kconfiglib. + """ + def __init__(self, config, target): + # target actually is not necessary here because kconfiglib.expr_value() will evaluate it internally + self.config = config + self.visibility = dict() # node name to (x, y) mapping where x is the visibility (True/False) and y is the + # name of the config which implies the visibility + self.target_env_var = 'IDF_TARGET' + self.direct_eval_set = frozenset([kconfiglib.EQUAL, kconfiglib.UNEQUAL, kconfiglib.LESS, kconfiglib.LESS_EQUAL, + kconfiglib.GREATER, kconfiglib.GREATER_EQUAL]) + + def _implies_invisibility(self, item): + if isinstance(item, tuple): + if item[0] == kconfiglib.NOT: + (invisibility, source) = self._implies_invisibility(item[1]) + if source is not None and source.startswith(self.target_env_var): + return (not invisibility, source) + else: + # we want to be visible all configs which are not dependent on target variables, + # e.g. "depends on XY" and "depends on !XY" as well + return (False, None) + elif item[0] == kconfiglib.AND: + (invisibility, source) = self._implies_invisibility(item[1]) + if invisibility: + return (True, source) + (invisibility, source) = self._implies_invisibility(item[2]) + if invisibility: + return (True, source) + return (False, None) + elif item[0] == kconfiglib.OR: + implication_list = [self._implies_invisibility(item[1]), self._implies_invisibility(item[2])] + if all([implies for (implies, _) in implication_list]): + source_list = [s for (_, s) in implication_list if s.startswith(self.target_env_var)] + if len(set(source_list)) != 1: # set removes the duplicates + print('[WARNING] list contains targets: {}'.format(source_list)) + return (True, source_list[0]) + return (False, None) + elif item[0] in self.direct_eval_set: + def node_is_invisible(item): + return all([node.prompt is None for node in item.nodes]) + if node_is_invisible(item[1]) or node_is_invisible(item[1]): + # it makes no sense to call self._implies_invisibility() here because it won't generate any useful + # "source" + return (not kconfiglib.expr_value(item), None) + else: + # expressions with visible configs can be changed to make the item visible + return (False, None) + else: + raise RuntimeError('Unimplemented operation in {}'.format(item)) + else: # Symbol or Choice + vis_list = [self._visible(node) for node in item.nodes] + if len(vis_list) > 0 and all([not visible for (visible, _) in vis_list]): + source_list = [s for (_, s) in vis_list if s is not None and s.startswith(self.target_env_var)] + if len(set(source_list)) != 1: # set removes the duplicates + print('[WARNING] list contains targets: {}'.format(source_list)) + return (True, source_list[0]) + + if item.name.startswith(self.target_env_var): + return (not kconfiglib.expr_value(item), item.name) + + if len(vis_list) == 1: + (visible, source) = vis_list[0] + if visible: + return (False, item.name) # item.name is important here in case the result will be inverted: if + # the dependency is on another config then it can be still visible + + return (False, None) + + def _visible(self, node): + if isinstance(node.item, kconfiglib.Symbol) or isinstance(node.item, kconfiglib.Choice): + dependencies = node.item.direct_dep # "depends on" for configs + name_id = node.item.name + simple_def = len(node.item.nodes) <= 1 # defined only in one source file + # Probably it is not necessary to check the default statements. + else: + dependencies = node.visibility # "visible if" for menu + name_id = node.prompt[0] + simple_def = False # menus can be defined with the same name at multiple locations and they don't know + # about each other like configs through node.item.nodes. Therefore, they cannot be stored and have to be + # re-evaluated always. + + try: + (visib, source) = self.visibility[name_id] + except KeyError: + def invert_first_arg(_tuple): + return (not _tuple[0], _tuple[1]) + + (visib, source) = self._visible(node.parent) if node.parent else (True, None) + + if visib: + (visib, source) = invert_first_arg(self._implies_invisibility(dependencies)) + + if simple_def: + # Configs defined at multiple places are not stored because they could have different visibility based + # on different targets. kconfiglib.expr_value() will handle the visibility. + self.visibility[name_id] = (visib, source) + + return (visib, source) # not used in "finally" block because failure messages from _implies_invisibility are + # this way more understandable + + def visible(self, node): + if not node.prompt: + # don't store this in self.visibility because don't want to stop at invisible nodes when recursively + # searching for invisible targets + return False + + return self._visible(node)[0] + + +def write_docs(config, visibility, filename): """ Note: writing .rst documentation ignores the current value of any items. ie the --config option can be ignored. (However at time of writing it still needs to be set to something...) """ with open(filename, "w") as f: for node in config.node_iter(): - write_menu_item(f, node) + write_menu_item(f, node, visibility) def node_is_menu(node): @@ -108,18 +221,12 @@ def format_rest_text(text, indent): return text -def node_should_write(node): - if not node.prompt: - return False # Don't do anything for invisible menu items +def write_menu_item(f, node, visibility): + def is_choice(node): + """ Skip choice nodes, they are handled as part of the parent (see below) """ + return isinstance(node.parent.item, kconfiglib.Choice) - if isinstance(node.parent.item, kconfiglib.Choice): - return False # Skip choice nodes, they are handled as part of the parent (see below) - - return True - - -def write_menu_item(f, node): - if not node_should_write(node): + if is_choice(node) or not visibility.visible(node): return try: @@ -175,7 +282,7 @@ def write_menu_item(f, node): child = node.list while child: try: - if node_should_write(child): + if not is_choice(child) and child.prompt and visibility.visible(child): if first: f.write("Contains:\n\n") first = False diff --git a/tools/kconfig_new/test/Kconfig b/tools/kconfig_new/test/confserver/Kconfig similarity index 100% rename from tools/kconfig_new/test/Kconfig rename to tools/kconfig_new/test/confserver/Kconfig diff --git a/tools/kconfig_new/test/README.md b/tools/kconfig_new/test/confserver/README.md similarity index 100% rename from tools/kconfig_new/test/README.md rename to tools/kconfig_new/test/confserver/README.md diff --git a/tools/kconfig_new/test/sdkconfig b/tools/kconfig_new/test/confserver/sdkconfig similarity index 100% rename from tools/kconfig_new/test/sdkconfig rename to tools/kconfig_new/test/confserver/sdkconfig diff --git a/tools/kconfig_new/test/test_confserver.py b/tools/kconfig_new/test/confserver/test_confserver.py similarity index 93% rename from tools/kconfig_new/test/test_confserver.py rename to tools/kconfig_new/test/confserver/test_confserver.py index e7da1f8c8..990da010f 100755 --- a/tools/kconfig_new/test/test_confserver.py +++ b/tools/kconfig_new/test/confserver/test_confserver.py @@ -56,12 +56,12 @@ def main(): with tempfile.NamedTemporaryFile(delete=False) as f: temp_kconfig_projbuilds_source_file = os.path.join(tempfile.gettempdir(), f.name) - cmdline = '''../confserver.py --env "COMPONENT_KCONFIGS_SOURCE_FILE=%s" \ - --env "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE=%s" \ - --env "COMPONENT_KCONFIGS=" \ - --env "COMPONENT_KCONFIGS_PROJBUILD=" \ - --kconfig Kconfig \ - --config %s \ + cmdline = '''../../confserver.py --env "COMPONENT_KCONFIGS_SOURCE_FILE=%s" \ + --env "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE=%s" \ + --env "COMPONENT_KCONFIGS=" \ + --env "COMPONENT_KCONFIGS_PROJBUILD=" \ + --kconfig Kconfig \ + --config %s \ ''' % (temp_kconfigs_source_file, temp_kconfig_projbuilds_source_file, temp_sdkconfig_path) cmdline = re.sub(r' +', ' ', cmdline) diff --git a/tools/kconfig_new/test/testcases_v1.txt b/tools/kconfig_new/test/confserver/testcases_v1.txt similarity index 100% rename from tools/kconfig_new/test/testcases_v1.txt rename to tools/kconfig_new/test/confserver/testcases_v1.txt diff --git a/tools/kconfig_new/test/testcases_v2.txt b/tools/kconfig_new/test/confserver/testcases_v2.txt similarity index 100% rename from tools/kconfig_new/test/testcases_v2.txt rename to tools/kconfig_new/test/confserver/testcases_v2.txt diff --git a/tools/kconfig_new/test/gen_kconfig_doc/Kconfig b/tools/kconfig_new/test/gen_kconfig_doc/Kconfig new file mode 100644 index 000000000..4d67dde1e --- /dev/null +++ b/tools/kconfig_new/test/gen_kconfig_doc/Kconfig @@ -0,0 +1,137 @@ +config IDF_TARGET + string + default "$IDF_TARGET" + +config IDF_TARGET_CHIPA + bool + default "y" if IDF_TARGET="chipa" + +config IDF_TARGET_CHIPB + bool + default "y" if IDF_TARGET="chipb" + +config ALWAYS_VISIBLE + bool "Always visible option" + +choice ALWAYS_VISIBLE_CHOICE + prompt "Always visible choice" + default ALWAYS_VISIBLE_CHOICE_OP1 + + config ALWAYS_VISIBLE_CHOICE_OP1 + bool "op1" + + config ALWAYS_VISIBLE_CHOICE_OP2 + bool "op2" +endchoice + +config CONFIG_FOR_CHIPA + bool "Config for chip A" + depends on IDF_TARGET_CHIPA + default n + +config CONFIG_FOR_CHIPB + bool "Config for chip B" + depends on IDF_TARGET_CHIPB + +choice CHOICE_FOR_CHIPA + prompt "Always visible choice" + default CHOICE_FOR_CHIPA_OP1 + depends on IDF_TARGET_CHIPA + + config CHOICE_FOR_CHIPA_OP1 + bool "op1" + + config CHOICE_FOR_CHIPA_OP2 + bool "op2" +endchoice + +choice CHOICE_FOR_CHIPB + prompt "Always visible choice" + default CHOICE_FOR_CHIPB_OP1 + depends on IDF_TARGET_CHIPB + + config CHOICE_FOR_CHIPB_OP1 + bool "op1" + + config CHOICE_FOR_CHIPB_OP2 + bool "op2" +endchoice + +source "Kconfig.chipa" +source "Kconfig.chipb" + +config DEEP_DEPENDENT_CONFIG + bool "Config depends on another config with default no value" + depends on CONFIG_FOR_CHIPA + +config DEEP_DEPENDENT_CONFIG_INV + bool "Config depends on the inverted value of another config" + depends on !CONFIG_FOR_CHIPA + +choice DEEP_DEPENDENT_CHOICE + prompt "depends on target-specific config" + default DEEP_DEPENDENT_CHOICE_OP1 + depends on DEEP_DEPENDENT_CONFIG + + config DEEP_DEPENDENT_CHOICE_OP1 + bool "op1" + + config DEEP_DEPENDENT_CHOICE_OP2 + bool "op2" +endchoice + +config INVISIBLE1 + bool "depends on cannot be satified at the same time" + depends on CONFIG_FOR_CHIPA && IDF_TARGET_CHIPB + +config VISIBLE1 + bool "makes no sense, just for testing OR dependencies" + depends on CONFIG_FOR_CHIPA || IDF_TARGET_CHIPB + +config CONFIG_FOR_CHIPA_DEPENDS_VAR1 + bool "redundant AND in depends on" + depends on CONFIG_FOR_CHIPA && IDF_TARGET_CHIPA + +config CONFIG_FOR_CHIPA_DEPENDS_VAR2 + bool "test AND + NOT" + depends on CONFIG_FOR_CHIPA && !IDF_TARGET_CHIPB + +config CONFIG_FOR_CHIPA_DEPENDS_VAR3 + bool "test NOT" + depends on !IDF_TARGET_CHIPB + +config CONFIG_DEPENDS_ENV_VAR1 + bool "test other environment variable (should be visible because only IDF_TARGET should make something invisible)" + depends on IDF_XYZ + +config CONFIG_DEPENDS_ENV_VAR2 + bool "test other environment variable (should be visible because only IDF_TARGET should make something invisible)" + depends on !IDF_XYZ + +choice CHIPA_VERSION + prompt "CHIPA version" + default CHIPA_VERSION2 + depends on CONFIG_FOR_CHIPA + + config CHIPA_VERSION1 + bool "Version 1" + config CHIPA_VERSION2 + bool "Version 2" + config CHIPA_VERSION3 + bool "Version 3" +endchoice + +config CHIPA_REV_MIN + int + default 1 if CHIPA_VERSION1 + default 2 if CHIPA_VERSION2 + default 3 if CHIPA_VERSION3 + +config CHIPA_FEATURE_FROM_V1 + depends on CONFIG_FOR_CHIPA && (CHIPA_REV_MIN <= 1) + bool "Feature available from version 1" + +config CHIPA_FEATURE_FROM_V3 + depends on CONFIG_FOR_CHIPA && (CHIPA_REV_MIN <= 3) + bool "Feature available from version 3" + diff --git a/tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipa b/tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipa new file mode 100644 index 000000000..1f6309c0f --- /dev/null +++ b/tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipa @@ -0,0 +1,19 @@ +menu "Menu for CHIPA" + visible if IDF_TARGET_CHIPA + + config EXT_CONFIG1_FOR_CHIPA_MENU + bool "Config for chip A" + depends on IDF_TARGET_CHIPA + + config EXT_CONFIG2_FOR_CHIPA_MENU + bool "Config for chip A (depend on the visibility of the menu)" + +endmenu + +config EXT_CONFIG3_FOR_CHIPA + bool "Config for chip A" + depends on IDF_TARGET_CHIPA + +config EXT_CONFIG4 + bool "Config for every chip (note that the config is defined at multiple places)" + depends on IDF_TARGET_CHIPA diff --git a/tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipb b/tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipb new file mode 100644 index 000000000..6dcaa0868 --- /dev/null +++ b/tools/kconfig_new/test/gen_kconfig_doc/Kconfig.chipb @@ -0,0 +1,19 @@ +menu "Menu for CHIPB" + visible if IDF_TARGET_CHIPB + + config EXT_CONFIG1_FOR_CHIPB_MENU + bool "Config for chip B" + depends on IDF_TARGET_CHIPB + + config EXT_CONFIG2_FOR_CHIPB_MENU + bool "Config for chip B (depend on the visibility of the menu)" + +endmenu + +config EXT_CONFIG3_FOR_CHIPB + bool "Config for chip B" + depends on IDF_TARGET_CHIPB + +config EXT_CONFIG4 + bool "Config for every chip (note that the config is defined at multiple places)" + depends on IDF_TARGET_CHIPB diff --git a/tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py b/tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py new file mode 100755 index 000000000..a4ded609f --- /dev/null +++ b/tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python +import os +import sys +import unittest + +try: + from . import kconfiglib +except Exception: + sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../..'))) + import kconfiglib +import gen_kconfig_doc + + +class ConfigTargetVisibilityTestCase(unittest.TestCase): + def setUp(self): + self.target = os.environ['IDF_TARGET'] + self.config = kconfiglib.Kconfig('Kconfig') + self.v = gen_kconfig_doc.ConfigTargetVisibility(self.config, self.target) + + def _get_config(self, name): + sym = self.config.syms.get(name) + if sym: + return sym.nodes[0] + choice = self.config.named_choices.get(name) + if choice: + return choice.nodes[0] + raise RuntimeError('Unimplemented {}'.format(name)) + + def visible(self, config_name): + self.assertTrue(self.v.visible(self._get_config(config_name))) + + def invisible(self, config_name): + self.assertFalse(self.v.visible(self._get_config(config_name))) + + +class ConfigTargetVisibilityChipA(ConfigTargetVisibilityTestCase): + @classmethod + def setUpClass(cls): + os.environ['IDF_TARGET'] = 'chipa' + + def test_config_visibility(self): + self.invisible('IDF_TARGET') + self.invisible('IDF_TARGET_CHIPA') + self.visible('ALWAYS_VISIBLE') + self.visible('ALWAYS_VISIBLE_CHOICE') + self.visible('CONFIG_FOR_CHIPA') + self.invisible('CONFIG_FOR_CHIPB') + self.visible('CHOICE_FOR_CHIPA') + self.invisible('CHOICE_FOR_CHIPB') + self.visible('EXT_CONFIG1_FOR_CHIPA_MENU') + self.visible('EXT_CONFIG2_FOR_CHIPA_MENU') + self.visible('EXT_CONFIG3_FOR_CHIPA') + self.invisible('EXT_CONFIG1_FOR_CHIPB_MENU') + self.invisible('EXT_CONFIG2_FOR_CHIPB_MENU') + self.invisible('EXT_CONFIG3_FOR_CHIPB') + self.visible('EXT_CONFIG4') + self.visible('DEEP_DEPENDENT_CONFIG') + self.visible('DEEP_DEPENDENT_CONFIG_INV') + self.visible('DEEP_DEPENDENT_CHOICE') + self.invisible('INVISIBLE1') + self.visible('VISIBLE1') + self.visible('CONFIG_FOR_CHIPA_DEPENDS_VAR1') + self.visible('CONFIG_FOR_CHIPA_DEPENDS_VAR2') + self.visible('CONFIG_FOR_CHIPA_DEPENDS_VAR3') + self.visible('CONFIG_DEPENDS_ENV_VAR1') + self.visible('CONFIG_DEPENDS_ENV_VAR2') + self.visible('CHIPA_VERSION') + self.invisible('CHIPA_REV_MIN') + self.visible('CHIPA_FEATURE_FROM_V1') + self.visible('CHIPA_FEATURE_FROM_V3') + + +class ConfigTargetVisibilityChipB(ConfigTargetVisibilityTestCase): + @classmethod + def setUpClass(cls): + os.environ['IDF_TARGET'] = 'chipb' + + def test_config_visibility(self): + self.invisible('IDF_TARGET') + self.invisible('IDF_TARGET_CHIPA') + self.visible('ALWAYS_VISIBLE') + self.visible('ALWAYS_VISIBLE_CHOICE') + self.invisible('CONFIG_FOR_CHIPA') + self.visible('CONFIG_FOR_CHIPB') + self.invisible('CHOICE_FOR_CHIPA') + self.visible('CHOICE_FOR_CHIPB') + self.invisible('EXT_CONFIG1_FOR_CHIPA_MENU') + self.invisible('EXT_CONFIG2_FOR_CHIPA_MENU') + self.invisible('EXT_CONFIG3_FOR_CHIPA') + self.visible('EXT_CONFIG1_FOR_CHIPB_MENU') + self.visible('EXT_CONFIG2_FOR_CHIPB_MENU') + self.visible('EXT_CONFIG3_FOR_CHIPB') + self.visible('EXT_CONFIG4') + self.invisible('DEEP_DEPENDENT_CONFIG') + self.visible('DEEP_DEPENDENT_CONFIG_INV') + self.invisible('DEEP_DEPENDENT_CHOICE') + self.invisible('INVISIBLE1') + self.visible('VISIBLE1') + self.invisible('CONFIG_FOR_CHIPA_DEPENDS_VAR1') + self.invisible('CONFIG_FOR_CHIPA_DEPENDS_VAR2') + self.invisible('CONFIG_FOR_CHIPA_DEPENDS_VAR3') + self.visible('CONFIG_DEPENDS_ENV_VAR1') + self.visible('CONFIG_DEPENDS_ENV_VAR2') + self.invisible('CHIPA_VERSION') + self.invisible('CHIPA_REV_MIN') + self.invisible('CHIPA_FEATURE_FROM_V1') + self.invisible('CHIPA_FEATURE_FROM_V3') + + +if __name__ == "__main__": + unittest.main()