我正在尝试从https://docs.gitlab.com/ee/api/lint.html#use-jq-to-create-and-process-yaml--json-payloads实现jq
管道curl
命令,但在make文件上下文中。
我花了几个小时尝试似乎每一个转义的排列和尝试替代命令,但我不能得到等效的工作。在makefile之外我没有问题。
我试着用"$$(<foo.yml)"
或$(shell cat foo.yml)
甚至cat foo.yml | ... @-
代替"$(<foo.yml)"
,但没有运气。shell cat
是我得到的最接近的,但猫删除了n字符,然后使我传递给GitLab的结果JSON返回令人困惑的错误:{" validate ":false,"error ":["(u003cunknownu003e):在此上下文中不允许在第1行第12列的块序列项"],"warnings"; [],"status"; " invalidate "}
我将该字符串与Makefile上下文之外的工作原始版本进行了比较,唯一不同的是缺少n字符。
请帮忙!谢谢你。
编辑根据请求,以下是来自URL的额外详细信息。
这是我试图移动到Makefile上下文中的命令。这个命令可以直接从我的bash终端运行。
jq --null-input --arg yaml "$(<.gitlab-ci.yml)" '.content=$yaml' | curl "https://gitlab.com/api/v4/ci/lint?" --header "Content-Type: application/json" --header "PRIVATE-TOKEN: $GITLAB_PERSONAL_ACCESS_TOKEN" --data @-
回复如下:{"valid":true,"errors":[],"warnings":[],"status":"valid"}
这是我的Makefile版本:
.PHONY: lint
make lint:
jq --null-input '.content="$(shell cat "$(GITLAB_CI_FILE_PATH)")"' | curl --header "Content-Type: application/json" --header "PRIVATE-TOKEN: $(GITLAB_PERSONAL_ACCESS_TOKEN)" --data @- "https://gitlab.com/api/v4/ci/lint"
回复如下:{"valid":false,"errors":["(u003cunknownu003e): block sequence entries are not allowed in this context at line 1 column 12"],"warnings":[],"status":"invalid"}
我知道这是因为我的makefile版本不包含换行符。
下面是输入的YAML文件:include:
- project: adamcunnington.info/MLG/common
file: /cicd/.gitlab-ci-python.yml
如果您提供您要编写的完整规则将非常有帮助。
使用$(<foo.yml)
不能在make recipe中工作,因为make将所有以$
开头的内容视为make变量,并在运行shell之前展开它。您需要转义您希望shell看到的所有$
,如$$
。
使用$$(<foo.yml)
可以在某些系统上工作,但不能在其他系统上工作:该语法不是由POSIX标准定义的,因此提供POSIX功能的shell将无法使用它做任何事情。这是bash shell的增强语法。Make在默认情况下总是运行/bin/sh
,所以如果您的/bin/sh
真的是bash,它可能会工作。
使用$(shell cat foo.yml)
不能工作,因为make的shell函数在替换它之前会从输出中删除所有换行符。
因为我们不能看到你的实际规则,我们不能真正建议最好的替代方案。有没有什么原因导致你不能使用简单的,标准的:
jq < foo.yml
?
埃塔
如前所述,您的shell是bash。Make always默认使用/bin/sh
作为shell(想象一下,如果Make always使用调用它的人正在使用的shell,可移植性问题)。
如果你不知道如何重写你的makefile配方来使用标准的POSIX语法,而你想使用bash特定的语法,你可以告诉make使用bash作为它的shell:
SHELL := /bin/bash
现在所有bash特定的魔法将在您的食谱中工作。当然,你的makefile不能在没有/bin/bash
的系统上工作。
jq
部分的一个更简单和更可移植的重新表述是
jq --null-input --rawfile yaml .gitlab-ci.yml '.content=$yaml'
在Makefile
中,显然是双美元符号
一个微小的区别是,--rawfile
也包括了文件中的最后一个换行符。
--rawfile
选项在jq
1.6中引入。