first commit
This commit is contained in:
commit
1354db6c39
90 files changed
+13123
No files matched your search
@@ -0,0 +1,150 @@
|
||||
#!make
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright (C) 2026 Bryan Joshua Pedini
|
||||
|
||||
# makefile for skeptical-updater: install, lint and test targets.
|
||||
# Plain GNU make + bash + Docker (+ curl once, for `make vendor`); no other tooling.
|
||||
# `make` or `make help` lists the targets. Tests run entirely in Docker containers.
|
||||
|
||||
SHELL := /bin/bash
|
||||
.SHELLFLAGS := -eu -o pipefail -c
|
||||
.ONESHELL:
|
||||
.NOTPARALLEL:
|
||||
.DEFAULT_GOAL := help
|
||||
MAKEFLAGS += --no-print-directory
|
||||
|
||||
APPLET := skeptical-updater
|
||||
PREFIX ?= /usr/local
|
||||
DESTDIR ?=
|
||||
|
||||
# ---- vendored test tooling, pinned --------------------------------------------
|
||||
# To bump: set the new tag and the sha256sum of its GitHub tag tarball
|
||||
# (https://github.com/bats-core/<repo>/archive/refs/tags/v<version>.tar.gz),
|
||||
# then `rm -rf tests/vendor && make vendor`.
|
||||
BATS_VERSION := 1.14.0
|
||||
BATS_SHA256 := bb537b70b15b732f6d8827dd6578e3d8ce166636ce1f18ea9a074184fcce9177
|
||||
BATS_SUPPORT_VERSION := 0.3.0
|
||||
BATS_SUPPORT_SHA256 := 7815237aafeb42ddcc1b8c698fc5808026d33317d8701d5ec2396e9634e2918f
|
||||
BATS_ASSERT_VERSION := 2.2.4
|
||||
BATS_ASSERT_SHA256 := e305df20c4c36cba4570e10f1cd824efb1ae71d88b5ef474550781ebee04192f
|
||||
BATS_GITHUB := https://github.com/bats-core
|
||||
VENDOR := tests/vendor
|
||||
BATS := $(VENDOR)/bats-core/bin/bats
|
||||
|
||||
# ---- tests ----------------------------------------------------------------------
|
||||
SHELLCHECK_IMAGE ?= koalaman/shellcheck:stable
|
||||
UNIT_IMAGE ?= debian:12
|
||||
E2E_IMAGES ?= tests/docker/images.txt
|
||||
E2E_ONLY ?=
|
||||
E2E_FAIL_FAST ?= 0
|
||||
|
||||
# discovery/ is frozen reference material (not shellcheck-clean, never edited): not linted.
|
||||
LINT_FILES := $(wildcard $(APPLET) tests/docker/*.sh tests/e2e/*.sh tests/e2e/fixtures/*.sh \
|
||||
tests/e2e/*.bash tests/e2e/*.bats tests/unit/*.bash tests/unit/*.bats \
|
||||
tests/unit/fakes/*.bash tests/unit/fakes/*/* tests/unit/data/rpm/db.bash)
|
||||
|
||||
# $(call fetch,<repo>,<version>,<sha256>,<file that must exist>)
|
||||
# Download github.com/bats-core/<repo> tag v<version> with curl into a temp dir,
|
||||
# verify its sha256 and that <file> was extracted, then move it to tests/vendor/<repo>.
|
||||
define fetch
|
||||
tmp=$$(mktemp -d "$${TMPDIR:-/tmp}/skeptical-updater-vendor.XXXXXX")
|
||||
trap 'rm -rf -- "$$tmp"' EXIT
|
||||
url="$(BATS_GITHUB)/$(1)/archive/refs/tags/v$(2).tar.gz"
|
||||
echo "vendor: $(1) v$(2) <- $$url"
|
||||
curl -fsSL --retry 3 --proto '=https' -o "$$tmp/src.tar.gz" "$$url"
|
||||
if ! echo "$(3) $$tmp/src.tar.gz" | sha256sum -c --status -; then echo "vendor: $(1) v$(2): sha256 mismatch (expected $(3))" >&2; exit 1; fi
|
||||
mkdir -- "$$tmp/src"
|
||||
tar -xzf "$$tmp/src.tar.gz" -C "$$tmp/src"
|
||||
if [[ ! -f "$$tmp/src/$(1)-$(2)/$(4)" ]]; then echo "vendor: $(1) v$(2): $(4) not found in the tarball" >&2; exit 1; fi
|
||||
mkdir -p -- "$(VENDOR)"
|
||||
rm -rf -- "$(VENDOR)/$(1)"
|
||||
mv -- "$$tmp/src/$(1)-$(2)" "$(VENDOR)/$(1)"
|
||||
echo "$(1) v$(2) sha256:$(3) $$url" >"$(VENDOR)/$(1)/.vendored"
|
||||
echo "vendor: $(1) v$(2) -> $(VENDOR)/$(1)"
|
||||
endef
|
||||
|
||||
.PHONY: help install uninstall lint vendor docker-snapshot docker-cleanup docker-cleanup-dry-run \
|
||||
test test-no-cleanup test-unit test-e2e clean
|
||||
|
||||
help: ## show this help (default target)
|
||||
@echo "usage: make <target> [VAR=value ...]"
|
||||
echo
|
||||
echo "targets:"
|
||||
grep -hE '^[A-Za-z0-9_.-]+:.*## ' $(MAKEFILE_LIST) | awk -F ':.*## ' '{ printf " %-24s %s\n", $$1, $$2 }'
|
||||
echo
|
||||
echo "variables:"
|
||||
echo " PREFIX=$(PREFIX) DESTDIR=$(DESTDIR) install location"
|
||||
echo " E2E_ONLY=<label>[,<label>...] run only these labels of $(E2E_IMAGES)"
|
||||
echo " E2E_FAIL_FAST=1 stop test-e2e at the first failing distro"
|
||||
|
||||
install: ## install skeptical-updater as DESTDIR/PREFIX/bin/skeptical-updater, mode 0755
|
||||
install -d -m 0755 "$(DESTDIR)$(PREFIX)/bin"
|
||||
install -m 0755 $(APPLET) "$(DESTDIR)$(PREFIX)/bin/$(APPLET)"
|
||||
|
||||
uninstall: ## remove DESTDIR/PREFIX/bin/skeptical-updater (the statefile in /var/lib is kept)
|
||||
rm -f -- "$(DESTDIR)$(PREFIX)/bin/$(APPLET)"
|
||||
|
||||
lint: ## shellcheck (in Docker) the applet, the test scripts, fixtures and fakes
|
||||
ifeq ($(strip $(LINT_FILES)),)
|
||||
@echo "lint: no shell files to check"
|
||||
else
|
||||
docker run --rm -v "$(CURDIR)":/mnt:ro $(SHELLCHECK_IMAGE) $(LINT_FILES)
|
||||
endif
|
||||
|
||||
vendor: $(BATS) $(VENDOR)/bats-support/load.bash $(VENDOR)/bats-assert/load.bash ## download pinned bats-core, bats-support, bats-assert to tests/vendor (once)
|
||||
|
||||
$(BATS):
|
||||
@$(call fetch,bats-core,$(BATS_VERSION),$(BATS_SHA256),bin/bats)
|
||||
|
||||
$(VENDOR)/bats-support/load.bash:
|
||||
@$(call fetch,bats-support,$(BATS_SUPPORT_VERSION),$(BATS_SUPPORT_SHA256),load.bash)
|
||||
|
||||
$(VENDOR)/bats-assert/load.bash:
|
||||
@$(call fetch,bats-assert,$(BATS_ASSERT_VERSION),$(BATS_ASSERT_SHA256),load.bash)
|
||||
|
||||
docker-snapshot: ## record the Docker image set (never overwrites; re-baseline: tests/docker/snapshot.sh --force)
|
||||
tests/docker/snapshot.sh
|
||||
|
||||
docker-cleanup: ## restore the Docker image set to the snapshot (re-tag stolen tags, remove new images)
|
||||
tests/docker/cleanup.sh
|
||||
|
||||
docker-cleanup-dry-run: ## print what docker-cleanup would do, without changing anything
|
||||
tests/docker/cleanup.sh --dry-run
|
||||
|
||||
test: docker-snapshot ## test-unit + test-e2e, then ALWAYS docker-cleanup; exits with the tests' status
|
||||
@status=0
|
||||
trap 'status=130' INT TERM
|
||||
$(MAKE) test-unit test-e2e || status=$$?
|
||||
trap - INT TERM
|
||||
echo "== test: restoring the Docker image set (tests exited with status $$status) =="
|
||||
$(MAKE) docker-cleanup || { rc=$$?; if (( status == 0 )); then status=$$rc; fi; }
|
||||
exit $$status
|
||||
|
||||
test-no-cleanup: docker-snapshot test-unit test-e2e ## same as test but keep pulled images (iterate; run docker-cleanup when done)
|
||||
|
||||
test-unit: vendor ## run tests/unit/*.bats with the vendored bats in a debian:12 container
|
||||
docker run --rm -i -v "$(CURDIR)":/work:ro -w /work \
|
||||
-e SKEPTICAL_UPDATER_STATE_DIR=/tmp/su-state \
|
||||
$(UNIT_IMAGE) bash $(BATS) --tap tests/unit
|
||||
|
||||
test-e2e: vendor ## run the E2E suite in each distro of tests/docker/images.txt (E2E_ONLY, E2E_FAIL_FAST)
|
||||
@only="$(strip $(E2E_ONLY))"
|
||||
only=",$${only//[[:space:]]/,},"
|
||||
ran=0
|
||||
failed=()
|
||||
while read -r -u 3 label image _ || [[ -n "$${label:-}" ]]; do
|
||||
case "$$label" in ''|'#'*) continue ;; esac
|
||||
if [[ "$$only" != ",," && "$$only" != *",$$label,"* ]]; then continue; fi
|
||||
if [[ -z "$${image:-}" ]]; then echo "test-e2e: $(E2E_IMAGES): no image for label '$$label'" >&2; exit 1; fi
|
||||
ran=$$((ran + 1))
|
||||
if ! tests/docker/run-e2e.sh "$$label" "$$image" </dev/null; then
|
||||
failed+=("$$label")
|
||||
if [[ "$(E2E_FAIL_FAST)" == 1 ]]; then echo "test-e2e: E2E_FAIL_FAST=1: stopping after $$label" >&2; break; fi
|
||||
fi
|
||||
done 3<"$(E2E_IMAGES)"
|
||||
if (( ran == 0 )); then echo "test-e2e: no label in $(E2E_IMAGES) matches E2E_ONLY='$(E2E_ONLY)'" >&2; exit 1; fi
|
||||
if (( $${#failed[@]} )); then echo "test-e2e: $${#failed[@]} of $$ran distro(s) FAILED: $${failed[*]} (logs: tests/docker/logs/)" >&2; exit 1; fi
|
||||
echo "test-e2e: all $$ran distro(s) passed"
|
||||
|
||||
clean: ## remove tests/docker/logs and .bats-tmp (never tests/vendor, never the Docker snapshot)
|
||||
rm -rf -- tests/docker/logs .bats-tmp
|
||||
Reference in new issue
Block a user