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
# COPR invokes this as: make -f .copr/Makefile srpm outdir=<dir>
#
# IMPORTANT: COPR runs this inside MOCK, not a plain container, and mock redefines rpm's
# %{_topdir} to /builddir/build. An earlier version called `rpmdev-setuptree` and then
# copied into $(HOME)/rpmbuild/SPECS -- which is where the tree lands in a plain container
# and is NOT where it lands under mock, so the copy failed with 'No such file or
# directory'. Verifying it in a container therefore proved nothing about COPR.
#
# This version does not depend on %{_topdir}, $(HOME), or a source tree existing at all:
# it points _sourcedir and _srcrpmdir explicitly, so the environment cannot move them.
#
# WHAT CHANGED, AND WHY IT MATTERS HERE
# -------------------------------------
# packaging/copr/retch.spec is now a TEMPLATE: its Version: is `@VERSION@` and its Source0
# is a local tarball. This recipe supplies both, from the checkout COPR cloned:
#
# version <- Cargo.toml, via scripts/render_packaging.py
# Source0 <- an archive of this checkout
#
# Neither needs a published tag or a network fetch, which is what lets a PR build its own
# SRPM -- previously impossible, because Source0 pinned a tag tarball that does not exist
# until after a release, so CI could only ever build the PREVIOUS release's source.
#
# HOW THE SOURCE ARCHIVE IS BUILT, AND THE TRAP THAT DECIDED IT
# -------------------------------------------------------------
# `git archive` when there is a repository to ask, plain `tar` otherwise. The fallback is
# not cosmetic: whether COPR's mock buildroot carries `.git` alongside the checkout is not
# something this repo can verify without a COPR build, so the recipe works either way and
# PRINTS which path it took -- the first COPR build after this lands answers it from its log.
#
# The reason the fallback needs explicit excludes is a measured trap: **GNU tar's
# `--exclude-vcs-ignores` does not implement .gitignore semantics.** Given this repo's
# .gitignore it excluded `WIP.md` (a bare filename) and silently kept `memory/` (directory
# form) and `/target` (anchored form) -- so the first version of this recipe packed the
# private cross-machine handoff log and the auto-memory directory into the SRPM, where they
# would have reached the published -debugsource package. The excludes are also written
# WITHOUT a leading `./`, which is the second half of the same trap: `--exclude=./__pycache__`
# anchors at the top level and silently kept `scripts/__pycache__/`. Comparing the two paths'
# listings is what found both. An SRPM is published and cannot be
# recalled, which is why the guard below is a hard failure rather than a warning, and why it
# also asserts the four files whose ABSENCE would be just as bad: no Cargo.lock means
# unpinned resolution, and no LICENSE/NOTICE means a GPL+MIT obligation shipped unmet.
#
# The guard has already corrected this file's author once, in the other direction:
# `.claude/settings.json` is TRACKED (only `settings.local.json` is ignored), so it is in
# every GitHub tag tarball the AUR and Homebrew already build from. Excluding it here would
# have made COPR's source differ from the released one, so it is deliberately not in the
# must-not-ship list -- the list names things git does not track, not things that look
# internal.
SPEC_IN :=
BUILD :=
RENDER :=
:
: