`cog_gov_search()` (and every other verb) used to fail with a cryptic `jsonlite` lexical error when the package's placeholder default URL was hit and the server returned an HTML welcome page that got cached as `manifest.json`. Three guards added: 1. `.check_url_configured()` aborts with class `uscogdata_url_not_configured` when the resolved URL is empty or still contains the `REPLACE_WITH_SHARE_TOKEN` sentinel. Message names both `Sys.setenv(USCOGDATA_URL = ...)` and `options(uscogdata.url = ...)` remediations and points at the bundled fixture. 2. `.fetch_or_cache_manifest()` parses the response body before persisting it. Non-JSON payloads raise class `uscogdata_invalid_manifest` (URL, Content-Type, parse error) and never touch the on-disk cache. 3. Cache writes are atomic via a sibling tempfile + `file.rename`, and existing caches with non-JSON content are silently refetched instead of returning a parse error to the caller. Local-path manifests that aren't valid JSON now surface the same `uscogdata_invalid_manifest` class with file context.
uscogdata
Curated R reader for the Civilytics US Census of Governments finance corpus.
Provides unit-level financial profiles, geographic rollups, and peer comparisons with auditable provenance and built-in cross-vintage correctness. Reads the published corpus (Hive-partitioned parquet + manifest.json) directly from Nextcloud via DuckDB httpfs — no local bulk downloads required.
Status
Under active development (Phase 2 of the cog_pipeline project). See
../cog_pipeline/docs/reader-specification.md for the reader contract this
package implements.
Installation
# pak::pkg_install("gitea.civilytics.org/Civilytics/uscogdata")
Configuration
USCOGDATA_URL— corpus root URL (public Nextcloud share, trailing slash)USCOGDATA_CACHE_DIR— optional override for the manifest cache directoryUSCOGDATA_MANIFEST_TTL_SECS— optional manifest re-fetch TTL (default 3600)
Developer notes
Testing
The package ships a bundled fixture corpus at inst/extdata/fixture_corpus/ —
a 3.6 MB two-year slice (2019 + 2020) of the full corpus covering all 50
states. tests/testthat/setup.R automatically points USCOGDATA_URL at this
fixture, so the full test suite runs offline with no network dependency:
devtools::test() # uses bundled fixture, no credentials required
Releasing against the live corpus
Before cutting a release, run the test suite against the published corpus to catch any drift between the fixture and the real data:
Sys.setenv(USCOGDATA_URL = "<published-corpus-url-with-trailing-slash>")
devtools::test()
When the live-corpus run is clean, strip the fixture from the built package by
adding this line to .Rbuildignore:
^inst/extdata/fixture_corpus$
The test suite is URL-agnostic — setup.R falls back to USCOGDATA_URL when
the bundled fixture is absent, so no test code changes are needed for the
release run or after stripping the fixture.