Deterministically diffs two sitemap_audit() objects component-by-component
and reports which rows were added, removed, or changed. Built for CI drift
monitoring (e.g. a scheduled job that flags when a site's sitemap audit
changes): comparing an audit to an identically-recomputed copy of itself
always yields an empty diff.
Value
A sitemap_audit_diff: a classed list whose components element
holds, for each of urls, findings, sources, problems, and tree, a
list of added, removed, and changed tibbles (each carrying the
component's columns, deterministically ordered by key). Use
audit_unchanged() to test whether anything changed, and summary() for a
per-component count table.
Details
Rows are matched by a stable identity key, never by position, so shuffling a
component's rows never produces a diff. Keys are: loc for urls;
requested_url for sources; sitemap_url + parent_sitemap + depth for
tree; and the whole row for findings and problems (a finding present in
one audit and not the other is added/removed).
Change detection ignores run-varying metadata so re-running the same audit
does not show spurious diffs: the elapsed-fetch column sources$timing is
excluded from the comparison. All other columns are deterministic content and
are compared.
See also
sitemap_audit() for the compared container, and
audit_unchanged() for the "did anything change?" predicate.
Examples
base <- paste0(
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
"<url><loc>https://example.com/</loc></url>",
"<url><loc>https://example.com/a</loc></url></urlset>"
)
moved <- paste0(
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
"<url><loc>https://example.com/</loc></url>",
"<url><loc>https://example.com/b</loc></url></urlset>"
)
p1 <- tempfile(fileext = ".xml")
p2 <- tempfile(fileext = ".xml")
writeLines(base, p1)
writeLines(moved, p2)
old <- sitemap_audit(urls = read_sitemap(p1))
new <- sitemap_audit(urls = read_sitemap(p2))
d <- compare_sitemap_audits(old, new)
d
#> <sitemap_audit_diff>
#> urls +1 -1 ~1
#> findings +0 -0 ~0
#> sources +1 -1 ~0
#> problems +0 -0 ~0
#> tree +0 -0 ~0
summary(d)
#> # A tibble: 5 × 4
#> component added removed changed
#> <chr> <int> <int> <int>
#> 1 urls 1 1 1
#> 2 findings 0 0 0
#> 3 sources 1 1 0
#> 4 problems 0 0 0
#> 5 tree 0 0 0
# An audit compared with itself has an empty diff.
audit_unchanged(compare_sitemap_audits(old, old))
#> [1] TRUE