Mohammed Ali
Mohammed Ali

Reputation: 155

Makefile cache creating false positive outcome

I have a make target, which i usually need to run twice to get accurate outcome. I.e the 1st run if accurate thenn on the 2nd run, if the variable is changed, it still displays the previous output, which is wrong, is there a way to get rid of cache or clear it in between.

.PHONY:check-tf-lint
check-tf-lint: configure ## TF Linting
    $(eval list_of_dir := $(shell cd ${deployment} && ls -ld */ |  awk '{print $$NF}'|  grep -v 'test_cases'| sed 's|/||g'))
    $(shell touch ${quality-metrics}/formatting.txt)
    @for i in aws_bot; do \
        make set-tf-version -e infra_module_path=$$i; \
        terraform fmt -check -list=false ${deployment}/$$i ; \
        if [ "$$?" != "0" ]; then \
            echo "Need Formatting in $$i" >> ${quality-metrics}/formatting.txt; \
            terraform fmt -check ${deployment}/$$i >> ${quality-metrics}/formatting.txt; \
            echo "" >> ${quality-metrics}/formatting.txt; \
        fi \
    done
    $(eval TMP := $(shell (cat ${quality-metrics}/formatting.txt | wc -l)))
    echo "${TMP}"
    @if [ "$(TMP)" = "0" ]; then \
        echo "All Good! No Formatting Needed."; \
    else \
        echo "Kindly Format Below Mentioned code and check in Again"; \
        cat ${quality-metrics}/formatting.txt; \
    fi
    $(shell rm -rf ${quality-metrics}/formatting.txt)
    @if [ "$(TMP)" != "0" ]; then \
        exit 1; \
    fi

Upvotes: 1

Views: 803

Answers (2)

Mohammed Ali
Mohammed Ali

Reputation: 155

This worked for me !

.PHONY:check-tf-lint
check-tf-lint: ## TF Linting
    $(eval list_of_dir := $(shell cd ${deployment} && ls -ld */ |  awk '{print $$NF}'|  grep -v 'test_cases'| sed 's|/||g'))
    @for i in $(list_of_dir); do \
        make set-tf-version -e infra_module_path=$$i; \
        terraform fmt -check -list=false ${deployment}/$$i ; \
        if [ "$$?" != "0" ]; then \
            echo "Need Formatting in $$i" >> ${quality-metrics}/formatting.txt; \
            terraform fmt -check ${deployment}/$$i >> ${quality-metrics}/formatting.txt; \
            echo "" >> ${quality-metrics}/formatting.txt; \
        fi \
    done
    @if [ -e "${quality-metrics}/formatting.txt" ]; then \
        export MNC=`cat ${quality-metrics}/formatting.txt | wc -l`; \
        if [ "$${MNC}" = "0" ]; then \
            echo "All Good! No Formatting Needed."; \
        else \
            echo ""; \
            echo "Kindly Format Below Mentioned code and check in Again"; \
            cat ${quality-metrics}/formatting.txt; \
        fi; \
        rm -rf ${quality-metrics}/formatting.txt; \
        if [ "$${MNC}" != "0" ]; then \
            exit 1; \
        fi \
    fi

Upvotes: 0

MadScientist
MadScientist

Reputation: 100866

Rule of thumb: you should never use eval or shell functions in a make recipe. If you are doing that it's a pretty sure sign that something has gone wrong somewhere.

In your case the reason you see this behavior is that make will expand ALL variables and functions for all lines in a recipe before the first line in the recipe is invoked. So as far as make is concerned your recipe is handled like this:

.PHONY:check-tf-lint
check-tf-lint: configure ## TF Linting
        $(eval list_of_dir := $(shell cd ${deployment} && ls -ld */ |  awk '{print $$NF}'|  grep -v 'test_cases'| sed 's|/||g'))
        $(shell touch ${quality-metrics}/formatting.txt)
        $(eval TMP := $(shell (cat ${quality-metrics}/formatting.txt | wc -l)))
        $(shell rm -rf ${quality-metrics}/formatting.txt)
        @for i in aws_bot; do \
            make set-tf-version -e infra_module_path=$$i; \
            terraform fmt -check -list=false ${deployment}/$$i ; \
            if [ "$$?" != "0" ]; then \
                echo "Need Formatting in $$i" >> ${quality-metrics}/formatting.txt; \
                terraform fmt -check ${deployment}/$$i >> ${quality-metrics}/formatting.txt; \
                echo "" >> ${quality-metrics}/formatting.txt; \
            fi \
        done
        echo "${TMP}"
        @if [ "$(TMP)" = "0" ]; then \
            echo "All Good! No Formatting Needed."; \
        else \
            echo "Kindly Format Below Mentioned code and check in Again"; \
            cat ${quality-metrics}/formatting.txt; \
        fi
        @if [ "$(TMP)" != "0" ]; then \
            exit 1; \
        fi

You should always write your recipes using shell facilities and not make facilities. Set shell variables, don't use eval to set make variables, and run shell commands directly (you're in a recipe after all!) rather than using make's shell function.

You may need to put all the lines in a single script (with semicolon / backslash) to allow this to work. Or consider .ONESHELL but that's a much bigger set of changes.

Upvotes: 1

Related Questions