Skip to content

Add the labelsync sentinel errors, KindOf, and the XDG paths - #49

Merged
Ilyes512 merged 6 commits into
mainfrom
feat/GH-12-labelsync-sentinels-xdg
Aug 7, 2026
Merged

Ilyes512 merged 6 commits into
mainfrom
feat/GH-12-labelsync-sentinels-xdg

Conversation

@Ilyes512

@Ilyes512 Ilyes512 commented Aug 6, 2026 •

Copy link
Copy Markdown
Member

Summary

  • internal/labelsync/errors.go: all 18 sentinels from the design's error table, plus KindOf mapping each to its stable kind string — the error_kind contract for JSON output.
  • internal/labelsync/configuration.go: ConfigDir and CacheDir over github.com/adrg/xdg, plus the labels.yml / labels.yaml constants and the ordered ConfigFileNames.
  • Table-driven tests: every sentinel round-trips, is recognised through three layers of fmt.Errorf("%w"), and kinds are unique.
  • docs/design.md now states the %w wrapping rule and what adding a sentinel costs, and task test runs with -race to match CI.

Keeping the sentinel table honest

The coverage test originally compared len(allSentinels) against a hardcoded 18, which is exactly as easy to forget to bump as the table itself is to update — and a removal paired with an addition would keep the count right while the table went wrong.

declaredSentinels now parses the package's own non-test files with go/parser and collects every exported package-level Err* variable, so the expected set comes from errors.go rather than a constant. The check runs both ways:

  • declared in the package but missing from allSentinels
  • listed in allSentinels but no longer declared

Reflection cannot enumerate package-level vars, so the table gained a name column to compare against. A t.Fatal guards the empty-glob case, so a broken working directory cannot quietly turn the test into a no-op.

Verified by temporarily adding a sentinel to errors.go and watching the test fail with the expected message.

Closes #12

All 18 sentinels from the design's error table land at once, even though
most have no call site yet: downstream packages import them constantly and
drip-feeding them would churn every in-flight branch.

KindOf maps each to its stable kind string, which is a public contract —
it is rendered as error_kind in JSON output. Tests cover the round-trip
for every sentinel, recognition through three layers of fmt.Errorf("%w"),
uniqueness of the kind strings, and "" for nil and unrelated errors.
ConfigDir and CacheDir resolve $XDG_CONFIG_HOME/labelsync and
$XDG_CACHE_HOME/labelsync via github.com/adrg/xdg. The labels.yml and
labels.yaml constants, plus the ordered ConfigFileNames, give the config
loader the two spellings it must search and the pair it must reject as
ambiguous.
The error table already listed the sentinels, but not the rule that makes
them work: wrap with %w, never render with %v or rebuild the error, or
both errors.Is and KindOf stop matching.
CI runs go test -race; the local task did not, so a data race could pass
locally and fail on the PR.
@Ilyes512
Ilyes512 force-pushed the feat/GH-12-labelsync-sentinels-xdg branch from 58b9f34 to 4b390d6 Compare August 7, 2026 15:27
TestKindOf_CoversEverySentinel checked len(allSentinels) against a
hardcoded 18, which is exactly as easy to forget to bump as the table
itself is to update — and a removal paired with an addition kept the
count right while the table went wrong.

declaredSentinels parses the package's own non-test files with go/parser
and collects every exported package-level Err* variable, so the expected
set now comes from errors.go. The check runs both ways: declared but
untabled, and tabled but no longer declared. Reflection cannot enumerate
package-level vars, so the table gained a name column to compare against.
The error table said what the sentinels are, not what adding one costs.
Three places have to move together — the table, KindOf, and allSentinels
— and the test now parses the package source to enforce the third, so
say so next to the table where someone adding a sentinel will read it.
@Ilyes512
Ilyes512 merged commit 8c62a7f into main Aug 7, 2026
5 checks passed
@Ilyes512
Ilyes512 deleted the feat/GH-12-labelsync-sentinels-xdg branch August 7, 2026 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

internal/labelsync: sentinel errors, KindOf, and XDG paths

1 participant