Skip to content

Feature: Track source file for each config option in ProjectConfig #5384

@m-mcgowan

Description

@m-mcgowan

Feature: Track source file for each config option in ProjectConfig

Problem

When platformio.ini uses extra_configs to include additional .ini files, ProjectConfig merges all values into a flat dict via Python's configparser. After merging, there's no way to determine which file a particular config value came from.

This makes it difficult to:

  • Debug config issues: "Where is this lib_deps entry defined?" requires manually searching all included files
  • Build tooling: Tools that need to modify a config value (e.g. updating a library version) must independently re-parse every config file to find where the value is declared
  • Provide helpful diagnostics: pio project config could show the source file for each option, especially useful when values are overridden by later files

Proposed Solution

Add source file tracking to ProjectConfig so each option records which file it was loaded from.

API suggestion:

config = ProjectConfig.get_instance("platformio.ini")

# Existing — returns merged value
config.get("env:esp32", "lib_deps")
# => ["blues/Notecard @ ^1.8.3", "acme/Foo @ ^2.0"]

# New — returns the file path where the option was defined
config.get_source("env:esp32", "lib_deps")
# => "/path/to/shared/libs.ini"

For multi-value options like lib_deps where entries may come from different files (base [env] section vs env-specific), a per-entry variant would be even more useful:

config.get_sources("env:esp32", "lib_deps")
# => {
#   "blues/Notecard @ ^1.8.3": "/path/to/shared/libs.ini",
#   "acme/Foo @ ^2.0": "/path/to/platformio.ini",
# }

Implementation Notes

Python's configparser.ConfigParser doesn't track source files natively. One approach:

  • Override read() / read_file() to tag each option with its source path before merging
  • Store metadata in a parallel dict: {(section, option): filepath}
  • For list-valued options, track per-entry sources

The _parsed attribute already records which files were read (in order), so the infrastructure for tracking is partially there.

Use Cases

  1. pio project config --verbose — show where each value comes from, like git config --show-origin
  2. Dependency management tools — update version specs in the correct file when using extra_configs
  3. CI debugging — understand why a config value differs between environments when configs are split across files

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions