我有以下Makefile:
#runs the working directory unit tests
test:
@NODE_ENV=test; \
mocha --ignore-leaks $(shell find ./test -name \*test.js);
#deploys working directory
deploy:
@make test; \
make deploy-git; \
make deploy-servers;
#deploys working to git deployment branch
deploy-git:
@status=$$(git status --porcelain); \
if test "x$${status}" = x; then \
git branch -f deployment; \
git push origin deployment; \
echo "Done deploying to git deployment branch."; \
else \
git status; \
echo "Error: cannot deploy. Working directory is dirty."; \
fi
deploy-servers:
# for each server
# @DEPLOY_SERVER_IP = "127.0.0.1"; \
# make deploy-server
#deploy-server:
# connect to this server with ssh
# check if app is already running
# stop the app on the server if already running
# set working directory to app folder
# update deployment git branch
# use git to move head to deployment branch
# start app again
请注意,deploy-servers
和deploy-server
现在只是傻瓜。这是deploy
命令应该执行的操作:
make test
),失败时退出make deploy-git
),在失败时退出make deploy-servers
)您可以在Makefile中看到:
deploy:
@make test; \
make deploy-git; \
make deploy-servers;
问题是我不确定如何在make deploy-git
失败时阻止make test
执行,以及如何在测试失败或{{1}时阻止make deploy-servers
执行失败。
有没有明确的方法可以做到这一点,还是应该使用shell文件或用普通的编程语言编写这些工具?
答案 0 :(得分:9)
shell命令 list 的退出状态是列表中最后一个命令的退出状态。只需将命令列表分成单独的简单命令即可。默认情况下,make
在命令返回非零时停止。
deploy:
@make test
make deploy-git
make deploy-servers
如果你希望忽略简单命令的退出状态,你可以用短划线作为前缀:
target:
cmd1
-cmd2 # It is okay if this fails
cmd3
您的make
手册包含所有详细信息。
答案 1 :(得分:2)
其他人已经给出了基于将“配方”分成单个命令的答案。
在不可行的情况下,您可以在shell脚本中执行set -e
,以便在命令失败时终止它:
target:
set -e ; \
command1 ; \
command2 ; command3 ; \
... commandN
这个set -e
与shell脚本顶部附近的command2
相同,以便在某些命令终止失败时使其保释。
假设我们对command3
和set -e
的终止状态不感兴趣。假设这些指示失败,或者不能可靠地使用终止状态。然后,我们可以编写显式退出测试代替target:
command1 ; \
command2 || exit 1 ; \
command3 ; \
true # exit 0 will do here also.
:
command3
由于{{1}}可以指示失败,并且我们不希望它失败,我们添加了一个成功的虚拟命令。
答案 2 :(得分:1)
make
应该已经这样做了;它使用sh -e
执行复杂命令,只要它不在POSIX兼容shell的循环中,如果命令退出非零,则中止执行,并在命令失败时中止整个Makefile
除非你明确告诉它不要。如果您感到偏执,可以在命令中使用&&
代替;
。
答案 3 :(得分:0)
我通过在潜在断点处代理新的make命令解决了这个问题:
.PHONY cmd_name cmd_name_contd
cmd_name:
if [ "`pwd`" = "/this/dir" ]; then make cmd_name_contd; fi
cmd_name_contd:
@echo "The directory was good, continuing"
这样,如果目录错误,它只是静默退出,你还可以添加一个else条件,并在失败时显示一条消息。