-
-
Notifications
You must be signed in to change notification settings - Fork 457
Yaml config enhancements to support variable substitutions, includes and packages #4818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@lolodomo FYI. This shouldn't conflict with anything that you're working on, I think. |
704d716 to
b4f551c
Compare
|
rebased to main |
b4f551c to
60bb8b0
Compare
60bb8b0 to
d04a9a2
Compare
|
Todo: merge lists in packages |
|
@lolodomo When you find time, I would appreciate a short review from your end. |
|
Great Work!
|
No, they only need to be defined in the include directive.
Out of the three options, I prefer
So that you can have
Good question. As it is now, it will return To fix this, I need to make it ungreedy, but it would no longer work for |
|
@spacemanspiff2007 I added a commit that supports quoted defaults (in which you can use braces).
|
|
@jimtng I really like what you did in this PR! This is going to be a great feature which will help a lot and make configuration a breeze.
In python there is a Instead of Would it also be possible to not have to use the packages:
livingroom-light1:
file: esphome-light.inc.yaml
vars:
thingid: livingroom-light1How about we also add a
I understand. I guess it's quite unexpected that |
|
I think
The the package keys not being used bothers me a bit. Perhaps it should just be a list instead of a map, but I went with a map to make it all consistent with the rest of the convention for things, items, tags. Perhaps I can pass an implicit variable
I'll consider it.
I think with the exclusion of *.inc.yaml it should be enough. Adding more subdirectories to exclusion may potentially cause confusion. You can of course structure your folder as ./includes/foo.inc.yaml if you wish.
This is consistent with sh / bash / ruby, e.g.
I thought of this, but it's a can of worm that I'd rather not have to deal with yet. |
I saw it after I sent the message. Both names are fine with me.
For items and things the key is the unique identifier. Since these packages are fully merged configs they have no unique identifier (which would be the path to the file). If you find a good use case for the Will you provide support for the short syntax e.g.
I thought some more and it might make sense to keep the
Yes - I noticed how everything is inspired by esphome. Will a change in a package/included file trigger a reload of the referencing file? |
It would be entirely up to the user to use it how they see fit. For me, I would use the PACKAGE_KEY as the thingid in the example above so there is no need to specify
That is true, although that wasn't the main reason. Using I've just tried implementing what you suggested and it resulted in more complexity and code duplication. This is of course simply an implementation detail invisible to the user.
Not currently, however I did consider this possibility. There are pros and cons to doing this, and I opted not doing this, at least for now. The cons: sometimes I might want to make changes to several templates without having it reloaded, and then I can just trigger one reload of the main yaml file. But perhaps it's fine for it to reload several times too. |
I think
|
I think it's rather common that these have different "rules" when it comes to substitutions, escaping etc. I'm not weighing in on whether it's a good idea here, I'm just saying that generally I think that is acceptable. But, doesn't YAML already have some "rules" regarding quoting to take into account? As far as I know, YAML only allows gives the escape character
That's preferable IMO. When making such "special codes", you might as well make them easy to use.
Don't. It shouldn't become "a mantra" that is more important than reason. People will have to learn to use arrays too, and it's the only thing that makes sense here.
In reality the terms matter less than we think, as soon as something is chosen and its meaning is well-defined and documented, people will quickly "get used to it". If the similarity with the ESPHome format is kept, parity with it might have a value in itself (for users using both systems). |
Your right about the
So this will be supported?
Let's keep the
But imho this would work the same way if you need to do changes now in an items and things file. If I reuse an |
I haven't tried this exact scenario but yes it should work just like you expected. That's essentially how
I think it depends. Besides, most people edit files in-place.
The two files are different. One is an include file, the other is the main file.
Yes, exactly the idea, but I do see the convenience of having it auto reload and on the other hand, it can be annoying for those who like total control that eventually someone would ask for the option to turn it off. I am so used to doing it manually and the way I currently do it is using one big main file, so I only need to reload one file.
It would be an effort yes, and I am currently on vacation with very limited "computer" time until end of June. This will have to be a separate PR later.
It's not merely following a mantra. I actually much prefer to have it as a map. But supporting a list is easy(easier), I'll see what it looks like and try it and if it looks OK, I'll consider supporting both syntaxes perhaps. |
I think the only sensible thing is that the templates "hot reload" too, otherwise you'd have to figure out and chase down which files are affected. I mean, the point of using a template is to avoid duplicating information. If you still have to hunt down the individual files and resave them, you could almost might as well just have copy/pasted. But, I guess that this can be a challenge implementation-wise. You would have to keep track of basically all "YAML model" files, and then trigger reparsing when required. It sounds like a path full of pitfalls. |
|
As I said, it depends on your workflow. I've been using a similar system and workflow in openhab for at least three years and preferred manual reloading. I have an implementation in mind on how to do the auto reload but will also need to add a setting not to do it for those who prefer not having it. I also have in mind how to do this A.global option through service config I'll implement this in a late pr if/when time permits or at the end of June. |
0012f04 to
7743285
Compare
|
Everybody was tired today and returned early, so I had some time to implement the include dependency tracking. Now whenever any include files are changed, the main yaml will be reloaded. |
6ad3002 to
0eecf01
Compare
...yaml/src/main/java/org/openhab/core/model/yaml/internal/util/preprocessor/ModelResolver.java
Show resolved
Hide resolved
|
@jimtng : snakeyaml is not a new dependency, it was an indirect dependency through Jackson YAML, correct ? |
Correct, it's not a new dependency and that's why I haven't added it to pom.xml. I don't know what the considerations were in the beginning. |
Maybe it was not SnakeYaml but another library we decided to not use. I do not remember exactly. |
…and packages Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
…ue resolution Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
They are merged in the IncludeObject expansion. Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
88413bb to
6ea8086
Compare
Changes in this PR:
*.inc.yamland*.inc.ymlfrom being processed by the YamlModelRepositoryImpl. These are meant to be used as files!included as packages.The output of the preprocessor is the same YAML structure and elements that are currently supported without the addition of this PR.
Current flow:
New flow:
Additional "pseudo elements" which, after being processed, are removed in the generated data output:
variablespackagesExample:
main.yaml:
mqtt_template.inc.yaml
in this file it starts from the top level (zero indentation), but it gets inserted into whatever level
!includewas invoked, so it can be as simple as!includeing a plain string, or a full on yaml structure.esphome-light.inc.yaml
Variables
Supported syntax (subject to change):
${var}returns the var, or a blank string if var is not defined${var-default_value}- returnsdefault_valueonly if var is undefined${var:-default_value}- returnsdefault_valueif var is undefined, or blank${var-${nested}}- nested vars are supported up to 10 levels deepThe default_value can optionally be enclosed in single or double quotes. The quotes are necessary when the default value contains a closing brace
}, e.g.${var:-'{foo: bar}'}. The resulting value does not include the enclosing quotes.Single quoted strings won't be interpolated, e.g.
Note that default values within single quotes are still subject to interpolation, e.g.
Invalid syntax won't be interpolated, simply because the regex pattern won't match
$varsyntax is not supported. The braces are mandatory, because I'm worried it might interfere with things like jsonpath patterns.Escaping is current not supported:
Plain text \${not_interpolated_because_its_escaped}.Variable Scope / Precedence
!include { vars: { xxxx: } }overrides both global and local variables.This is designed so that you can "include" a file and override its defaults / values and adjust it as needed.
Special Variables
__FILE__full absolute path of the current file, e.g./path/to/file.inc.yaml__FILE_NAME__only the filename portion without the extension or leading path, e.g.file.inc__FILE_EXT__only the extension portion, e.g.yaml__DIRECTORY__only the directory portion of the current file, e.g./path/to__DIR__alias for__DIRECTORY__They can be accessed using the same variable syntax, i.e.
${__FILE_NAME__}Including Other Files
Two syntaxes are supported for including other files as the "value" of a key
keyname: !include <filename>Changes made to the included files will trigger an automatic reload of the main yaml file.
Variable interpolation is done on the full syntax, e.g.
Include variable precedence
The variables defined in the
varskey for the!includestatement takes the highest priority over the toplevel variables.main.yaml
subfile.inc.yaml
Packages
A Package file looks just like the main file except
version:andreadOnly:keys aren't needed and shouldn't be in it.It can contain any number of valid elements (things, items, tags, and anything else that may be be implemented in the future).
Packages are simply merged into the main file into their corresponding top-level elements.
Package combined with variable substitutions allow the use of one package file into many actual instances because the variable substitutions make each inclusion to have unique IDs.
A package file can contain the full definition of a "device", which includes Things and Items related for that device. This can be "instantiated" by providing the package with specific device ID (thing id, item names) using include vars.