当可能的参数可以包括冒号字符(:)时,捕获Makefile的所有帮助程序

当可能的参数可以包括冒号字符(:)时,捕获Makefile的所有帮助程序,makefile,Makefile,尝试改进我的项目的Makefile,以便我可以直接在实际运行应用程序的docker容器中执行某些命令 到目前为止,我有一个解决方案,适用于以下情况: $ make composer update $ make console help 这是迄今为止Makefile的相关部分: # if the command starts with "composer" or console, grab the arguments for the command ifeq ($(firstword $(MAK

尝试改进我的项目的Makefile,以便我可以直接在实际运行应用程序的docker容器中执行某些命令

到目前为止,我有一个解决方案,适用于以下情况:

$ make composer update
$ make console help
这是迄今为止
Makefile
的相关部分:

# if the command starts with "composer" or console, grab the arguments for the command
ifeq ($(firstword $(MAKECMDGOALS)), $(filter $(firstword $(MAKECMDGOALS)), console composer))
    # use the rest as arguments for our real command
    COMMAND_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
    # turn them into null targets 
    $(eval $(COMMAND_ARGS):;@:)
endif 

console: ## execute bin console within the APP/PHP container
    docker-compose exec core19app sh -c "php bin/console $(COMMAND_ARGS)"

composer: ## execute container's console 
    docker-compose exec core19app sh -c "composer $(COMMAND_ARGS)"
问题是,
console
命令是Symfony命令,几乎在所有情况下都包含
字符

例如:

尝试执行任何一项都会扼杀make,这将令人遗憾地报告:

Makefile:6:**目标模式不包含“%%”。停下来

问题在于我们动态地为被调用的命令自动注册空任务,并且由于变量命令包含一个
make
阻塞


尽量保持这一点尽可能接近
生成控制台命令:sucommand
,我们将所有内容都保存在
生成文件
中,尽管可以使用变体,但尽量保持摩擦尽可能小

利用生成调用约定,您可能会获得更多的收益(期望得到的目标列表)。不同的论题风格很难。考虑备选方案:

使用变量将参数传递到控制台

make console CMD=cache:clear

Makefile:
console:
    docker-compose exec core19app sh -c "php bin/console $(CMD)"

或者使用伪目标

make console-cache:clear

Makefile
console-%:
    docker-compose exec core19app sh -c "php bin/console $(@:console-%=%)"

作为最后的手段,如果需要的话,请考虑小包装器“使控制台”更友好的命令行界面。

#! /bin/sh
make console CMD="$1"
差不多

ifeq ($(firstword $(MAKECMDGOALS)), $(filter $(firstword $(MAKECMDGOALS)), console composer))
    COMMAND_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
endif 

console:
    @docker-compose exec core19app sh -c "php bin/console $(COMMAND_ARGS)"

composer:
    @docker-compose exec core19app sh -c "composer $(COMMAND_ARGS)"

%:
    @:
似乎是你想要的。我不能保证你认为不相关的
Makefile
部分不会有不必要的副作用,我同意那些建议你滥用
make
去做它没有设计的事情。我可能会使用我自己的脚本,围绕
make
docker compose
。简化版为:

#! /bin/sh

case "$1" in
    console)
       shift
       docker-compose exec core19app sh -c "php bin/console $*"
       ;;
    composer)
       shift
       docker-compose exec core19app sh -c "composer $*"
       ;;
    *)
       make "$@"
       ;;
esac

此解决方案最多只能用于一个目标,作为命令行上的第一个参数提供(或无)

听起来你实际上不想构建
缓存:clear
作为目标;为什么不传入一个普通变量呢?例如
make console_ARGS=cache:clear基本上是因为它更详细?如果没有其他方法可以实现这一点,那么它可以工作。但是使用命令的方式与我在没有使用docker会更方便,而且对肌肉记忆有很大帮助。不,我不想把
cache:clear
作为目标,也不想把
console
提供的几十个命令中的任何一个作为目标(它们都像
namespace:command
)“因为它更详细”⟶ 您可以使用shell函数或脚本根据您喜欢的语法创建和执行
make
命令。现在还不清楚
make
是否是您想要的工具(我看不到任何依赖项)。如果我没弄错的话,你只想让第一个命令行参数成为一个真正的目标。为什么不编写一个简单的shell包装程序,而不是针对好的生成习惯编写一些命运多舛的编程呢?是的,@TobySpeight说了些什么。谢谢。如果能够实现上述功能,那就太好了。伪目标已经足够相似了,如果没有其他功能可以实现,我们就可以了“我可以接受它。但它并没有真正像现在这样工作。例如,执行
make console debug:config
尝试执行
php bin/console debug:config
,而不是执行
php bin/console debug:config
。@yivi糟糕,我有一个输入错误-抱歉,请参阅更新的代码,它将从目标。我最初的实现是使用“cmd-*”作为前缀。这并不是说我不想忽略任何东西。但是这个makefile中已经内置了很多其他东西(更不用说内部文档),这使得将内容放在外部变得不那么吸引人。(对于make targets,失去内置的自动完成功能,我们有“帮助”列出所有可用命令的目标,等等)。关于“make是为什么而设计的”…我相信这是该工具的一个有效用例,即使我们达到了它的极限。非常感谢您的帮助,我会看看我们可以使用哪些。
#! /bin/sh

case "$1" in
    console)
       shift
       docker-compose exec core19app sh -c "php bin/console $*"
       ;;
    composer)
       shift
       docker-compose exec core19app sh -c "composer $*"
       ;;
    *)
       make "$@"
       ;;
esac
ifneq ($(if $(MAKECMDGOALS),$(words $(MAKECMDGOALS)),1),1)
.SUFFIXES:
TARGET := $(if $(findstring :,$(firstword $(MAKECMDGOALS))),,$(firstword $(MAKECMDGOALS))) 
PARAMS := $(if $(findstring :,$(firstword $(MAKECMDGOALS))),$(MAKECMDGOALS),$(wordlist 2,100000,$(MAKECMDGOALS)))
.PHONY: ONLY_ONCE
ONLY_ONCE:
    $(MAKE) $(TARGET) COMMAND_ARGS="$(PARAMS)"
%: ONLY_ONCE
    @:
else
# Your previous makefile goes here:
.PHONY: console composer

console: ## execute bin console within the APP/PHP container
    docker-compose exec core19app sh -c "php bin/console $(COMMAND_ARGS)"

composer: ## execute container's console 
    docker-compose exec core19app sh -c "composer $(COMMAND_ARGS)"

endif