如何在生成文件目标内实现 $(<某个文件)?



我正在尝试从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选项在jq1.6中引入。

相关内容

最新更新