I have following Makefile:
SHELL := /bin/bash
boot:
#go run main.go
test:
#go test ./...
test-conf:
#go test --verbose conf
test-httpd:
#go test --verbose ./httpd
.PHONY: test test-conf test-httpd
Strangely enough make test works without problems however make test-conf or make test-httpd will both result in "github.com/bodokaiser/foobar [no test files]".
When I run go test ./conf from the working dir it works - shouldn't the makefile work too then?
What do I need to do to get go test working with packages in a Makefile?
PS: I would like to avoid using $(pwd) or something in front of all paths if possible...
test-httpd and test-conf don't work, as you can't use --verbose with go test, only -v.
Related
$(shell command -v docker) What command means? it's being used in a Makefile.
I saw this in a github repository that I'm trying to understand.
It looks like it's setting a variable with a command to test if docker is installed, and stop the build if its not, the problem is this that I don't have a command installed and I tryed to install command in ubuntu but it can't find it, looking on internet how to install this commad command seems realy difficult because of its name, how to install command in linux/ubuntu didn't bring anything useful, also search for this being using on Makefiles trying to get some clue but nothing so far.
Running the build command seems to work becuse it build the image and yes I have docker installed, but still getting that message in the terminal make: command: Command not found
Any idea?
make build output (trucated):
$ make build
make: command: Command not found
make: command: Command not found
docker build -t codelytv/typescript-ddd-skeleton:dev .
Sending build context to Docker daemon 1.023MB
.....
This is the Makefile:
.PHONY = default deps build test start clean start-database
IMAGE_NAME := codelytv/typescript-ddd-skeleton
SERVICE_NAME := app
# Test if the dependencies we need to run this Makefile are installed
DOCKER := $(shell command -v docker)
DOCKER_COMPOSE := $(shell command -v docker-compose)
deps:
ifndef DOCKER
#echo "Docker is not available. Please install docker"
#exit 1
endif
ifndef DOCKER_COMPOSE
#echo "docker-compose is not available. Please install docker-compose"
#exit 1
endif
default: build
# Build image
build:
docker build -t $(IMAGE_NAME):dev .
# Run tests
test: build
docker-compose run --rm $(SERVICE_NAME) bash -c 'npm run build && npm run test'
# Start the application
start: build
docker-compose up $(SERVICE_NAME) && docker-compose down
# Clean containers
clean:
docker-compose down --rmi local --volumes --remove-orphans
# Start mongodb container in background
start_database:
docker-compose up -d mongo
What it means is that the person who wrote this makefile wasn't careful enough to write it in a portable way.
The command command is part of the shell (which is why you won't see it if you look for it in the GNU make manual). Not only that, it's part of the bash shell specifically: it is not a POSIX sh standard command. The bash man page says:
command [-pVv] command [arg ...]
Run command with args suppressing the normal shell function
lookup. Only builtin commands or commands found in the PATH are
executed.
Basically, running command docker ... means that any shell alias or function named docker is ignored, and only the actual docker command is run.
However, GNU make always runs /bin/sh as its shell, including for both recipes and for the $(shell ...) function.
So, if you're on a system (such as Red Hat or CentOS or Fedora GNU/Linux) where the /bin/sh is a link to the bash shell, then the above command will work.
However, if you're on a system (such as Debian or Ubuntu GNU/Linux) where the /bin/sh is a link to a simpler POSIX shell such as dash, then the above command will not work.
In reality, this is not needed because there won't be any shell aliases or functions defined in the shell that make invokes, regardless. However, if the author wants to use bash shell features in their makefiles and allow them to work, they also need to tell make to use bash as its shell, by adding this to their makefile:
SHELL := /bin/bash
(of course this assumes that the user has a /bin/bash on their system, but...)
I'm using Make for handling basic tasks in a project, and I have the following signature in my Makefile:
.PHONY: exec lint test
exec:
docker-compose exec service ${CMD}
lint: CMD := npm run lint
lint: exec
test: CMD := npm run test
test: exec
When I run the make lint test command I want it to run both npm run lint and npm run test inside the Docker container.
But as I observed it doesn't happen because make consider the prerequisite to be done after the lint task run and I get
make: Nothing to be done for 'test'.
message upon calling it. This is totally understandable from make's point of view, but it's a side-effect for my usage.
Is there a way to solve this inside the Makefile, without creating a shell script to act as an intermediate agent?
There is no way to get make to build the same target multiple times within a single invocation of make. That's just not how it works: it builds a thing, then expects it to be up to date for the rest of that session.
You can use recursive invocations of make to do what you want:
.PHONY: lint test exec
lint: CMD := npm run lint
test: CMD := npm run test
lint test:
$(MAKE) exec CMD=$(CMD)
exec:
docker-compose exec service ${CMD}
After getting inspiration from #madscientist and digging into the documentation I found what I was looking for: Canned Recipes allow to declare a list of commands to be reused in multiple tasks (recipes).
The following will satisfy the example from the question:
.PHONY: exec
define exec =
docker-compose exec service ${CMD}
endef
lint: CMD := npm run lint
lint:
$(exec)
test: CMD := npm run test
test:
$(exec)
While the solution from #madscientist can also work, I feel this is superior because it doesn't cause recursive make call and a task is not splitted into two pieces (assigning the CMD variable and calling the exec task)
I have following Makefile target defined:
.PHONY: docker-build
docker-build:
# Build Docker image
docker build \
--squash \
...
-t $(DOCKER_IMAGE):$(DOCKER_TAG) .
output:
#echo Docker Image: $(DOCKER_IMAGE):$(DOCKER_TAG)
I need to use the variables DOCKER_IMAGE and DOCKER_TAG as input for another script to run right after the make docker-build.
Do you have any idea how to do it? Thanks in advance.
I have tried many ways but can't get the output from Makefile to environment variables or even just to terminal.
how do i create a makefile that takes in 2 arguments?
myapp written in go, uses cobra cli. has a command that takes in 2 arguments(flags).
this works
$ go build; myapp mycmd --flag1=myvalue1 --flag2=myvalue2
in my make file i have
//makefile
run:
#echo Building and Running
$(GO) build -i -o myapp .
./myapp start $(ARGS)
so in CLI, when I try
$ make run ARGS=--flag1=arg1--flag2=arg2
or
$ make run ARGS=--flag1=arg1,--flag2=arg2
doesn't read in the flag values
how do i read in the 2 flag values, it only seems to read in 1 flag value.
make run ARGS=--flag1=arg1--flag2=arg2
Has no separator between the flags
make run ARGS=--flag1=arg1,--flag2=arg2
Cobra doesn't use ',' as a default flag separator.
Try:
make run ARGS='--flag1=arg1 --flag2=arg2'
Tried against a cobra CLI of my own, works perfectly.
I have a pretty straightforward setup..
- a Travis.yml file : https://github.com/openassistive/OpenATFrontEnd/blob/master/.travis.yml
which has this line:
before_script:
- go get -u -v github.com/spf13/hugo
but it fails - with
The command "eval go get -t -v ./..." failed. Retrying, 2 of 3.
(https://travis-ci.org/openassistive/OpenATFrontEnd/builds/166105574)
I can't figure it out. I see the language is set correctly - and looking at other SO posts the version number is correct. Is there a different version I should be using?
Read this, the go get .... is part of the default go build script on travis, if no makefile is found.
A simple solution may be to add a Makefile with an empty recipe
$ cat Makefile
target: ;
$ make && echo "ok"
make: « target » uptodate.
ok
So travis will set the default install step to true, which should avoid the got get