Reputation: 1273
I’ve a Makefile with multiple git repo’s which I need to clone I use the following which works
clone:
git clone https://github.company.corp/dev-wi/ws-led.git
git clone https://github.company.corp/dev-wi/tools-extension.git
git clone https://github.company.corp/dev-wi/javt-ra.git
While the following code works, I want to do something like this in loop for all the repos on the list
build:
cd ws-led; \
docker build -t ws-led .
cd tools-extension; \
docker build -t tools-extension .
...
For each repo I need to change dir And run the docker build , I want to avoid doing this over and over again ... I know that I need to extract the string after /dev-wi/ as this is the repo directory which I need to run docker build on. since I’ve many repo how can I do it easily ?
I try with subset however I have also the git command (in clone) so it doesn't work,any idea?
update
I've created the A new makefile and use only this code (the ws-led
and tools-extension
is folders in the same level of of the makefile
repos := ws-led tools-extension
.PHONY: all
all: $(patsubst%,%/docker-build.log,$(repos))
%/docker-build.log: %/.git
cd $*; docker build -t $* . >&2 | tee docker-build.log
I got error:
make: Nothing to be done for
all'.`
what am I missing here ?
I try to simplify it but removing the git and let say that the folders (repo) existing on the same level of the makefile
UPDATE
Im change the makefile to be under the root
proj
- ws-led
— Dockerfile
-tools-ext
—Dockerfile
-Makefile
I try with the following
all: pre docker-build
.PHONY: pre docker-build
repos := ws-led tools-ext
pre:
$(patsubst %,%docker-build,$(repos))
docker-build:pre
cd $*; docker build -t $* . >&2 | tee docker-build
when I run make I got the following error
ws-leddocker-build ws-leddocker-build
make: ws-leddocker-build: No such file or directory
Any idea?
Upvotes: 1
Views: 201
Reputation: 189789
Looping is generally something you want to avoid. Instead, declare a series of targets for each repo.
repos := ws-led tools-extension javt-ra
.PHONY: all clone
all: $(patsubst %,%/.built,$(repos))
clone: $(patsubst %,%/.git,$(repos))
%/.built: %/.git
cd $*; docker build -t $* .
touch $@
%/.git:
git clone https://github.company.corp/dev-wi/$*.git
The .built
flag file is a bit of a wart, and could usefully be replaced with something more useful, like the output from docker build
.
all: $(patsubst %,%/docker-build.log,$(repos))
%/docker-build.log: %/.git
cd $*; docker build -t $* . >&2 | tee docker-build.log
The reason we generally try to avoid loops is to allow make
to do its primary job properly -- avoid rerunning commands when a target is already up to date. So, for example, if you only changed ws-led
, you don't want to force the other two to be rebuilt as well.
Having said that, the $(patsubst ...)
is a loop of sorts; it basically loops over repos
and creates a small piece of text around each. Without the patsubst
we could write
all: ws-led/.built tools-extension/.built javt-ra/.built
which simply says that to make all
we need to make those three; and then
%/.built: %/.git
says that for anything matching the pattern, it depends on the same stem with /.git
after it. So in an otherwise empty directory, make
would find that
all
, we need to make ws-led/.built
, tools-extension/.built
, and javt-ra/.built
;
ws-led/.built
, we need to make ws-led/.git
;
ws-led/.git
, we need togit clone https://github.company.corp/dev-wi/ws-led.git
cd ws-led; docker build -t ws-led .
touch ws-led/.built
tools-extension/.built
, we need to make tools-extension/.git
;
tools-extension/.git
, we need togit clone https://github.company.corp/dev-wi/tools-extension.git
... etc etc.In the future, when make
finds that ws-led
is newer than ws-led/.built
it will build it again; but if it is not, it will conclude that no work needs to be done, etc for the other targets. This is how we avoid building things needlessly; but it obviously requires that the Makefile
properly contains a formalization of every relevant dependency. (In this case, you would ideally like for there to be a way to know when the Git upstream has changed and something needs to be pulled by the local Makefile
; this currently simply regards everything as done if the local Git clone has not received any updates.)
Upvotes: 2