当子命令抛出时终止makefile命令?

Tom*_*Tom 3 shell makefile

我有以下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
Run Code Online (Sandbox Code Playgroud)

请注意,deploy-serversdeploy-server对于现在只是假人.这是deploy命令应该做的:

  1. 运行tests(make test),失败时退出
  2. 将当前头推送到部署分支(make deploy-git),在失败时退出
  3. 拉服务器上的部署分支(make deploy-servers)

您可以在Makefile中看到:

deploy:
    @make test; \
    make deploy-git; \
    make deploy-servers;
Run Code Online (Sandbox Code Playgroud)

问题是我不知道如何防止make deploy-gitmake test失败时执行,以及如何make deploy-servers在测试失败或make deploy-git失败时阻止执行.

有没有明确的方法来做到这一点,还是应该使用shell文件或用普通的编程语言编写这些工具?

Jen*_*ens 10

shell命令列表的退出状态是列表中最后一个命令的退出状态.只需将命令列表转换为单独的单个简单命令即可.默认情况下,make当命令返回非零值时停止.所以你得到你想要的东西

deploy:
    @make test
    make deploy-git
    make deploy-servers
Run Code Online (Sandbox Code Playgroud)

如果您忽略简单命令的退出状态,可以在前面加上破折号:

 target:
     cmd1
     -cmd2 # It is okay if this fails
     cmd3
Run Code Online (Sandbox Code Playgroud)

您的make手册包含所有详细信息.


Kaz*_*Kaz 6

其他人给出的答案是基于将“配方”拆分为单独的命令。

在不可行的情况下,您可以set -e在 shell 脚本中执行以下操作,使其在命令失败时终止:

target:
        set -e ; \
          command1 ; \
          command2 ; command3 ; \
          ... commandN
Run Code Online (Sandbox Code Playgroud)

这与您放置在 shell 脚本顶部附近的情况相同set -e,以便在某些命令失败时终止它。

假设我们对command2和的终止状态不感兴趣command3。假设如果这些指示失败,或者不能可靠地使用终止状态,那就可以了。然后,set -e我们可以编写一个显式的退出测试:

target:
        command1 ; \
        command2 || exit 1 ; \
        command3 ; \
        true  # exit 0 will do here also.
Run Code Online (Sandbox Code Playgroud)

由于command3可以指示失败,并且我们不希望它使我们的构建失败,因此我们添加了一个成功的虚拟命令。