1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
MAKEFLAGS += --no-builtin-rules --no-builtin-variables --warn-undefined-variables
unexport MAKEFLAGS
.DEFAULT_GOAL := all
.DELETE_ON_ERROR:
.SUFFIXES:
SHELL := bash
.SHELLFLAGS := -eu -o pipefail -c
escape = $(subst ','\'',$(1))
define noexpand
ifeq ($$(origin $(1)),environment)
$(1) := $$(value $(1))
endif
ifeq ($$(origin $(1)),environment override)
$(1) := $$(value $(1))
endif
ifeq ($$(origin $(1)),command line)
override $(1) := $$(value $(1))
endif
endef
.PHONY: DO
DO:
PROJECT := cgitize
# Target platforms (used by buildx):
PLATFORMS := linux/amd64,linux/armhf
# Docker Hub credentials:
DOCKER_USERNAME := egortensin
ifdef DOCKER_PASSWORD
$(eval $(call noexpand,DOCKER_PASSWORD))
endif
.PHONY: all
all: build
.PHONY: login
login:
ifndef DOCKER_PASSWORD
$(error Please define DOCKER_PASSWORD)
endif
@echo '$(call escape,$(DOCKER_PASSWORD))' | docker login --username '$(call escape,$(DOCKER_USERNAME))' --password-stdin
.PHONY: build
# Build natively by default.
build: compose/build
.PHONY: clean
clean:
docker system prune --all --force --volumes
.PHONY: push
# Push multi-arch images by default.
push: buildx/push
.PHONY: check-build
check-build:
ifndef FORCE
$(warning Going to build natively; consider `docker buildx build` instead)
endif
.PHONY: check-push
check-push:
ifndef FORCE
$(error Please use `docker buildx build --push` instead)
endif
.PHONY: compose/build
# `docker-compose build` has week support for multiarch repos (you need to use
# multiple Dockerfile's, create a manifest manually, etc.), so it's only here
# for testing purposes, and native builds.
compose/build: check-build
docker-compose build
.PHONY: compose/push
# `docker-compose push` would replace the multiarch repo with a single image by
# default (you'd have to create a manifest and push it instead), so it's only
# here for testing purposes.
compose/push: check-push compose/build
docker-compose push
.PHONY: buildx/create
buildx/create:
docker buildx create --use --name '$(call escape,$(PROJECT))_builder'
.PHONY: buildx/rm
buildx/rm:
docker buildx rm '$(call escape,$(PROJECT))_builder'
.PHONY: buildx/build
buildx/build:
docker buildx build -t '$(call escape,$(DOCKER_USERNAME))/$(call escape,$(PROJECT))' -f docker/Dockerfile --platform '$(call escape,$(PLATFORMS))' --progress plain .
.PHONY: buildx/push
buildx/push:
docker buildx build -t '$(call escape,$(DOCKER_USERNAME))/$(call escape,$(PROJECT))' -f docker/Dockerfile --platform '$(call escape,$(PLATFORMS))' --progress plain --push .
venv_dir := .venv
.PHONY: venv-reset
venv-reset:
rm -rf -- '$(call escape,$(venv_dir))'
mkdir -p -- '$(call escape,$(venv_dir))'
python -m venv -- '$(call escape,$(venv_dir))'
.PHONY: venv
venv: venv-reset
. '$(call escape,$(venv_dir))/bin/activate' && pip install -r requirements.txt
# Is there a better way?
.PHONY: venv-update
venv-update: venv-reset
. '$(call escape,$(venv_dir))/bin/activate' \
&& pip install . \
&& pip uninstall --yes "$$( python setup.py --name )" \
&& pip freeze > requirements.txt
.PHONY: py
py: python
.PHONY: repl
repl: python
.PHONY: python
python:
. '$(call escape,$(venv_dir))/bin/activate' && python
.PHONY: test
test:
. '$(call escape,$(venv_dir))/bin/activate' && python -m unittest --verbose --buffer
|