From ed0b12dcf97accc7672892ae78888c290ee6ea9c Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 12 May 2022 13:24:27 +0300 Subject: [PATCH] Improve project config parser to resolve renamed options // Issue #4259 --- docs | 2 +- examples | 2 +- platformio/project/config.py | 42 ++++++++++++++++++++++++++++++------ tests/project/test_config.py | 3 +++ 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/docs b/docs index a997e10d..1759320c 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit a997e10df9e5082d8a312bfc9113d363facf4b19 +Subproject commit 1759320cdc52a814a1a81af6e1aeb724bbb52799 diff --git a/examples b/examples index 042c58bb..c328c386 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit 042c58bb71fac5245e316231a7ecd2e5b8c665da +Subproject commit c328c386fe8427b31562196cd3a989b08df03e05 diff --git a/platformio/project/config.py b/platformio/project/config.py index 863c3271..8633589c 100644 --- a/platformio/project/config.py +++ b/platformio/project/config.py @@ -132,7 +132,7 @@ class ProjectConfigBase(object): renamed_options.update({name: option.name for name in option.oldnames}) for section in self._parser.sections(): - scope = section.split(":", 1)[0] + scope = self.get_section_scope(section) if scope not in ("platformio", "env"): continue for option in self._parser.options(section): @@ -164,6 +164,10 @@ class ProjectConfigBase(object): ) return True + @staticmethod + def get_section_scope(section): + return section.split(":", 1)[0] if ":" in section else section + def walk_options(self, root_section): extends_queue = ( ["env", root_section] if root_section.startswith("env:") else [root_section] @@ -195,7 +199,7 @@ class ProjectConfigBase(object): result.append(option) # handle system environment variables - scope = section.split(":", 1)[0] + scope = self.get_section_scope(section) for option_meta in ProjectOptions.values(): if option_meta.scope != scope or option_meta.name in result: continue @@ -233,9 +237,29 @@ class ProjectConfigBase(object): value = "\n" + value self._parser.set(section, option, value) - def getraw( # pylint: disable=too-many-branches - self, section, option, default=MISSING - ): + def getraw(self, section, option, default=MISSING): + try: + return self._getraw(section, option, default) + except configparser.NoOptionError as exc: + renamed_option = self._resolve_renamed_option(section, option) + if renamed_option: + return self._getraw(section, renamed_option, default) + raise exc + + def _resolve_renamed_option(self, section, old_name): + scope = self.get_section_scope(section) + if scope not in ("platformio", "env"): + return None + for option_meta in ProjectOptions.values(): + if ( + option_meta.oldnames + and option_meta.scope == scope + and old_name in option_meta.oldnames + ): + return option_meta.name + return None + + def _getraw(self, section, option, default): # pylint: disable=too-many-branches if not self.expand_interpolations: return self._parser.get(section, option) @@ -245,7 +269,9 @@ class ProjectConfigBase(object): value = self._parser.get(sec, option) break - option_meta = ProjectOptions.get("%s.%s" % (section.split(":", 1)[0], option)) + option_meta = ProjectOptions.get( + "%s.%s" % (self.get_section_scope(section), option) + ) if not option_meta: if value == MISSING: value = ( @@ -316,7 +342,9 @@ class ProjectConfigBase(object): except configparser.Error as e: raise exception.InvalidProjectConfError(self.path, str(e)) - option_meta = ProjectOptions.get("%s.%s" % (section.split(":", 1)[0], option)) + option_meta = ProjectOptions.get( + "%s.%s" % (self.get_section_scope(section), option) + ) if not option_meta: return value diff --git a/tests/project/test_config.py b/tests/project/test_config.py index 38e194b1..669406c1 100644 --- a/tests/project/test_config.py +++ b/tests/project/test_config.py @@ -310,6 +310,9 @@ def test_getraw_value(config): ) assert config.getraw("platformio", "build_dir") == "~/tmp/pio-$PROJECT_HASH" + # renamed option + assert config.getraw("env:base", "debug_load_cmd") == ["load"] + def test_get_value(config): assert config.get("custom", "debug_flags") == "-D DEBUG=1"