cross-cleaner

LOW
maintainer nekiplay 1 votes scanned 2026-10-17 07:17:15.137327
View on AUR
Why flagged

Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.

Triggered rules

Low Few votes, recently uploaded zero_votes_recent

Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.

PKGBUILD

1# Maintainer: Roman <roman at users.noreply.github.com>
2# Based on upstream packaging by the Cross-Cleaner authors.
3#
4# NOTE: the license in this repository (the packaging files) is 0BSD, per the
5# AUR submission guidelines. The packaged software itself is GPL-3.0-or-later,
6# which is what the license= field below refers to.
7
8# Built from source with the distribution package's own flags, mirroring the
9# reasoning in packaging/linux/nfpm.yaml: the package manager owns the installed
10# version, so every binary is compiled with --no-default-features and the
11# self-update path is not part of the build at all. `crates/desktop`,
12# `crates/tui` and `crates/cli` each document this in their own Cargo.toml.
13
14pkgname=cross-cleaner
15# The tag archive, not a `git+` source: a VCS source always tracks the default
16# branch, so every user would build whatever main happened to contain at that
17# moment instead of the release that was actually published. With an archive,
18# the version below names exactly one commit.
19#
20# The four lines between the markers are the whole of what
21# .github/workflows/aur.yml rewrites, and the block deliberately contains
22# nothing else -- regenerating it must not delete the explanation around it.
23# ---AUR-VERSION-BEGIN---
24pkgver=2.0.4.4
25pkgrel=1.1
26source=("cross-cleaner-v${pkgver}.tar.gz::https://github.com/Cross-Cleaner/Cross-Cleaner/archive/refs/tags/v${pkgver}.tar.gz")
27sha256sums=('86e98f694c97f518e573c267add2873fc91a751b7905a4a374d326b35b745af5')
28# ---AUR-VERSION-END---
29pkgdesc='Addon-style system cleanup tool that removes temporary files, cache and other system junk'
30arch=('x86_64' 'aarch64')
31url='https://github.com/Cross-Cleaner/Cross-Cleaner'
32license=('GPL-3.0-or-later')
33# ~636 crates in the lock file, all of them needed by the window app. Without a
34# lower bound the resolver picks a version the sources have never been built
35# against; with one, an Arch update that breaks the build is a visible bisect
36# rather than a silent surprise.
37depends=('gcc-libs'
38 'alsa-lib'
39 'mesa'
40 'libdrm'
41 'wayland'
42 'wayland-protocols'
43 'libx11'
44 'libxcursor'
45 'libxrandr'
46 'libxi'
47 'libxinerama'
48 'libxrender'
49 'libxext'
50 'libxkbcommon'
51 'libxkbcommon-x11'
52 'fontconfig')
53# rust, cargo, git, pkgconf and make are base-devel members and so are not
54# listed here; they are named above only to record why the build needs them.
55makedepends=('icoutils'
56 'desktop-file-utils'
57 'appstream'
58 # alsa-sys, khronos-egl and wayland-sys all resolve their native
59 # libraries through pkg-config at compile time, so the -dev side of
60 # each has to be present while building, not only afterwards.
61 'alsa-lib'
62 'mesa'
63 'wayland')
64optdepends=('gtk-update-icon-cache: update the icon cache without restarting the session')
65
66# No pkgver() function. The version is pinned to one git tag by the source line
67# above, so there is nothing left to compute at build time -- and a pkgver()
68# function is exactly what made this package unusable as an AUR package before:
69# it resolved against whatever the clone happened to contain, which drifted
70# from the pkgver= line the AUR web interface displays.
71
72# GitHub's tag archives extract into a directory named after the tag without
73# its leading `v`. Set once here so prepare(), build() and package() all agree.
74_srcdir_tag="Cross-Cleaner-${pkgver}"
75
76prepare() {
77 cd "$srcdir/$_srcdir_tag"
78
79 # crates/winicon/assets/icon.ico holds a single 96px frame, so this is a
80 # straight extraction rather than a resize. Unlike the AppImage build, which
81 # upscales to 128 and 256 with ImageMagick, nothing is invented here: the
82 # one real size is installed as-is. Dropping a >=512px master PNG into
83 # crates/winicon/assets is what makes the larger hicolor slots worth filling.
84 #
85 # Extraction goes to a throwaway directory rather than straight to
86 # $srcdir/icons: prepare() has to be idempotent, because makepkg reuses an
87 # existing $srcdir whenever only the PKGBUILD changed. Writing the frame
88 # next to its destination and then `mv`-ing it onto itself fails the second
89 # time round, with "mv: ... and ... are the same file".
90 local extract
91 extract=$(mktemp -d)
92 icotool -x -o "$extract" crates/winicon/assets/icon.ico
93 # icotool names its output after the source and the frame's geometry, so
94 # glob rather than hardcode the name.
95 local frame
96 frame=$(find "$extract" -name '*.png' -print -quit)
97 if [[ -z "$frame" ]]; then
98 rm -rf "$extract"
99 printf 'icotool extracted no frame from icon.ico\n' >&2
100 return 1
101 fi
102 install -Dm644 "$frame" "$srcdir/icons/cross-cleaner.png"
103 rm -rf "$extract"
104
105 # Make the binaries report this package's version.
106 #
107 # `--version` comes from CARGO_PKG_VERSION, and cargo takes that from the
108 # `version` field of each crate's [package] table. It is not overridable
109 # from the environment -- exporting CARGO_PKG_VERSION before the build
110 # changes nothing, verified on cargo 1.98.
111 #
112 # The values in the tree are whatever the release happened to leave there,
113 # and they disagree with the tag: crates/*/Cargo.toml says 2.0.1 while the
114 # tag this package is built from is 2.0.4.2.5. The cause is upstream --
115 # dev_build.yml rewrote every Cargo.toml back to a hardcoded 2.0.1 on each
116 # push while release.yml wrote the real version, so the two ping-ponged and
117 # each tag inherited whichever it landed on (v2.0.4.2.4 reports 2.0.1,
118 # v2.0.4.2.5 reports 2.0.4).
119 #
120 # Rewriting only the [package] table, not every `version = ` line: a
121 # dependency declared as
122 # [dependencies.foo]
123 # version = "1"
124 # is legal TOML and a plain /^version = / would rewrite that too, silently
125 # changing which version of a dependency is required.
126 # The release version has four components (2.0.4.2.5) but a cargo package
127 # version is semver: exactly three numeric components, optionally followed
128 # by -pre or +build. Passing four in is a hard parse error, which is why
129 # release.yml does the same `cut -d. -f1-3`. So the application reports
130 # 2.0.4 for a 2.0.4.2.5 package: the fourth component has no representation
131 # inside the binary and cannot be recovered from one.
132 local crate_version
133 crate_version=$(printf '%s' "$pkgver" | cut -d. -f1-3)
134 if ! printf '%s' "$crate_version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
135 printf 'pkgver %s does not reduce to a semver version (%s)\n' "$pkgver" "$crate_version" >&2
136 return 1
137 fi
138
139 find "$srcdir/$_srcdir_tag" -name Cargo.toml -print0 |
140 while IFS= read -r -d '' manifest; do
141 awk -v v="$crate_version" '
142 /^\[package\]/ { inpkg = 1 }
143 /^\[/ && !/^\[package\]/ { inpkg = 0 }
144 inpkg && /^version[[:space:]]*=/ && !seen {
145 print "version = \"" v "\""
146 seen = 1
147 next
148 }
149 { print }
150 ' "$manifest" > "$manifest.tmp" && mv "$manifest.tmp" "$manifest"
151 done
152
153 # The three components alone are not the release version, so the string the
154 # binaries print is set outright. clap takes it from CARGO_PKG_VERSION when
155 # the attribute says a bare `version,`, and that can only ever hold three
156 # semver numbers. Replacing the bare form with an explicit literal is what
157 # makes `cross-cleaner-cli --version` read 2.0.4.2.5 for a 2.0.4.2.5
158 # package.
159 #
160 # The patch is verified rather than assumed: if upstream moves the clap
161 # attribute, sed would quietly match nothing and the binaries would fall
162 # back to reporting 2.0.4 with no error anywhere. Each file is checked
163 # after the substitution, so that regression fails the build loudly.
164 #
165 # Two shapes have to be covered, and both appear upstream today: a bare
166 # `version,` line inside a multi-line #[command(...)] (cli/src/args.rs) and
167 # `#[command(version, about, ...)]` on one line (tui and desktop).
168 local manifest
169 for manifest in \
170 crates/cli/src/args.rs \
171 crates/tui/src/main.rs \
172 crates/desktop/src/main.rs
173 do
174 [[ -f "$srcdir/$_srcdir_tag/$manifest" ]] || {
175 printf 'expected %s to exist; upstream moved it\n' "$manifest" >&2
176 return 1
177 }
178 sed -i \
179 -e "s/^\([[:space:]]*\)version,$/\1version = \"$pkgver\",/" \
180 -e "s/#\[command(version, /#[command(version = \"$pkgver\", /" \
181 "$srcdir/$_srcdir_tag/$manifest"
182 grep -q "version = \"$pkgver\"," "$srcdir/$_srcdir_tag/$manifest" || {
183 printf 'could not set the version string in %s\n' "$manifest" >&2
184 return 1
185 }
186 done
187
188 # packaging/linux/cross-cleaner.appdata.xml carries %%VERSION%% and %%DATE%%
189 # for the release workflow to fill in. The date cannot come from the
190 # commit here: the source is a tag archive, not a git checkout, so there is
191 # no .git to ask. The build date is used instead, which is the only moment
192 # this package knows about.
193 local release_date
194 release_date=$(date -u +%Y-%m-%d)
195 sed -e "s/%%VERSION%%/$pkgver/g" \
196 -e "s/%%DATE%%/$release_date/g" \
197 packaging/linux/cross-cleaner.appdata.xml > "$srcdir/cross-cleaner.appdata.xml"
198 if grep -q '%%' "$srcdir/cross-cleaner.appdata.xml"; then
199 printf 'unsubstituted placeholder left in the AppStream metadata\n' >&2
200 return 1
201 fi
202
203 desktop-file-validate packaging/linux/cross-cleaner.desktop
204 desktop-file-validate packaging/linux/cross-cleaner-tui.desktop
205 # Non-fatal, matching the release workflow: a metadata lint should be
206 # visible without being able to block an install.
207 appstreamcli validate --pedantic "$srcdir/cross-cleaner.appdata.xml" || :
208}
209
210# One cargo invocation per binary, as .github/workflows/release.yml does it.
211build() {
212 cd "$srcdir/$_srcdir_tag"
213
214 # Unset the compiler flags makepkg exports, and tell rustc not to read a
215 # rustflags setting from anywhere. Arch's CFLAGS
216 #
217 # -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions
218 # -Wp,-D_FORTIFY_SOURCE=3 -fstack-clash-protection -fcf-protection ...
219 #
220 # are handed to the `cc` crate, which passes them straight to the C compiler
221 # that ring's build.rs uses for its crypto core. At least one of them makes
222 # that build produce objects whose symbols the final link cannot resolve,
223 # and the whole binary then fails to link:
224 #
225 # ld.lld: error: undefined symbol: ring_core_0_17_14__x25519_sc_mask
226 # ld.lld: error: undefined symbol: ring_core_0_17_14__aes_nohw_set_encrypt_key
227 # ... every symbol of ring's native core
228 #
229 # ring's own build.rs output is correct throughout -- it emits both
230 # `rustc-link-lib=static=ring_core_0_17_14_` and `rustc-link-search`, and
231 # the archive really does contain all 157 symbols. What breaks is the link
232 # step, which sees the `-L` search path but not the `-l`.
233 #
234 # Verified by bisection on a reduced crate (ureq -> rustls -> ring): the
235 # build passes with makepkg's CFLAGS removed and fails with them set, while
236 # LTO, RUSTFLAGS, LDFLAGS and the rest of makepkg's environment are all
237 # neutral. Note this is NOT upstream's fat LTO profile causing it -- the
238 # release profile in Cargo.toml builds these binaries fine on Ubuntu.
239 #
240 # Clearing the variables is also the more correct behaviour for a package:
241 # these are the distribution's hardening flags for distribution-built
242 # software, not something a third-party package should silently inherit.
243 unset CFLAGS CXXFLAGS CPPFLAGS FCFLAGS FFLAGS ARFLAGS LDFLAGS LTOFLAGS
244 unset RUSTFLAGS CARGO_ENCODED_RUSTFLAGS
245
246 # No --locked. The Cargo.lock committed in the release tags is stale with
247 # respect to the manifests in those same tags: tag v2.0.4.2.5 declares
248 # version = "2.0.4" in crates/*/Cargo.toml while its Cargo.lock still records
249 # the workspace crates at 2.0.1, so cargo insists on rewriting the lock and
250 # --locked aborts the build before anything is compiled.
251 #
252 # The thing --locked was here to protect still holds without it. Cargo.lock
253 # already pins gpu-allocator to a concrete git revision through
254 # Cargo.toml's [patch.crates-io], and cargo does not revisit entries that
255 # are present and still satisfy the manifests -- the only edits it makes are
256 # the workspace version numbers above. Upstream's own release builds do not
257 # pass --locked either.
258 cargo build --release --no-default-features -p desktop
259 cargo build --release --no-default-features -p tui
260 cargo build --release --no-default-features -p cli
261}
262
263# No check() on purpose. The workspace release profile sets panic = "abort",
264# which is not what the test harness wants, and the android crate in the
265# workspace needs the NDK to build at all. The upstream CI does not run
266# `cargo test` either, so there is no suite this package would be able to run
267# that CI is not already running.
268package() {
269 cd "$srcdir/$_srcdir_tag"
270
271 # cargo names each binary after its package. They are renamed to
272 # hyphenated commands so the desktop entries and the AppImage agree with
273 # this package: Exec lines and shell completions must not change per release.
274 install -Dm755 target/release/desktop "$pkgdir/usr/bin/cross-cleaner"
275 install -Dm755 target/release/tui "$pkgdir/usr/bin/cross-cleaner-tui"
276 install -Dm755 target/release/cli "$pkgdir/usr/bin/cross-cleaner-cli"
277
278 install -Dm644 packaging/linux/cross-cleaner.desktop \
279 "$pkgdir/usr/share/applications/cross-cleaner.desktop"
280 install -Dm644 packaging/linux/cross-cleaner-tui.desktop \
281 "$pkgdir/usr/share/applications/cross-cleaner-tui.desktop"
282
283 install -Dm644 "$srcdir/icons/cross-cleaner.png" \
284 "$pkgdir/usr/share/icons/hicolor/96x96/apps/cross-cleaner.png"
285
286 install -Dm644 "$srcdir/cross-cleaner.appdata.xml" \
287 "$pkgdir/usr/share/metainfo/cross-cleaner.appdata.xml"
288}
289

Changes since previous scan

--- PKGBUILD @ 2026-10-17 00:21
+++ PKGBUILD @ 2026-10-17 07:17
@@ -22,7 +22,7 @@
# nothing else -- regenerating it must not delete the explanation around it.
# ---AUR-VERSION-BEGIN---
pkgver=2.0.4.4
-pkgrel=1
+pkgrel=1.1
source=("cross-cleaner-v${pkgver}.tar.gz::https://github.com/Cross-Cleaner/Cross-Cleaner/archive/refs/tags/v${pkgver}.tar.gz")
sha256sums=('86e98f694c97f518e573c267add2873fc91a751b7905a4a374d326b35b745af5')
# ---AUR-VERSION-END---

Scan history

Scanned at (UTC)SeverityRules
2026-10-17 07:17:15 Low 1
2026-10-17 00:21:55 Clean 2
2026-10-16 15:16:11 Low 1
2026-10-14 00:06:47 Clean 2
2026-10-13 11:16:23 Low 1
2026-10-11 00:26:05 Clean 2
2026-10-10 14:14:18 Low 1
2026-10-10 10:13:47 Low 1
2026-10-10 08:13:38 Low 1

Report a package

Reports go to the AURWatch maintainer (one person) and are read by hand. No login required.

0 / 4000
Your suggestion