Repository navigation
Expand file tree
/
Copy pathactions.mk
More file actions
123 lines (109 loc) · 6.79 KB
/
Copy pathactions.mk
File metadata and controls
123 lines (109 loc) · 6.79 KB
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
# actions.mk — dynamic target generation for verb+modifier pattern
#
# Usage — define a recipe block, then register it:
#
# define build.frontend
# @echo "Building frontend..."
# bun run build
# endef
# $(call register,build,frontend)
#
# With prerequisites:
# $(call register,build,frontend,$(_HIDE)stamp.frontend)
#
# Then declare the verb to wire everything up:
# $(call declare_verb,build)
# ── Modifier-to-flag mapping ────────────────────────────────
$(_HIDE)FLAG_frontend := $($(_HIDE)WANT_FRONTEND)
$(_HIDE)FLAG_backend := $($(_HIDE)WANT_BACKEND)
$(_HIDE)FLAG_website := $($(_HIDE)WANT_WEBSITE)
$(_HIDE)FLAG_booklets := $($(_HIDE)WANT_BOOKLETS)
$(_HIDE)FLAG_cf := $($(_HIDE)WANT_CF)
$(_HIDE)FLAG_github := $($(_HIDE)WANT_GITHUB)
$(_HIDE)FLAG_aio := $($(_HIDE)WANT_AIO)
$(_HIDE)FLAG_pages := $($(_HIDE)WANT_PAGES)
$(_HIDE)FLAG_e2e := $($(_HIDE)WANT_E2E)
$(_HIDE)FLAG_dist := $($(_HIDE)WANT_CLEAN_DIST)
$(_HIDE)FLAG_repo := $($(_HIDE)WANT_CLEAN_REPO)
$(_HIDE)FLAG_version := $($(_HIDE)WANT_VERSION)
$(_HIDE)FLAG_actions := $($(_HIDE)WANT_ACTIONS)
$(_HIDE)FLAG_packages := $($(_HIDE)WANT_PACKAGES)
$(_HIDE)FLAG_secrets := $($(_HIDE)WANT_SECRETS)
$(_HIDE)FLAG_lint := $($(_HIDE)WANT_LINT)
$(_HIDE)FLAG_gate := $($(_HIDE)WANT_GATE)
$(_HIDE)FLAG_tests := $($(_HIDE)WANT_TESTS)
$(_HIDE)FLAG_coverage := $($(_HIDE)WANT_COVERAGE)
$(_HIDE)FLAG_summary := $($(_HIDE)WANT_SUMMARY)
$(_HIDE)FLAG_dependabot := $($(_HIDE)WANT_DEPENDABOT)
$(_HIDE)FLAG_tree := $($(_HIDE)WANT_TREE)
$(_HIDE)FLAG_history := $($(_HIDE)WANT_HISTORY)
$(_HIDE)FLAG_licenses := $($(_HIDE)WANT_LICENSES)
$(_HIDE)FLAG_modrot := $($(_HIDE)WANT_MODROT)
$(_HIDE)FLAG_semgrep := $($(_HIDE)WANT_SEMGREP)
$(_HIDE)FLAG_codeql := $($(_HIDE)WANT_CODEQL)
$(_HIDE)FLAG_sarif := $($(_HIDE)WANT_SARIF)
$(_HIDE)FLAG_upload := $($(_HIDE)WANT_UPLOAD)
$(_HIDE)FLAG_tag := $($(_HIDE)WANT_TAG)
$(_HIDE)FLAG_untag := $($(_HIDE)WANT_UNTAG)
$(_HIDE)FLAG_line := $($(_HIDE)WANT_LINE)
$(_HIDE)FLAG_cert := $($(_HIDE)WANT_CERT)
# Known modifiers — the set checked during validation in declare_verb
$(_HIDE)KNOWN_MODS := frontend backend website booklets cf github aio pages e2e dist repo version actions packages secrets lint gate tests coverage summary dependabot tree history licenses modrot semgrep codeql sarif upload tag untag line cert
# Known verbs — populated by declare_verb, checked for collisions
$(_HIDE)KNOWN_VERBS :=
# ── register(verb,modifier,[prereqs]) ───────────────────────
# Generates hidden target via $(eval). The $(_HIDE) prefix on
# generated target names hides them from tab completion.
define $(_HIDE)register_impl
.PHONY: $(_HIDE)$1.$2
$(_HIDE)$1.$2: $3
$$($1.$2)
$(_HIDE)DEPS_$1 += $$(if $$($(_HIDE)FLAG_$2),$(_HIDE)$1.$2)
$(_HIDE)VALID_MODS_$1 += $2
$(_HIDE)ALL_MODS += $2
$(_HIDE)REGISTRY += $1.$2
endef
register = $(if $(filter $(strip $2),$($(_HIDE)KNOWN_VERBS)),$(warning COLLISION: modifier '$(strip $2)' in 'register($(strip $1),$(strip $2))' is also a declared verb — 'make $(strip $1) $(strip $2)' will run both))$(eval $(call $(_HIDE)register_impl,$(strip $1),$(strip $2),$(strip $3)))
# ── register_always(verb,modifier,[prereqs]) ─────────────────
# Like register, but the target is always created (no flag check)
# and the modifier is NOT added to VALID_MODS or REGISTRY.
# Use for targets with custom wiring (e.g., clean.release, dump.version).
# If the modifier is flag-gated, pair with allow() to suppress warnings.
define $(_HIDE)register_always_impl
.PHONY: $(_HIDE)$1.$2
$(_HIDE)$1.$2: $3
$$($1.$2)
endef
register_always = $(eval $(call $(_HIDE)register_always_impl,$(strip $1),$(strip $2),$(strip $3)))
# ── allow(verb,modifier) ─────────────────────────────────────
# Mark a modifier as valid for a verb without creating a recipe.
# Use when the modifier affects behavior through variables rather
# than adding a distinct target (e.g., cf forces linux/amd64 for build).
allow = $(eval $(_HIDE)VALID_MODS_$(strip $1) += $(strip $2))
# ── require_tool(name,hint) ──────────────────────────────────
# Hard-fail a recipe with a consistent message if `name` isn't on PATH.
# hint is free text describing how to install it.
require_tool = @which $(strip $1) > /dev/null 2>&1 || (echo "$(strip $1) not installed. $(strip $2)" >&2 && exit 1)
# ── Modifier validation ──────────────────────────────────────
# Called inside declare_verb and declare_verb_default. Emits a
# parse-time warning for each modifier typed on the command line that
# is not registered or allowed for this verb. A modifier only turned on
# by another verb's default (build alone means frontend + backend) is
# not the user's, so `make build release cf` must not warn that release
# takes no frontend.
$(_HIDE)check_mods = $(if $(filter $1,$(MAKECMDGOALS)),$(foreach mod,$($(_HIDE)KNOWN_MODS),$(if $(and $(filter $(mod),$(MAKECMDGOALS)),$($(_HIDE)FLAG_$(mod)),$(if $(filter $(mod),$($(_HIDE)VALID_MODS_$1)),,x)),$(warning WARNING: 'make $1 $(mod)' — '$(mod)' is not a valid modifier for '$1' (ignored)))))
# ── declare_verb(verb) ──────────────────────────────────────
define $(_HIDE)declare_verb_impl
.PHONY: $1
$1: $$($(_HIDE)DEPS_$1)
endef
declare_verb = $(if $(filter $(strip $1),$($(_HIDE)KNOWN_MODS) $($(_HIDE)ALL_MODS)),$(warning COLLISION: verb '$(strip $1)' in 'declare_verb($(strip $1))' is also a registered modifier — 'make <verb> $(strip $1)' will conflict))$(eval $(_HIDE)KNOWN_VERBS += $(strip $1))$(call $(_HIDE)check_mods,$(strip $1))$(eval $(call $(_HIDE)declare_verb_impl,$(strip $1)))
# ── declare_verb_default(verb,default_dep) ──────────────────
# Like declare_verb, but runs default_dep when no flag-gated deps
# are active. Use for verbs like clean where the bare invocation
# should have a sensible default action.
define $(_HIDE)declare_verb_default_impl
.PHONY: $1
$1: $$($(_HIDE)DEPS_$1) $$(if $$(strip $$($(_HIDE)DEPS_$1)),,$(strip $2))
endef
declare_verb_default = $(if $(filter $(strip $1),$($(_HIDE)KNOWN_MODS) $($(_HIDE)ALL_MODS)),$(warning COLLISION: verb '$(strip $1)' in 'declare_verb_default($(strip $1))' is also a registered modifier — 'make <verb> $(strip $1)' will conflict))$(eval $(_HIDE)KNOWN_VERBS += $(strip $1))$(call $(_HIDE)check_mods,$(strip $1))$(eval $(call $(_HIDE)declare_verb_default_impl,$(strip $1),$(strip $2)))