0

Rather than installing Black on my local machine, I'm experimenting with running Black (installed from requirements.txt) from a Docker container. I'm looking to add a Makefile command to format modified files. This is what I've come up with so far, which is run with make format:

# formats any files which differ from the point at which the current branch (2) forked from master (1)
# ____1_____________ master
#     \__________ dev
#          \_________2 current_branch
diff_files := $(shell git diff $(git merge-base --fork-point master) --name-only -- "*.py")
format:
    docker-compose run --rm api black $(diff_files)

This finds the point at which the current branch forked from master

https://git-scm.com/docs/git-merge-base#_operation_modes:

git merge-base --fork-point master

And this returns the files names returned from the diff with the .py extension (.py filter might be overkill?)

https://git-scm.com/docs/git-diff#_description

--name-only -- "*.py"

Would love to hear some feedback, or any examples of similar setups.

strongdev
  • 3
  • 2

1 Answers1

1

Dollar signs are significant to make: they introduce variables. If you want to pass a dollar sign to a shell script, say within a $(shell ..) function, you need to escape them by writing them as $$:

diff_files := $(shell git diff $$(git merge-base --fork-point master) --name-only -- "*.py")

Otherwise, make thinks that $(git merge-base --fork-point master) is a long and very odd-looking make variable, and all make variables that are not defined are evaluated to the empty string.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • Since the dollar signs are being used for command substitutions and not to reference variables, isn't escaping them with $$ incorrect? I've tested the format target as defined in my original question and it seems to work without any issues, am I misunderstanding something? – strongdev Jun 15 '20 at 10:39
  • As I mentioned in my answer if you want a make variable or function you use single `$` (don't escape it). If you want to pass the value to the shell (for example, as a command substitution) you have to escape it from make and use `$$`. The way you have it written, the shell is running the command `git diff --name-only -- "*.py"`. Maybe that is actually working for you so it seems OK. But, you are absolutely _not_ running the `git merge-base` command at all in your makefile. – MadScientist Jun 15 '20 at 18:23