skip to Main Content

I am trying to create a nice and dynamic help, but I am struggling to interpret the variable name in the project’s .env file. I need these names to be interpreted by the .env. I will provide the closest result I was able to achieve, but I couldn’t make any further progress.

enter image description here

In the image above, I marked the text that needs to be interpreted by the .env

Here is the code:

SHELL := /bin/bash
include .env

ENV_FILE = .env

help:  ## Show help.
    @awk 'BEGIN { 
        FS = ":.*##"; 
        printf "nUsage:n  make 33[0;34m<target>33[0mnnTargets:n" 
    } 
    /^[a-zA-Z_/-$${}]+:.*?##/ { 
        targetName = $$1; 
        description = $$2; 
        if (match(targetName, "\$\{([^}]+)\}")) { 
            varEnvName = substr(targetName, RSTART+1, RLENGTH-2); 
            gsub("\$$\{[a-zA-Z_]+\}", varEnvName, targetName); 
        }; 
        printf "  33[0;34m%-10s33[0m %sn", targetName, description 
    }' $(MAKEFILE_LIST)

call/${DOCKER_PHP_CONTAINER_NAME}/a: ## PHP // Help dynamic.
    @echo "Dynamic target running for ${DOCKER_PHP_CONTAINER_NAME}"

call/${DOCKER_NGINX_CONTAINER_NAME}/a: ## NGINX // Help dynamic.
    @echo "Dynamic target running for ${DOCKER_NGINX_CONTAINER_NAME}"

call/bpro_php/b: ## Help fixed.
    @echo "Fixed target running..."

2

Answers


  1. Chosen as BEST ANSWER

    I made it :)

    I'm not sure if it's a best solution, but it's work for me.

    help:  ##           Show help.
    @set -a; source .env &>/dev/null; set +a; 
    awk -v ENV_FILE=".env" ' 
    BEGIN { 
        FS = ":.*##"; 
        printf "nUsage:n  make 33[0;34m<target>33[0mnnTargets:n" 
    } 
    /^[a-zA-Z_/-$${}]+:.*?##/ { 
        targetName = $$1; 
        description = $$2; 
        while ((getline < ENV_FILE) > 0) { 
            if ($$0 ~ /^[^#[:space:]]/) { 
                gsub(/=.*/, "", $$0); 
                varName = $$0; 
                varValue = ENVIRON[varName]; 
                gsub("\$\{" varName "\}", varValue, targetName); 
                gsub(/$$/, "", targetName); 
            } 
        } 
        printf "  33[0;34m%-10s33[0m %sn", targetName, description; 
        close(ENV_FILE); 
    }' $(MAKEFILE_LIST)
    

  2. Another way to go, would be to have your help recipe run make -np to ask make to print its database of rules and then parse that output to get the target names you want. This way make itself will expand the variables just as it will when it runs "for real" and you don’t have to replace variables and there’s no chance that you’ll get the wrong thing.

    To do this you’d need to do something like:

    _MAKE = $(MAKE)
    help:  ## Show help.
            @printf 'nUsage:n  make 33[0;34m<target>33[0mnnTargets:n'
            @$(_MAKE) -np | sed -n 's,^(call/[^:]*):.*,1,p'
    

    This will extract all the targets starting with call/ from the output of the make -np call.

    If you want to know what the _MAKE stuff is about, it’s because of this… oh I was going to include a link to the manual but gnu.org is offline due to an upstream network outage. I’ll try to remember to come back and do that.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search