refactor: 각 어댑터터별 리펙토링 진행

This commit is contained in:
DongHyeonka
2026-08-24 18:26:40 +09:00
parent e98b56eb03
commit 0137263441
439 changed files with 31935 additions and 4719 deletions
+71
View File
@@ -0,0 +1,71 @@
# build-logic
The included build that holds this repository's Gradle conventions. A convention lives here when the
same machine code was otherwise copied into more than one place, and the copies could drift apart
without any check noticing.
## What is here
| Plugin | Owns |
| --- | --- |
| `ca.architecture-registry` (settings) | project inclusion, directory mapping, and the parsed registry every other reader shares |
| `ca.strict-test-lane` | tagged / named / own-source-set Test lanes that cannot pass without executing something |
| `ca.strict-qualification` | qualification lanes that cannot pass without executing every named class, re-checked against the JUnit XML |
| `ca.evidence` | the JUnit XML reader and the no-skip / required-class rules built on it |
| `ca.api-surface` | read-only API surface verification with an explicit, separate update task |
| `ca.testkit-publisher` | a leaf's testkit source set consumers and its optional consumable artifact |
| `ca.dependency-policy` | declared absences, checked against the resolved graph rather than against a comment |
| `ca.runtime-membership` | the resolved runtime project closure against the registry's memberships |
`dev.caskeleton.buildlogic.ModuleRegistry` and `JUnitEvidence` are plain classes rather than plugins,
because settings and projects load plugins through different mechanisms and both need them.
## What the design named and this build does not have
The remediation design's §10.2 listed eight conventions. Two of them were attempted or assessed and
deliberately not built, and the reasons belong next to the code rather than in a review thread.
### `ca.java-leaf` — reverted
Written, measured, reverted. The full reasoning is in `src/build.gradle` beside the static-analysis
block it would have moved. In short: a recorded decision (`feature-static-analysis-quality-contract`
D8) already put that baseline in the root `subprojects {}` block; the block is applied once and
copied nowhere, so extracting it removes no duplication; and build-logic would have to re-declare the
spotless / spotbugs / errorprone / dependency-management coordinates *and their versions*, which
creates a drift surface where there was none.
A content-level baseline of the resolved analysis configuration — compiler args, encoding, release,
Checkstyle tool version and config, SpotBugs effort and report level, for every source set of every
project — was captured before the attempt and compared after the revert, because the task graph
cannot see a weakened Error Prone flag: the task names are identical either way. The two dumps are
identical.
### `ca.optional-adapter` — not warranted
Its stated responsibility was "activation metadata and disabled/on composition contract wiring".
Neither half is build machine code in this repository:
- Activation metadata is one registry, `docs/registries/env-keys.yaml`, verified by one root task,
`verifyEnvKeys`. There is no per-leaf copy for a convention to deduplicate.
- The off invariant and the on fail-closed contract are ordinary tests over the shared `test` source
set, gated by the master switch in `@ConditionalOnProperty` at runtime. They need no source set,
no configuration, and no task of their own.
A plugin here would have to invent state to hold — an `optionalAdapter { switch = '...' }` block that
no build step reads — and a declaration nothing checks is worse than no declaration, because it reads
like a guarantee.
## Testing a convention
```bash
cd src
./gradlew -p build-logic test --console=plain
```
The lane and registry conventions are covered by Gradle TestKit against real builds rather than by
reading the plugin source, because the properties that matter — a lane that discovers nothing fails,
a lane never reports up-to-date, a malformed registry is refused before any project is included — are
runtime behaviour rather than text in a script. Two of those tests exist because the obvious reading
of the Gradle documentation was wrong: `failOnNoDiscoveredTests` does not fire when a tag filter
matches nothing, and `failOnNoMatchingTests` does not fire when only *some* of the named tests are
missing.