magynhard / yaml_extend Goto Github PK
View Code? Open in Web Editor NEWRuby gem that extends YAML to support file based inheritance, including command line version
License: MIT License
Ruby gem that extends YAML to support file based inheritance, including command line version
License: MIT License
if the yaml filesfile.yml
and other.yml
are in a directory called config
and the call YAML.ext_load_file 'config/file.yml'
is issued with cwd one above config
then the other files that are extended are not found
# file.yml
extends:
- 'other.yml' # not found
- 'config/other.yml' # not found either
does not work with path relative to file.yml or relative to cwd
Hi,
I've added the gem and followed the instructions, but I keep getting this error: undefined method `start_with?' for #Pathname:0x00000006327430
Method called: YAML.ext_load_file('/opt/config/test.yml')
Any ideas?
Thanks.
Details:
undefined method `start_with?' for #Pathname:0x00000006327430
/usr/local/rvm/gems/ruby-1.9.3-p551/gems/yaml_extend-1.1.1/lib/yaml_extend.rb:160:in `absolute_path?'
/usr/local/rvm/gems/ruby-1.9.3-p551/gems/yaml_extend-1.1.1/lib/yaml_extend.rb:142:in `make_absolute_path'
/usr/local/rvm/gems/ruby-1.9.3-p551/gems/yaml_extend-1.1.1/lib/yaml_extend.rb:107:in `ext_load_file_recursive'
/usr/local/rvm/gems/ruby-1.9.3-p551/gems/yaml_extend-1.1.1/lib/yaml_extend.rb:75:in `ext_load_file'
According to the docs:
If you want to inherit from several files, you can specify a list (Array) of files. They are merged from top to bottom, so the latest file "wins" - that means it overwrites duplicate values if they exist with the values in the latest file where they occur.
This however is not true. Actually the order seems to be exactly the opposite!
The later entries in the extends
array have precedence over the earlier ones.
Additionally, the own keys of the file that extends multiple others tend to come first i.e. own entries first, then extended ones (the order is messed up, but they correctly overwrite the values of parent entries).
As an example, let's have the following 3 files:
# parent1.yml
parent1_key_overwritten: parent1
parent1_key_own: parent1
# parent2.yml
parent1_key_overwritten: parent2
parent2_key_own: parent2
# child.yml
extends:
- parent1.yml
- parent2.yml
some_other_key: child
The expected result of YAML.ext_load_file 'child.yml'
should then be:
parent1_key_overwritten: parent2
parent1_key_own: parent1
parent2_key_own: parent2
some_other_key: child
but instead, what we get is:
some_other_key: child
parent1_key_overwritten: parent1
parent1_key_own: parent1
parent2_key_own: parent2
For example,
Let the base YAML be:
# base.yml
alpha: true
beta: false
gamma: true
data:
delta: false
kappa: true
theta: false
Let the extended YAML be:
# extended.yml
extends: 'base.yml'
alpha: false
beta: true
data:
delta: true
kappa: false
When you call
YAML.ext_load_file 'extended.yml'
the returned YAML value results in
alpha: true
beta: true
gamma: true
data:
delta: true
kappa: true
theta: false
The values of alpha and kappa should actually be false since they are over-written in extended YAML
Please see the failing spec here: #13
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?
As I understand, extends
seems to add the extended files at the end of the main file, and not at the beginning.
This is a little counter intuitive (since everywhere else, extend or include means "first use the content of the included file"), and causes issues when using anchors.
Example use case:
This is a valid YAML:
one: &one
hello: world
menu:
<<: *one
While this is not a valid YAML:
menu:
<<: *one
one: &one
hello: world
So, if I wish to provide "blocks of YAML" that can be used by other blocks, I cannot use the extend functionality. The below example is broken:
# test.rb
require 'yaml_extend'
data = YAML.ext_load_file 'child.yml'
puts data.to_yaml
# child.yml
extends:
- parent.yml
menu:
<<: *one
<<: *two
# parent.yml
one: &one
hello: world
two: &two
hi: world
hey: world
I know there are other ways around it, but my use case was more naturally implemented with anchors, and now I know they cannot be used this way.
Is there any reason for the included content to come last and not first?
Please see the failing spec here: #15
Hi,
I've been looking to use this library and was wondering if it only works for values of type String.
Would it be possible to support at least other primitive types, like Integer, Boolean?
I thought this package would be a very nice addition to a mechanism I have in place to specify settings/configurations...but it seems the order in which merged files end up in the final result are giving not the results I would desire.
My settings syntax is as follows:
block:
- rule1:
setting a
setting b
....
- rule2:
setting c
...
The rules determine on what settings get applied. It is legal to list the same rule multiple times (that is why it is an array). If a setting is repeated, the 'last one wins' which feels most intuitive and follows what yaml does.
However in the following example:
# base.yaml
---
blockX:
- playground:
macros:
M_BASE: ja
M_REPLACE: to_be_replaced
...
# settings.yaml
---
extends:
- 'base.yaml'
blockX:
- playground:
macros:
M_DERIVE: ja
M_REPLACE: replaced
...
Gives as result:
---
blockX:
- playground:
macros:
M_DERIVE: ja
M_REPLACE: replaced
- playground:
macros:
M_BASE: ja
M_REPLACE: to_be_replaced
...
In which it is unfortunate that the extended base comes last in the list, as a result when I process the file the macros result in:
M_DERIVE: ja
M_BASE: ja
M_REPLACE: to_be replaced ---> should haven bee 'replaced'
Would it be difficult to put the merged list in the order from base --> derived? (maybe optional)
I've been using yaml_extend and like it. Thanks!
I now need to pass the symbolize_names
option to Psych. Specifically I need to pass symbolize_names: true
.
I don't see a way to do this. Is there a way to pass options thru to Psych? Am I overlooking something?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.