Search code examples
jsonnet

Extending inner object without explicitly extending every object in its path


I have the following 2 files:

1.jsonnet

{
  a: {
    b: {
      b1: 1
    }
  }
}

2.jsonnet

local one = import'1.jsonnet';

one {
  a+: {
    b+: {
      b2: 2
    }
  }
}

I want to extend the inner object b which is part of a (e.g. add a.b.b2), is there a way to do it without explicitly doing as in 2.jsonnet? The idea is that an object might be a few levels deep and that the user should not care about the inner structure.

Something similar to:

{
  bInner::self.a.b,
  a : {
    b : {
      b1 : 1
    }
  }
}

one {
  bInner +: {
    b2 : 2
  }
}

Solution

  • Note I'm assuming that the user will need somehow to know where in the tree they'd want to overload the field(s).

    You can use helpers.jsonnet from https://github.com/bitnami/kube-prod-runtime/blob/master/manifests/contrib/helpers.jsonnet as:

    $ wget https://raw.githubusercontent.com/bitnami/kube-prod-runtime/master/manifests/contrib/helpers.jsonnet
    
    $ cat 2.jsonnet
    local one = import'1.jsonnet';
    local helpers = import 'helpers.jsonnet';
    
    helpers.mergeAtPath(one, 'a.b.b2', 2)
    
    $ jsonnet 2.jsonnet 
    {
       "a": {
          "b": {
             "b1": 1,
             "b2": 2
          }
       }
    }
    

    Note also that you could merge there any type of jsonnet object, e.g.

    helpers.mergeAtPath(one, "a.b.b2", [1,2,3])