{{define "index.html"}} {{template "head" .}} {{template "topbar" .}}

AUR Report Card

Generated reports on the quality of PKGBUILDs in the Arch User Repository (AUR). Reports are generated by statically analyzing the PKGBUILD files using pkglint.

{{/* The counts carry data-stat so the script can redraw them for the repositories pressed below; as rendered they are the whole corpus, which is what a reader without the script gets. */}}
scanned
{{.Generated}}
packages
{{.Corpus.Total}}
findings
{{.Corpus.Findings}}
auto-fixable
{{.Corpus.Fixable}}
drifted
{{.Corpus.Drifted}}
Distributionn = {{.Corpus.Total}}
{{range .Corpus.Bands}} {{end}}
{{/* A disclosure rather than a standing section: the caveat matters, but it is read once and then in the way.
keeps it one click deep with no script. Before it, when the corpus has more than one source, the repositories as toggles: the pressed ones are what the numbers above, the bar and the roster show. Each carries its own tally in the JSON below so the script can sum any combination. */}}
{{if gt (len .Repos) 1}}
{{range .Repos}} {{end}}
{{end}}
What a grade means

The grade measures hygiene: are sources pinned to something that can't change underneath you, does the build stay off the network, and can a reader follow what the package does without running it? That is all it measures.

It is not a malware verdict. An F means read this PKGBUILD before you build it. An A means nothing stood out to a parser — not that the package is safe. Static analysis cannot catch a malicious upstream release pinned with a perfectly valid checksum.

See every rule and how each grade is derived.

Rostern = {{.Total}}
{{/* The roster has no maintainer column, so the box is where it says so. The "@" prefix is spelled out in the title and the label rather than the placeholder: the placeholder has to describe what typing does by default, and it is already as long as the field can hold. */}} {{if lt .Shown .Total}}{{.Shown}} of {{.Total}} packages{{else}}{{.Total}} packages{{end}}
{{template "rostertable" .}} {{/* The table above is the corpus's head, not the corpus, so say so and say where the rest is. With JavaScript the filter reaches every package once roster.json lands and site.js rewrites this line to match; the alphabetical pages are the answer that does not depend on it. The two cases are not cosmetic: a scan bounded by -budget can leave fewer packages than the table holds, and claiming to show "the 596 most-voted of 596" would describe a slice that isn't one. */}}

{{if lt .Shown .Total}}Showing the {{.Shown}} most-voted of {{.Total}} packages.{{else}}All {{.Total}} packages.{{end}} Browse {{if lt .Shown .Total}}all {{.Total}} {{end}}alphabetically.

{{end}}