magynhard/yaml_extend

Emulating nested settings

Closed this issue · 15 comments

Hi,

I was trying to use your gem in the following fashion -

nested_config.yml

options:
  extends: 'child_config.yml'

child_config.yml

blah: 'blah'

I want to be able to access the config like so config.options.blah rather than config.blah because I put the extends underneath the options key. Maybe I am doing something wrong? How do I achieve this?

Also, can you add multiple extends in a file?

By default you have to write the keyword for extending (by default: extends) on top level.

You can overwrite the default key by the second parameter, but only a string for top level.

YAML.ext_load_file(yaml_path, inheritance_key='extends', extend_existing_arrays=true, config = {})

I will take your example as feature request and will check if implementing support for nested configurations makes sense. A solution might look like a parameter of format 'options.extends' or ['options']['extends'].

Yes, you can extend by multiple files by defining a list instead a string:

extends:
  - 'super_config.yml'
  - 'another_super_config.yml'

Great, I look forward to the feature!

Thanks for the quick response.

You are welcome!

I just created the new release 0.1.0 with the asked feature.

You now can specify nested inheritance keys, for your example you have to write:

YAML.ext_load_file('nested_config.yml',['options','extends'])

Please report to me, if it works as you expected.

Great, thank you!

I have one comment though.

Can the process of loading it be automatic rather than having to specify additional parameters to ext_load_file? Because I plan to use these to eliminate a lot of duplication inside config files.

Otherwise it'll become really painful having to specify each key that is extended when loading each config file. There are hundreds of config files and the names of the keys that will be extended will be different.

Thank you for your feedback.

That means you think on something like a global configuration where you once can set the custom key, something like

YAML.ext_load_key = 'my_key'

Can you otherwise give me an example?

Here's an example -

settings_group_1:
  settings_sub_group_1: `extends settings_sub_group_1.yml

In another file, it might be something like

settings_group_2:
  settings_sub_group_2: `extends settings_sub_group_2.yml

Does that make sense? There won't be a single custom key but multiple custom keys (all of which will be a pain to manually specify).

Thank you for your feedback.

I'm not exactly sure, how your example looks like in a real situation.
It looks like, if your problem can already be solved with the available functionality.

But to ensure this, or if there may be a real need for solving your problem in another way:
Could you provide a more detailed real world example with pseudo data, including all the files? (including the resulting file!)

Sorry about the delayed reply, been held up by other things.

I'll try to describe an example in our project.

We have lots of build configs in our project for various compilers (gcc, clang etc.) and each one of these configurations have warning options, compile options etc. These are duplicated in every single config and we have to modify each config any time we change one of the options. This is rather annoying.

This is what it looks like -

---------
compiler:
  compile_options:
    - option_1
    - option_2
    ...
  warning_options:
    - option_1
    - option_2
    ...

What I want to do is something like below for every single build config.

---------
compiler:
  defines: `extends compiler_defines.yml`
  compile_options: `extends compile_options.yml`
  warning_options: `extends warning_options.yml`
linker:
  link_options: `extends link_options.yml`

I hope that makes more sense now? Let me know if you want me to clarify anything.

No Problem, same here: got ill, but feel better now. ;)

If I understand your problem correctly, you can already solve your problem this way:

# compile_options.yml
---------
compiler:
  compile_options:
    - option_1
    - option_2
# warning_options.yml
---------
compiler:
  warning_options:
    - option_1
    - option_2
# compiler_defines.yml
---------
compiler:
  defines:
    - define_1
    - define_2

And extend them in the final or pre-final configuration file:

# compiler.yml
---------
extends:
  - 'compile_options.yml'
  - 'warning_options.yml'
  - 'compiler_defines.yml'
compiler:
  compile_options:
    - option_3
  another_option:
    - option_1
some_global_option: true

This will result in the following configuration:

---------
compiler:
  compile_options:
    - option_1
    - option_2
    - option_3
  warning_options:
    - option_1
    - option_2
  defines:
    - define_1
    - define_2
  another_option:
    - option_1
some_global_option: true

Isn't it, what you wanted to achieve?

Thanks for the response and no worries about the delay, hope you are feeling better now!

Okay yes what you've specified is exactly what we want to achieve. But don't we need to specify each key in the load like so?

YAML.ext_load_file('nested_config.yml', ['compile_options','warning_options', 'compiler_defines'])

If I don't need to do that, then yes your gem already works for my use case.

Thanks, I'm feeling better every day.

If you use my example, you do not specify any key, only the file (first parameter).

You only need to specify a key for the extend attribute, if you don't like using the default, which is defined as "extends:" on the yaml root level. This may be the case, if you already use "extends:" on the yaml root level for other cases - or you just don't like it, because the way it is defined might not fit to your configuration style.

Do you have any further questions?

Ah, i think missunderstood your previous question - it was your the point, to have one central place, to specify the key? I will check a solution, like in comment Nr. 6 (#2 (comment))

Just published a new release 0.2.0.

You can specify the key once globally now by #ext_load_key=(key), e.g.:

YAML.ext_load_key = 'my_custom_key'

I think we can close this issue now, if you don't have any more questions to its topic.

Awesome, yes everything's now resolved, thanks!

We can close this issue.

You are welcome!
Thank you for your ideas and inspiration!