Skip to content

Instantly share code, notes, and snippets.

@jesugmz
Last active July 17, 2019 20:04
Show Gist options
  • Save jesugmz/a155b4a6686c4172048fabc6836c59e1 to your computer and use it in GitHub Desktop.
Save jesugmz/a155b4a6686c4172048fabc6836c59e1 to your computer and use it in GitHub Desktop.
Git tag regex validation using Makefile

Git tag regex validation using Makefile

This is a portion of a Makefile where I select a Git tag, validate its name using regular expresion and build a Docker image with it as tag.

# it is evaluated when is used (recursively expanded variable)
# https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_6.html#SEC59
git_tag = $(shell git describe --abbrev=0 --tags)
# Semantic versioning format https://semver.org/
tag_regex := ^v([0-9]{1,}\.){2}[0-9]{1,}$

build-image-prod:
ifeq ($(shell echo ${git_tag} | egrep "${tag_regex}"),)
	@echo "No Git tag selected. Are there tags?"
else
	@git checkout ${git_tag} -q
	@echo "Building image for production for Git tag $(git_tag)"
	docker build --target prod --tag trivago/ha-ci-api:$(git_tag) --file docker/api/Dockerfile .
endif
@snebel29
Copy link

I think in Makefiles you have to scape the dollar sign so this is interpreted correctly by grep as the end of the string

tag_regex := ^v([0-9]{1,}\.){2}[0-9]{1,}$$

@jesugmz
Copy link
Author

jesugmz commented Jun 13, 2019

That's a good point. I've been researching and testing, in this case that dollar is render as text. As soon as you escape it with a double dollar it will be interpreted in the shell as a variable. Check it with this examples. To avoid problems with Makefile interpreter scaping that dollar at the end of line I have create two different tests. The expected result is Not works:

  • Dollar will be render as text
$ cat Makefile
text := "testing Makefile"
regex := ^testing$

test:
ifeq ($(shell echo ${text} | egrep "${regex}"),)
	@echo "Works"
else
	@echo "Not works"
endif

$ make test 
Not works
  • Dollar will be render as variable in the shell
$ cat Makefile
text := "testing Makefile"
regex := ^testing$$

test:
ifeq ($(shell echo ${text} | egrep "${regex}"),)
	@echo "Works"
else
	@echo "Not works"
endif

$ make test
Works

Interesting things:

[...] secondary expansions always take place within the scope of the automatic variables for that target. This means that you can use variables such as $@, $*, etc. during the second expansion and they will have their expected values, just as in the recipe. All you have to do is defer the expansion by escaping the $. [...]

https://www.gnu.org/software/make/manual/html_node/Shell-Function.html
https://www.gnu.org/software/make/manual/html_node/Secondary-Expansion.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment