In my pio_extra_script.py I retrieve the value(s) like this:
values = env.GetProjectOption('custom_foo')
The result is a multiline str → not list[str], with values of the config, split by a new line character.
So I do it manually:
values = [
value
for value
in env.GetProjectOption('custom_foo', default='').split('\n')
if value != ''
]
BUT, interestingly, if I take a built–in config value, like GetProjectOption('build_src_flags'), it is already a list[str], and I don’t need to convert it manually.
So, the question is: can I somehow mark my custom_foo config option to automatically be a list[str], just like the build_src_flags is?
Or, in other words: why is GetProjectOption(build_src_flags) a list[str] automatically, while my custom options are not? I guess it is processed somewhere on the way?
You can try to mock ProjectOption in PRE script and declare a custom project option. In this case, it can start with anything that you want (no need to use the prefix custom.
Please note that I didn’t test this. Please share here your feedback.
import click
from debug import var_dump
from platformio.project.config import ProjectOptions
from platformio.project.options import ConfigEnvOption
from typing import Callable
Import('env')
def list_available_packages() -> list[str]:
return [
package.metadata.name
for package
in env.PioPlatform().get_installed_packages()
]
def add_custom_config_option(
name: str,
description: str,
type: Callable = str,
multiple: bool = False,
default=None,
validate: Callable = None,
) -> None:
option = ConfigEnvOption(
group='custom',
name=name,
description=description,
type=type,
multiple=multiple,
default=default,
validate=validate,
)
ProjectOptions['%s.%s' % (option.scope, option.name)] = option
add_custom_config_option(
name='custom_system_packages',
description=(
'Adds `-isystem` flag for the specified packages. '
'As the result, warnings for those packages will be silenced.'
),
multiple=True,
type=click.Choice(list_available_packages()),
)
var_dump(env.GetProjectOption('custom_system_packages'))
it actually works within a post:extra_script.py.
I’m not sure if Callable is the proper typehint in type: Callable = str and validate: Callable = None in add_custom_config_option()
group='custom' in for ConfigEnvOption is a guess
description for ConfigEnvOption is useless? i’ve tried grep for it, but haven’t found any usage [?]
BTW, I believe multiple should be handled before validate and validate should be called process or processor → as it does not do any validation, but it is being used to change dir paths
And if the multiple key has no more meaning than to call a special callback that converts the value, then you can get rid of it for just reusing the current validate key:
def convert_to_multiple(self, value):
return self.parse_multi_values(value or [])
[…]
ConfigEnvOption(
group="platform",
name="framework",
description="A list of project dependent frameworks",
validate=convert_to_multiple,
buildenvvar="PIOFRAMEWORK",
)
validate=convert_to_multiple is instead of multiple=True. And now you can see how validate is actually more like convert / cast / process