如何使用yq为YAML树中任意层级的responses对象新增属性
问题说明
处理OpenAPI规范的YAML文件时,需要为所有键名为responses的对象统一新增一条响应配置,尝试多种写法均未达到预期,暂未定位到yq语法的具体问题点。
涉及的示例YAML文件结构如下:
openapi: 3.0.1 info: title: my service description: API for my service version: 1.0.0 security: - jwt: - read paths: '/foo/{fooId}/firmware/update-request': post: parameters: - name: fooId in: path description: Foo Id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/FooRequest' example: firmwareVersion: "0.1" responses: '202': description: Foo has been done '400': $ref: '#/components/responses/BadRequest' '409': $ref: '#/components/responses/Conflict' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/ServerError' '502': $ref: '#/components/responses/BadGateway' '/foo/{fooId}/firmware/auto-update': put: parameters: - name: fooId in: path description: Foo Id required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/FooUpdate' example: enabled: true responses: '204': description: Foo update '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/ServerError' '502': $ref: '#/components/responses/BadGateway' # 后续还有大量同类路径配置
目标效果
在完全保留原有文件结构的前提下,所有responses节点都新增指定响应条目,原有配置保持不变,效果示例:
responses: '204': description: Foo update # ... 其余原有响应配置保持不变 'xxx': description: yyy
问题排查
之前尝试的命令如下:
yq -i '.. | select(has("responses")).responses | . += {"xxx": {"description": yyy}}' my.yaml
该写法的问题在于:管道符会将前一步的输出作为后一步的处理上下文,最终整个命令只输出所有匹配到的responses节点内容,根节点到responses路径上的其他无关节点会被全部过滤丢弃。
正确实现方案
使用mikefarah/yq v4版本时,执行以下命令即可满足需求:
yq -i '(.. | select(type == "object" and has("responses")).responses) += {"xxx": {"description": "yyy"}}' my.yaml
语法说明:
- 用括号包裹目标节点匹配表达式,将其指定为更新操作的目标路径,而非通过管道过滤输出结果,因此会完整保留原始文档的所有结构
- 增加
type == "object"判断,避免遍历到数组、字符串等非对象类型节点时调用has()方法触发报错 +=操作会在原有responses节点的配置基础上追加新的响应条目,不会覆盖原有配置
内容的提问来源于stack exchange,提问作者Sven-Michael Stübe
相关产品推荐
相关产品推荐

