如何在 Jsonnet 中覆盖 'self'?

How to override 'self' in Jsonnet?

我正在尝试创建一个具有一些默认值的模板,但如果提供了自定义值文件,则应覆盖这些默认值。问题是我在对象中的一些变量是从同一对象中的其他变量构建的,比如 adjective: 'Good' + self.fruit。这不会被覆盖。

std.mergePatch 没有产生预期的结果,因为它渲染了整个对象(现在已经使我们成为 self.fruit)然后覆盖了 fruit.

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

未覆盖任何内容时产生正确的结果:

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

但是当我尝试用另一个变量覆盖它时,如果我使用 std.mergePatch 它仍然采用默认值,如下所示:

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

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

std.mergePatch(myobj, config)

生产(注意adjective中错误的水果名称):

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

如果我直接添加这两个对象,它会遗漏额外的信息:

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

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

myobj + config

生成(注意缺少默认值 qty: 1):

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

如何使用 Jsonnet 实现这一点?

std.mergePatch() 将合并那些已经 "finalized" 的对象,因此无法覆盖 self 字段。

添加两个对象只需要 +: 能够从父字段派生:

jsonnet-Whosebug-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-Whosebug-56971012.jsonnet output:

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

请注意 myobj 不需要 +,尽管 IMO 最好将其保留在那里,以防您需要自己覆盖(未来的)基础对象。