如何在Jsonnet中覆盖“自我”?

时间:2019-07-10 12:45:38

标签: 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实现这一目标?

1 个答案:

答案 0 :(得分:1)

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

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

  

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输出:

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

请注意,+不需要myobj,尽管IMO还是建议将其保留在该位置,以防您需要自己覆盖(未来)基础对象。