.PHONY: image tag forcetag show-tag check-dirty push forcepush
default: push

ORG?=linuxkit
SOURCE ?= .

ARCH := $(shell uname -m)

# Hash is of $(CURDIR) not $(CURDIR)$(SOURCE) to allow autogenerated
# source subdirectories (which would not be covered by ls-tree, but
# the code which autogenerates should be in $(CURDIR) so that is what
# we want to use.
ifeq ($(HASH),)
HASH_COMMIT?=HEAD # Setting this is only really useful with the show-tag target
HASH?=$(shell git ls-tree --full-tree $(HASH_COMMIT) -- $(CURDIR) | awk '{print $$3}')

ifneq ($(HASH_COMMIT),HEAD) # Others can't be dirty by definition
DIRTY:=$(shell git update-index -q --refresh && git diff-index --quiet HEAD -- $(CURDIR) || echo "-dirty")
endif

ifeq ($(ARCH), x86_64)
SUFFIX=-amd64
endif
ifeq ($(ARCH), aarch64)
SUFFIX=-arm64
endif

endif

# Makefiles can specify specific architectures they compile for. Default: all
ifeq ($(ARCHES),)
ARCHES:=x86_64 aarch64
endif

ifneq ($(filter $(ARCH),$(ARCHES)),)
REAL:=-y
else
REAL:=-n
endif

TAG:=$(ORG)/$(IMAGE):$(HASH)$(DIRTY)

REPO?=https://github.com/linuxkit/linuxkit
ifneq ($(REPO),)
REPO_LABEL=--label org.opencontainers.image.source=$(REPO)
endif
ifeq ($(DIRTY),)
REPO_COMMIT=$(shell git rev-parse HEAD)
COMMIT_LABEL=--label org.opencontainers.image.revision=$(REPO_COMMIT)
endif
LABELS=$(REPO_LABEL) $(COMMIT_LABEL)

BASE_DEPS=Dockerfile Makefile

# Get a release tag, if present
RELEASE:=$(shell git tag -l --points-at HEAD)

# Path to push-manifest.sh
PUSH_MANIFEST:=$(shell git rev-parse --show-toplevel)/scripts/push-manifest.sh

ifdef NETWORK
NET_OPT=
else
NET_OPT=--network=none
endif

ifeq ($(DOCKER_CONTENT_TRUST),)
ifndef NOTRUST
export DOCKER_CONTENT_TRUST=1
endif
endif

tag: tag$(REAL)
forcetag: forcetag$(REAL)
push: push$(REAL)
forcepush: forcepush$(REAL)

show-tag:
	@echo $(TAG)

tag-y: $(BASE_DEPS) $(DEPS)
	docker pull $(TAG)$(SUFFIX) || \
	docker build $(LABELS) $(NET_OPT) -t $(TAG)$(SUFFIX) $(SOURCE)

forcetag-y: $(BASE_DEPS) $(DEPS)
	docker build $(LABELS) $(NET_OPT) -t $(TAG)$(SUFFIX) $(SOURCE)

check-dirty:
ifneq ($(DIRTY),)
	$(error Your repository is not clean. Will not push package image)
endif
ifeq ($(SUFFIX),)
	$(error Refusing to push without a SUFFIX)
endif

push-y: tag-y check-dirty
	docker pull $(TAG)$(SUFFIX) || \
		(docker push $(TAG)$(SUFFIX) && \
		 $(PUSH_MANIFEST) $(TAG) $(DOCKER_CONTENT_TRUST))
ifneq ($(RELEASE),)
	docker tag $(TAG)$(SUFFIX) $(ORG)/$(IMAGE):$(RELEASE)$(SUFFIX)
	docker push $(ORG)/$(IMAGE):$(RELEASE)$(SUFFIX)
	$(PUSH_MANIFEST) $(ORG)/$(IMAGE):$(RELEASE) $(DOCKER_CONTENT_TRUST)
endif

forcepush-y: forcetag-y check-dirty
	docker push $(TAG)$(SUFFIX)
	$(PUSH_MANIFEST) $(TAG) $(DOCKER_CONTENT_TRUST)
ifneq ($(RELEASE),)
	docker tag $(TAG)$(SUFFIX) $(ORG)/$(IMAGE):$(RELEASE)
	docker push $(ORG)/$(IMAGE):$(RELEASE)$(SUFFIX)
	$(PUSH_MANIFEST) $(ORG)/$(IMAGE):$(RELEASE) $(DOCKER_CONTENT_TRUST)
endif

# If not supported for an arch, print a message
tag-n:
	$(info This package does not work on $(ARCH). Ignored)
forcetag-n:
	$(info This package does not work on $(ARCH). Ignored)
push-n:
	$(info This package does not work on $(ARCH). Ignored)
forcepush-n:
	$(info This package does not work on $(ARCH). Ignored)
