问题
I need to create a lookup table/dictionary/map in my Makefile to look up key-value information.
I have been trying to use ifeq
statements to do the same thing but my statements seem to fail:
# this gets the account id from the current user's ARN, you must have the AWS CLI and jq installed
AWS_ACCOUNT_ID:=$(shell aws iam get-user | jq -r '.User.Arn' | awk -F ':' '{print $$5;}')
# define a friendly account name for output
ifeq ($(AWS_ACCOUNT_ID), 123456)
AWS_ACCOUNT_FRIENDLY:=staging
endif
ifeq ($(AWS_ACCOUNT_ID), 789012)
AWS_ACCOUNT_FRIENDLY:=preprod
endif
ifeq ($(AWS_ACCOUNT_ID), 345678)
AWS_ACCOUNT_FRIENDLY:=production
endif
It seems to only work with the first value 123456
but not with others.
Is there a way to define a dictionary/map in Make to simply look up the account friendly name by the key of the account id?
回答1:
I can't explain why you don't see the behavior you expect: I would verify that the value of AWS_ACCOUNT_ID
is what you expect: maybe your shell script is not doing what you want. Try adding something like:
AWS_ACCOUNT_ID := $(shell ...)
$(info AWS_ACCOUNT_ID = '$(AWS_ACCOUNT_ID)')
and see what you get.
However related to your more general question, I prefer to use constructed macro names when dealing with situations like this, instead of lots of ifeq
values:
AWS_123456_FRIENDLY := staging
AWS_789012_FRIENDLY := preprod
AWS_345678_FRIENDLY := production
AWS_ACCOUNT_ID := $(shell ...)
AWS_ACCOUNT_FRIENDLY := $(AWS_$(AWS_ACCOUNT_ID)_FRIENDLY)
回答2:
Build and configuration management is becoming a programming task on its own. Unluckily the tools to do that are lacking coherency and broadness of acceptance. Teams often end up rolling their own scripting zoo to glue build, test and release together. If you want to avoid some of the dilution coming with make
and necessary helper scripts outside of it, you can use gmtt which allows table selection for those kinds of tasks you want to complete with onboard GNUmake
calls:
include gmtt/gmtt.mk
AWS_ACCOUNT_ID:=$(shell aws iam get-user | jq -r '.User.Arn' | awk -F ':' '{print $$5;}')
# define a table of 3 columns: <AWS-id> <name> <admin>
define AWS_ACCOUNT_TBL
3
123456 staging kay
789012 preprod catbert
345678 production pointyhairedboss
endef
# select column 2 & 3 from table AWS_ACCOUNT_TBL where column 1 string-equals AWS_ACCOUNT_ID
AWS_ACCOUNT := $(call select,2 3,$(AWS_ACCOUNT_TBL),$$(call str-eq,$$1,$(AWS_ACCOUNT_ID)))
AWS_NAME := $(word 1,$(AWS_ACCOUNT))
ADMIN := $(word 2,$(AWS_ACCOUNT))
$(info AWS account $(AWS_NAME) administered by $(ADMIN))
来源:https://stackoverflow.com/questions/40919502/dictionaries-maps-lookup-tables-in-makefiles