0

I have a makefile that deploys x project in aws

The goal is to execute the make like this:

make deploy-production

And see output like this

Please select the project:
1) api
2) web
3) somethingelse

You press then the number and make continues, by assigning the choice to a variable named project

I have already "autogenerating" targets for supported envs, just want to build the multichoice for projects. Sample makefile of mine with removed nonrelevant stuff:

ENVIRONMENTS := development staging production
TARGETS := $(foreach X,$(ENVIRONMENTS),deploy-$X)

$(TARGETS):
  $(eval ENV:=$(subst deploy-,,$(@)))
  # here want to ask for project, env i have already as resolved from above line
Kristi Jorgji
  • 1,154
  • 1
  • 14
  • 39
  • Do you mean that user can select multiple options at the same time (like both api + web)? Or only one of the presented? – Alexey S. Larionov Jul 05 '21 at 08:05
  • 1
    The short answer is, that's not really how make works. It's not not supposed to be interactive and it has no facilities that allow for interactive use. In fact, interactive is actually not possible if you want to do useful things like enable parallel builds (because you don't know which recipe has stdin). Why don't you just create targets like `deploy-api`, `deploy-web`, etc. and have the user enter `make deploy-api`, `make deploy-web`, etc. – MadScientist Jul 05 '21 at 14:44
  • Sorry wrong question description, no i want to select only one value but shown it in a select menu, and user can enter only one answer example: `1` then press enter, then api will start deploying. So only 1 at a time. Also if some env value let say PROJECT is defined, the menu will not show but use that env – Kristi Jorgji Jul 05 '21 at 15:51
  • @MadScientist that is what i did created multiple targets with cartesian product of environemts and repositories. Work fine, just for learning was curious if this was possible. For now am using the many targets solution you also suggest – Kristi Jorgji Jul 05 '21 at 15:52

1 Answers1

1

Well, make can run any shell script. So if you write a shell script that will ask the user for input and accept an answer you can run it from make.

You could do something like this:

deploy-production:
        @echo Please select the project:; \
        echo '1) api'; \
        echo '2) web'; \
        echo '3) somethingelse'; \
        read -p 'Enter value: ' result && $(MAKE) CHOICE=$$result got-choice

There is a LOT left out here: handling invalid values, converting the CHOICE value into a target that would then be a prerequisite of the got-choice target, etc. etc. I don't really think this is a good way forward but you could make it work.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • thanks, so here have to map manually the result which is number to text ? the choice (project) should be the text api|web|somethingelse and not number – Kristi Jorgji Jul 05 '21 at 21:24
  • It's up to you, and the person typing things in, what they type. I have no idea. They can type the word if they want. whatever they type, will go into the shell variable `result`. This isn't really related to makefiles at all: this is shell script programming. `read` is a shell built-in. You can read more about shell scripting on the web etc. – MadScientist Jul 06 '21 at 00:20
  • I know `read` i mean they need to choose a number as is more user friendly/easy but makefile need to store in variable the word correpsonding to that number – Kristi Jorgji Jul 06 '21 at 13:33
  • It's up to you. You can either write some makefile code using things like `ifeq` etc. or you can do the translation using shell operations such as a `case` statement, in the recipe, after they enter the value. – MadScientist Jul 06 '21 at 13:39
  • allright thanks then i am accepting this answer as is complete now first reading the number, then have to map to the project string value, and that variable is aused afterwards – Kristi Jorgji Jul 06 '21 at 13:50
  • what would be elegant if make support is declaring a map array like `number => text` and not use switch statement to find the text, but get it from map – Kristi Jorgji Jul 06 '21 at 13:51
  • Perhaps but this particular need is not a reason to add that feature IMO. As I mentioned initially, makefiles are not intended to be interactive and I don't really have any interest in adding features to allow interactive uses. Having make support some kind of dictionary variable type in addition to its current "string" type could be a useful feature in general although getting the syntax right could be tricky: makefile syntax is famously lax which means its hard to add new syntax without backward-compatibility problems. – MadScientist Jul 06 '21 at 13:58