0

I am trying to create a template which has some defaults but these should be overridden if a custom values file is provided. The problem is some of my variables in the object are built from other variables in the same object, like adjective: 'Good' + self.fruit. This does not get overridden.

std.mergePatch does not produce expected result because it renders the whole object (which has already made us of self.fruit by now) and then overrides fruit.

local myobj = { 
  adjective: 'Good ' + self.fruit.name, 
  fruit: {
    name: 'apple', 
    qty: 1
  },
};
myobj

produces correct result when nothing is overridden:

{
  "adjective": "Good apple",
  "fruit": {
    "name": "apple",
    "qty": 1
  }
}

But when I try to override it with another variable, it still takes the default value if I use std.mergePatch as follows:

local config = {
  fruit: {
    name: 'banana',
    size: 'large',
  },
};

local myobj = { 
  adjective: 'Good ' + self.fruit.name, 
  fruit: {
    name: 'apple', 
    qty: 1
  },
};

std.mergePatch(myobj, config)

Produces (notice the wrong fruit name in adjective):

{
  "adjective": "Good apple",
  "fruit": {
    "name": "banana",
    "qty": 1,
    "size": "large"
  }
}

And if I directly add the two objects, it misses the extra information:

local config = {
  fruit: {
    name: 'banana',
    size: 'large',
  },
};

local myobj = { 
  adjective: 'Good ' + self.fruit.name, 
  fruit: {
    name: 'apple', 
    qty: 1
  },
};

myobj + config

Produces (notice the missing default qty: 1):

{
  "adjective": "Good banana",
  "fruit": {
    "name": "banana",
    "size": "large"
  }
}

How to achieve this with Jsonnet?

1 Answers1

1

std.mergePatch() will combine those already "finalized" objects, thus overriding self fields won't be possible.

Adding the two objects just needs the +: to be able to derive from parent's field:

jsonnet-stackoverflow-56971012.jsonnet src:

local config = {
  fruit+: {
    name: 'banana',
    size: 'large',
  },
};

local myobj = {
  adjective: 'Good ' + self.fruit.name,
  fruit+: {
    name: 'apple',
    qty: 1
  },
};

myobj + config

jsonnet-stackoverflow-56971012.jsonnet output:

{
   "adjective": "Good banana",
   "fruit": {
      "name": "banana",
      "qty": 1,
      "size": "large"
   }
}

Note the + is not needed for myobj, although IMO it's a good idea to keep it there in case you'd need itself to override a (future) base object.

jjo
  • 2,595
  • 1
  • 8
  • 16