starter-kit/Makefile
Martin Pitt 5d2840449a Use Cockpit's shared static code checks
These will soon take over ESLint and stylelint, plus they also cover
ruff and other goodies for the Python part. This supersedes the explicit
ruff call.

This is already being used by cockpit-{podman,machines,navigator} etc.
2024-02-07 17:57:56 +01:00

196 lines
7.2 KiB
Makefile

# 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 = centos-8-stream
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
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 \
test/static-code \
$(NULL)
COCKPIT_REPO_URL = https://github.com/cockpit-project/cockpit.git
COCKPIT_REPO_COMMIT = bc12d5e116b56ebc5509fde7191a2ac5c09b1018 # 310.1 + 17 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= \
--add-comments=Translators: \
--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 '*.js' -o -name '*.jsx')
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' $< > $@
$(DIST_TEST): $(NODE_MODULES_TEST) $(COCKPIT_REPO_STAMP) $(shell find src/ -type f) package.json build.js
NODE_ENV=$(NODE_ENV) ./build.js
watch: $(NODE_MODULES_TEST) $(COCKPIT_REPO_STAMP)
NODE_ENV=$(NODE_ENV) ./build.js --watch
clean:
rm -rf dist/
rm -f $(SPEC)
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)"
dist: $(TARFILE)
@ls -1 $(TARFILE)
# when building a distribution tarball, call bundler with a 'production' environment
# we don't ship node_modules for license and compactness reasons; 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)
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 packaging/$(SPEC).in --exclude node_modules \
$$(git ls-files) $(COCKPIT_REPO_FILES) $(NODE_MODULES_TEST) $(SPEC) dist/
$(NODE_CACHE): $(NODE_MODULES_TEST)
tar --xz $(TAR_ARGS) -cf $@ node_modules
node-cache: $(NODE_CACHE)
# convenience target for developers
srpm: $(TARFILE) $(NODE_CACHE) $(SPEC)
rpmbuild -bs \
--define "_sourcedir `pwd`" \
--define "_srcrpmdir `pwd`" \
$(SPEC)
# convenience target for developers
rpm: $(TARFILE) $(NODE_CACHE) $(SPEC)
mkdir -p "`pwd`/output"
mkdir -p "`pwd`/rpmbuild"
rpmbuild -bb \
--define "_sourcedir `pwd`" \
--define "_specdir `pwd`" \
--define "_builddir `pwd`/rpmbuild" \
--define "_srcrpmdir `pwd`" \
--define "_rpmdir `pwd`/output" \
--define "_buildrootdir `pwd`/build" \
$(SPEC)
find `pwd`/output -name '*.rpm' -printf '%f\n' -exec mv {} . \;
rm -r "`pwd`/rpmbuild"
rm -r "`pwd`/output" "`pwd`/build"
# build a VM with locally built distro pkgs installed
# disable networking, VM images have mock/pbuilder with the common build dependencies pre-installed
$(VM_IMAGE): $(TARFILE) $(NODE_CACHE) bots test/vm.install
bots/image-customize --no-network --fresh \
--upload $(NODE_CACHE):/var/tmp/ --build $(TARFILE) \
--script $(CURDIR)/test/vm.install $(TEST_OS)
# 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)
# 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
# run the browser integration tests
# this will run all tests/check-* and format them as TAP
check: prepare-check
test/common/run-tests ${RUN_TESTS_OPTIONS}
codecheck: test/static-code $(NODE_MODULES_TEST)
test/static-code
# checkout Cockpit's bots for standard test VM images and API to launch them
bots: $(COCKPIT_REPO_STAMP)
test/common/make-bots
$(NODE_MODULES_TEST): package.json
# if it exists already, npm install won't update it; force that so that we always get up-to-date packages
rm -f package-lock.json
# unset NODE_ENV, skips devDependencies otherwise
env -u NODE_ENV npm install --ignore-scripts
env -u NODE_ENV npm prune
.PHONY: all clean install devel-install devel-uninstall print-version dist node-cache rpm prepare-check check vm print-vm