ToolOwnedTierHandler.java
package network.ike.plugin.scaffold;
import java.nio.file.Path;
import java.util.Arrays;
/**
* Tier handler for {@link ScaffoldTier#TOOL_OWNED}.
*
* <p>Policy: publish always overwrites. The file is intended to be
* reproduced verbatim from the template; any user edits are discarded.
* Divergence is surfaced in draft output as telemetry but never blocks
* publish.
*
* <p>Produces:
* <ul>
* <li>{@link TierAction.UpToDate} when the on-disk bytes already
* match the template;</li>
* <li>{@link TierAction.Write} with
* {@link TierAction.Write.Kind#INSTALL INSTALL} when the file is
* absent;</li>
* <li>{@link TierAction.Write} with
* {@link TierAction.Write.Kind#UPDATE UPDATE} otherwise.</li>
* </ul>
*/
public final class ToolOwnedTierHandler implements TierHandler {
/**
* Construct a stateless tool-owned tier handler. Instances are
* safe to share across planning calls; all per-invocation state
* lives on method parameters.
*/
public ToolOwnedTierHandler() {
}
@Override
public ScaffoldTier tier() {
return ScaffoldTier.TOOL_OWNED;
}
@Override
public TierAction plan(
ManifestEntry entry,
Path resolvedDest,
byte[] currentContent,
byte[] templateContent,
LockfileEntry priorEntry) {
if (templateContent == null) {
throw new ScaffoldException(
"tool-owned entry '" + entry.dest()
+ "' has no template content");
}
String templateSha = Sha256.of(templateContent);
if (currentContent != null
&& Arrays.equals(currentContent, templateContent)) {
return new TierAction.UpToDate(
entry, resolvedDest, templateSha, templateSha,
"up to date");
}
TierAction.Write.Kind kind = currentContent == null
? TierAction.Write.Kind.INSTALL
: TierAction.Write.Kind.UPDATE;
String reason = switch (kind) {
case INSTALL -> "install";
case UPDATE -> currentContent != null
&& priorEntry != null
&& !Sha256.of(currentContent)
.equals(priorEntry.appliedSha() != null
? priorEntry.appliedSha()
: priorEntry.templateSha())
? "overwrite (user-edited; tool-owned)"
: "refresh";
case REVERT -> "revert";
};
return new TierAction.Write(
entry, resolvedDest, templateContent,
templateSha, templateSha, kind, reason);
}
}