yamlassets

Is there a way to alias/anchor an array in YAML?


I'm using Jammit to package assets up for a Rails application and I have a few asset files that I'd like to be included in each of a few groups. For example, I'd like Sammy and its plugins to be in both my mobile and screen JS packages.

I've tried this:

sammy: &SAMMY
  - public/javascripts/vendor/sammy.js
  - public/javascripts/vendor/sammy*.js

mobile:
  <<: *SAMMY
  - public/javascripts/something_else.js

and this:

mobile:
  - *SAMMY

but both put the Sammy JS files in a nested Array, which Jammit can't understand. Is there a syntax for including the elements of an Array directly in another Array?

NB: I realize that in this case there are only two elements in the SAMMY Array, so it wouldn't be too bad to give each an alias and reference both in each package. That's fine for this case, but quickly gets unmaintainable when there are five or ten elements that have a specific load order.


Solution

  • Your example is valid YAML (a convenient place to check is YPaste), but it's not defined what the merge does. Per the spec, a merge key can have a value:

    1. A mapping, in which case it's merged into the parent mapping.
    2. A sequence of mappings, in which case each is merged, one-by-one, into the parent mapping.

    There's no way of merging sequences on YAML level.

    You can, however, do this in code. Using the YAML from your second idea:

    mobile:
      - *SAMMY
    

    you'll get nested sequences - so flatten them! Assuming you have a mapping of such nested sequences:

    data = YAML::load(File.open('test.yaml'))
    data.each_pair { |key, value| value.flatten! }
    

    (Of course, if you have a more complicated YAML file, and you don't want every sequence flattened (or they're not all sequences), you'll have to do some filtering.)