-
Notifications
You must be signed in to change notification settings - Fork 90
/
Makefile
212 lines (172 loc) · 8.26 KB
/
Makefile
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# extract name from package.json
PACKAGE_NAME := $(shell awk '/"name":/ {gsub(/[",]/, "", $$2); print $$2}' package.json)
RPM_NAME := cockpit-$(PACKAGE_NAME)
VERSION := $(shell T=$$(git describe 2>/dev/null) || T=1; echo $$T | tr '-' '.')
ifeq ($(TEST_OS),)
TEST_OS = fedora-41
endif
export TEST_OS
TARFILE=$(RPM_NAME)-$(VERSION).tar.xz
NODE_CACHE=$(RPM_NAME)-node-$(VERSION).tar.xz
SPEC=$(RPM_NAME).spec
PREFIX ?= /usr/local
APPSTREAMFILE=org.cockpit_project.$(PACKAGE_NAME).metainfo.xml
VM_IMAGE=$(CURDIR)/test/images/$(TEST_OS)
# stamp file to check for node_modules/
NODE_MODULES_TEST=package-lock.json
# one example file in dist/ from bundler to check if that already ran
DIST_TEST=dist/manifest.json
# one example file in pkg/lib to check if it was already checked out
COCKPIT_REPO_STAMP=pkg/lib/cockpit-po-plugin.js
# common arguments for tar, mostly to make the generated tarballs reproducible
TAR_ARGS = --sort=name --mtime "@$(shell git show --no-patch --format='%at')" --mode=go=rX,u+rw,a-s --numeric-owner --owner=0 --group=0
VM_CUSTOMIZE_FLAGS =
# the following scenarios need network access
ifeq ("$(TEST_SCENARIO)","updates-testing")
VM_CUSTOMIZE_FLAGS += --run-command 'dnf -y update --setopt=install_weak_deps=False --enablerepo=updates-testing >&2'
else ifeq ("$(TEST_SCENARIO)","podman-next")
VM_CUSTOMIZE_FLAGS += --run-command 'dnf -y copr enable rhcontainerbot/podman-next >&2; dnf -y update --repo "copr*" >&2'
else
# default scenario does not install packages
VM_CUSTOMIZE_FLAGS += --no-network
endif
ifeq ($(TEST_COVERAGE),yes)
RUN_TESTS_OPTIONS+=--coverage
NODE_ENV=development
endif
all: $(DIST_TEST)
# checkout common files from Cockpit repository required to build this project;
# this has no API stability guarantee, so check out a stable tag when you start
# a new project, use the latest release, and update it from time to time
COCKPIT_REPO_FILES = \
pkg/lib \
test/common \
tools/node-modules \
$(NULL)
COCKPIT_REPO_URL = https://github.com/cockpit-project/cockpit.git
COCKPIT_REPO_COMMIT = 35090b743b6b4536fc9c09cd9644c1c3b53c1cb2 # 330 + 76 commits
$(COCKPIT_REPO_FILES): $(COCKPIT_REPO_STAMP)
COCKPIT_REPO_TREE = '$(strip $(COCKPIT_REPO_COMMIT))^{tree}'
$(COCKPIT_REPO_STAMP): Makefile
@git rev-list --quiet --objects $(COCKPIT_REPO_TREE) -- 2>/dev/null || \
git fetch --no-tags --no-write-fetch-head --depth=1 $(COCKPIT_REPO_URL) $(COCKPIT_REPO_COMMIT)
git archive $(COCKPIT_REPO_TREE) -- $(COCKPIT_REPO_FILES) | tar x
#
# i18n
#
LINGUAS=$(basename $(notdir $(wildcard po/*.po)))
po/$(PACKAGE_NAME).js.pot:
xgettext --default-domain=$(PACKAGE_NAME) --output=- --language=C --keyword= \
--keyword=_:1,1t --keyword=_:1c,2,2t --keyword=C_:1c,2 \
--keyword=N_ --keyword=NC_:1c,2 \
--keyword=gettext:1,1t --keyword=gettext:1c,2,2t \
--keyword=ngettext:1,2,3t --keyword=ngettext:1c,2,3,4t \
--keyword=gettextCatalog.getString:1,3c --keyword=gettextCatalog.getPlural:2,3,4c \
--from-code=UTF-8 $$(find src/ -name '*.[jt]s' -o -name '*.[jt]sx') | \
sed '/^#/ s/, c-format//' > $@
po/$(PACKAGE_NAME).html.pot: $(NODE_MODULES_TEST) $(COCKPIT_REPO_STAMP)
pkg/lib/html2po.js -o $@ $$(find src -name '*.html')
po/$(PACKAGE_NAME).manifest.pot: $(NODE_MODULES_TEST) $(COCKPIT_REPO_STAMP)
pkg/lib/manifest2po.js src/manifest.json -o $@
po/$(PACKAGE_NAME).metainfo.pot: $(APPSTREAMFILE)
xgettext --default-domain=$(PACKAGE_NAME) --output=$@ $<
po/$(PACKAGE_NAME).pot: po/$(PACKAGE_NAME).html.pot po/$(PACKAGE_NAME).js.pot po/$(PACKAGE_NAME).manifest.pot po/$(PACKAGE_NAME).metainfo.pot
msgcat --sort-output --output-file=$@ $^
po/LINGUAS:
echo $(LINGUAS) | tr ' ' '\n' > $@
#
# Build/Install/dist
#
$(SPEC): packaging/$(SPEC).in $(NODE_MODULES_TEST)
provides=$$(npm ls --omit dev --package-lock-only --depth=Infinity | grep -Eo '[^[:space:]]+@[^[:space:]]+' | sort -u | sed 's/^/Provides: bundled(npm(/; s/\(.*\)@/\1)) = /'); \
awk -v p="$$provides" '{gsub(/%{VERSION}/, "$(VERSION)"); gsub(/%{NPM_PROVIDES}/, p)}1' $< > $@
packaging/arch/PKGBUILD: packaging/arch/PKGBUILD.in
sed 's/VERSION/$(VERSION)/; s/SOURCE/$(TARFILE)/' $< > $@
packaging/debian/changelog: packaging/debian/changelog.in
sed 's/VERSION/$(VERSION)/' $< > $@
$(DIST_TEST): $(COCKPIT_REPO_STAMP) $(shell find src/ -type f) package.json build.js
$(MAKE) package-lock.json && NODE_ENV=$(NODE_ENV) ./build.js
watch: $(NODE_MODULES_TEST)
NODE_ENV=$(NODE_ENV) ./build.js -w
clean:
rm -rf dist/
rm -f $(SPEC) packaging/arch/PKGBUILD packaging/debian/changelog
rm -f po/LINGUAS
install: $(DIST_TEST) po/LINGUAS
mkdir -p $(DESTDIR)$(PREFIX)/share/cockpit/$(PACKAGE_NAME)
cp -r dist/* $(DESTDIR)$(PREFIX)/share/cockpit/$(PACKAGE_NAME)
mkdir -p $(DESTDIR)$(PREFIX)/share/metainfo/
msgfmt --xml -d po \
--template $(APPSTREAMFILE) \
-o $(DESTDIR)$(PREFIX)/share/metainfo/$(APPSTREAMFILE)
# this requires a built source tree and avoids having to install anything system-wide
devel-install: $(DIST_TEST)
mkdir -p ~/.local/share/cockpit
ln -s `pwd`/dist ~/.local/share/cockpit/$(PACKAGE_NAME)
# assumes that there was symlink set up using the above devel-install target,
# and removes it
devel-uninstall:
rm -f ~/.local/share/cockpit/$(PACKAGE_NAME)
print-version:
@echo "$(VERSION)"
# required for running integration tests
TEST_NPMS = \
node_modules/sizzle \
$(NULL)
dist: $(TARFILE)
@ls -1 $(TARFILE)
# when building a distribution tarball, call bundler with a 'production' environment by default
# we don't ship most node_modules for license and compactness reasons, only the ones necessary for running tests
# we ship a pre-built dist/ (so it's not necessary) and ship package-lock.json (so that node_modules/ can be reconstructed if necessary)
$(TARFILE): export NODE_ENV ?= production
$(TARFILE): $(DIST_TEST) $(SPEC) packaging/arch/PKGBUILD packaging/debian/changelog
if type appstream-util >/dev/null 2>&1; then appstream-util validate-relax --nonet *.metainfo.xml; fi
tar --xz $(TAR_ARGS) -cf $(TARFILE) --transform 's,^,$(RPM_NAME)/,' \
--exclude '*.in' --exclude test/reference \
$$(git ls-files | grep -v node_modules) \
$(COCKPIT_REPO_FILES) $(NODE_MODULES_TEST) $(SPEC) $(TEST_NPMS) \
packaging/arch/PKGBUILD packaging/debian/changelog dist/
# convenience target for developers
rpm: $(TARFILE)
rpmbuild -tb --define "_topdir $(CURDIR)/tmp/rpmbuild" $(TARFILE)
find tmp/rpmbuild -name '*.rpm' -printf '%f\n' -exec mv {} . \;
rm -r tmp/rpmbuild
# build a VM with locally built distro pkgs installed
$(VM_IMAGE): $(TARFILE) packaging/debian/rules packaging/debian/control packaging/arch/PKGBUILD bots
# HACK for ostree images: skip the rpm build/install
if [ "$${TEST_OS%coreos}" != "$$TEST_OS" ] || [ "$${TEST_OS%bootc}" != "$$TEST_OS" ] || [ "$$TEST_OS" = "rhel4edge" ]; then \
bots/image-customize --verbose --fresh --no-network $(VM_CUSTOMIZE_FLAGS) \
--run-command 'mkdir -p /usr/local/share/cockpit' \
--upload dist/:/usr/local/share/cockpit/podman \
--script $(CURDIR)/test/vm.install $(TEST_OS); \
else \
bots/image-customize --verbose --fresh $(VM_CUSTOMIZE_FLAGS) --build $(TARFILE) \
--script $(CURDIR)/test/vm.install $(TEST_OS); \
fi
# convenience target for the above
vm: $(VM_IMAGE)
@echo $(VM_IMAGE)
# convenience target to print the filename of the test image
print-vm:
@echo $(VM_IMAGE)
# run static code checks for python code
PYEXEFILES=$(shell git grep -lI '^#!.*python')
codecheck: test/common $(NODE_MODULES_TEST)
test/common/static-code
# convenience target to setup all the bits needed for the integration tests
# without actually running them
prepare-check: $(NODE_MODULES_TEST) $(VM_IMAGE) test/common test/reference
# run the browser integration tests; skip check for SELinux denials
# this will run all tests/check-* and format them as TAP
check: prepare-check
TEST_AUDIT_NO_SELINUX=1 test/common/run-tests ${RUN_TESTS_OPTIONS}
bots: $(COCKPIT_REPO_STAMP)
test/common/make-bots
test/reference: test/common
test/common/pixel-tests pull
# We want tools/node-modules to run every time package-lock.json is requested
# See https://www.gnu.org/software/make/manual/html_node/Force-Targets.html
FORCE:
$(NODE_MODULES_TEST): FORCE tools/node-modules
tools/node-modules make_package_lock_json
.PHONY: all clean install devel-install devel-uninstall print-version dist rpm prepare-check check vm print-vm