first commit
This commit is contained in:
147
docs/devtools/tooling/installer/src/host/host.md
Normal file
147
docs/devtools/tooling/installer/src/host/host.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# `host`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs --> - conflict — Resolves the per-op `conflict` policy on…
|
||||
- [apply](./apply/apply.md) — <!-- begin:auto-docs --> _(no submodules)_- conflict — Resolves the per-op `conflict` policy on…
|
||||
- [conflict](./apply/conflict.md) — Resolves the per-op `conflict` policy on a target that already exists. Five policies are supported: `error` (raise `APP…
|
||||
- [json-merge](./apply/json-merge.md) — Implements the deep-merge semantics used by `patch-json` ops with `conflict: "merge"`. Match the conventions of `@suave…
|
||||
- [text-patch](./apply/text-patch.md) — Applies an ordered sequence of `TextEdit`s to a string. Used by `patch-text` ops to make targeted insertions/deletions/…
|
||||
- [detect](./detect.md) — Runs a plugin's optional `detect` stage inside an OpenTelemetry span. The plugin reports what is already present in the…
|
||||
- [host](./host.md) — <!-- begin:auto-docs --> _(no submodules)_- conflict — Resolves the per-op `conflict` policy on…
|
||||
- [plan](./plan.md) — Invokes `plugin.plan(answers, ctx)` and validates the returned `FileOp[]` against `FileOpsSchema` before letting them f…
|
||||
- [post-install](./post-install.md) — Runs the plugin's optional `postInstall` stage with abort propagation. This is where plugins do follow-up work that doe…
|
||||
- [prompts](./prompts.md) — Runs the plugin's optional `prompts` stage and validates the answers against the schema the plugin returns. This is whe…
|
||||
- conflict — Resolves the per-op `conflict` policy on…
|
||||
|
||||
- [apply](./apply/apply.md) — <!-- begin:auto-docs --> _(no submodules)_- conflict — Resolves the per-op `conflict` policy on…
|
||||
- [conflict](./apply/conflict.md) — Resolves the per-op `conflict` policy on a target that already exists. Five policies are supported: `error` (raise `APP…
|
||||
- [json-merge](./apply/json-merge.md) — Implements the deep-merge semantics used by `patch-json` ops with `conflict: "merge"`. Match the conventions of `@suave…
|
||||
- [text-patch](./apply/text-patch.md) — Applies an ordered sequence of `TextEdit`s to a string. Used by `patch-text` ops to make targeted insertions/deletions/…
|
||||
- [detect](./detect.md) — Runs a plugin's optional `detect` stage inside an OpenTelemetry span. The plugin reports what is already present in the…
|
||||
- [host](./host.md) — <!-- begin:auto-docs --> _(no submodules)_- conflict — Resolves the per-op `conflict` policy on…
|
||||
- [plan](./plan.md) — Invokes `plugin.plan(answers, ctx)` and validates the returned `FileOp[]` against `FileOpsSchema` before letting them f…
|
||||
- [post-install](./post-install.md) — Runs the plugin's optional `postInstall` stage with abort propagation. This is where plugins do follow-up work that doe…
|
||||
- [prompts](./prompts.md) — Runs the plugin's optional `prompts` stage and validates the answers against the schema the plugin returns. This is whe…
|
||||
|
||||
- conflict — Resolves the per-op `conflict` policy on…
|
||||
|
||||
- [apply](./apply/apply.md) — <!-- begin:auto-docs --> _(no submodules)_- conflict — Resolves the per-op `conflict` policy on…
|
||||
- [conflict](./apply/conflict.md) — Resolves the per-op `conflict` policy on a target that already exists. Five policies are supported: `error` (raise `APP…
|
||||
- [json-merge](./apply/json-merge.md) — Implements the deep-merge semantics used by `patch-json` ops with `conflict: "merge"`. Match the conventions of `@suave…
|
||||
- [text-patch](./apply/text-patch.md) — Applies an ordered sequence of `TextEdit`s to a string. Used by `patch-text` ops to make targeted insertions/deletions/…
|
||||
- [detect](./detect.md) — Runs a plugin's optional `detect` stage inside an OpenTelemetry span. The plugin reports what is already present in the…
|
||||
- [host](./host.md) — <!-- begin:auto-docs --> _(no submodules)_- conflict — Resolves the per-op `conflict` policy on…
|
||||
- [plan](./plan.md) — Invokes `plugin.plan(answers, ctx)` and validates the returned `FileOp[]` against `FileOpsSchema` before letting them f…
|
||||
- [post-install](./post-install.md) — Runs the plugin's optional `postInstall` stage with abort propagation. This is where plugins do follow-up work that doe…
|
||||
- [prompts](./prompts.md) — Runs the plugin's optional `prompts` stage and validates the answers against the schema the plugin returns. This is whe…
|
||||
|
||||
- conflict — Resolves the per-op `conflict` policy on…
|
||||
|
||||
- [apply](./apply/apply.md) — <!-- begin:auto-docs --> _(no submodules)_- conflict — Resolves the per-op `conflict` policy on…
|
||||
- [conflict](./apply/conflict.md) — Resolves the per-op `conflict` policy on a target that already exists. Five policies are supported: `error` (raise `APP…
|
||||
- [json-merge](./apply/json-merge.md) — Implements the deep-merge semantics used by `patch-json` ops with `conflict: "merge"`. Match the conventions of `@suave…
|
||||
- [text-patch](./apply/text-patch.md) — Applies an ordered sequence of `TextEdit`s to a string. Used by `patch-text` ops to make targeted insertions/deletions/…
|
||||
- [detect](./detect.md) — Runs a plugin's optional `detect` stage inside an OpenTelemetry span. The plugin reports what is already present in the…
|
||||
- [host](./host.md) — <!-- begin:auto-docs --> _(no submodules)_- apply — <!-- begin:auto-docs --> _(no submodules)_…
|
||||
- [plan](./plan.md) — Invokes `plugin.plan(answers, ctx)` and validates the returned `FileOp[]` against `FileOpsSchema` before letting them f…
|
||||
- [post-install](./post-install.md) — Runs the plugin's optional `postInstall` stage with abort propagation. This is where plugins do follow-up work that doe…
|
||||
- [prompts](./prompts.md) — Runs the plugin's optional `prompts` stage and validates the answers against the schema the plugin returns. This is whe…
|
||||
- [apply](./apply/apply.md) — <!-- begin:auto-docs --> _(no submodules)_- [conflict](./apply/conflict.md) — Resolves the per-op `conflict` policy on a target that already exists. Five policies are supported: `error` (raise `APP…
|
||||
- [json-merge](./apply/json-merge.md) — Implements the deep-merge semantics used by `patch-json` ops with `conflict: "merge"`. Match the conventions of `@suave…
|
||||
- [text-patch](./apply/text-patch.md) — Applies an ordered sequence of `TextEdit`s to a string. Used by `patch-text` ops to make targeted insertions/deletions/…
|
||||
- [detect](./detect.md) — Runs a plugin's optional `detect` stage inside an OpenTelemetry span. The plugin reports what is already present in the…
|
||||
- [host](./host.md) — <!-- begin:auto-docs --> _(no submodules)_- [plan](./plan.md) — Invokes `plugin.plan(answers, ctx)` and validates the returned `FileOp[]` against `FileOpsSchema` before letting them f…
|
||||
- [post-install](./post-install.md) — Runs the plugin's optional `postInstall` stage with abort propagation. This is where plugins do follow-up work that doe…
|
||||
- [prompts](./prompts.md) — Runs the plugin's optional `prompts` stage and validates the answers against the schema the plugin returns. This is whe…
|
||||
|
||||
## Purpose
|
||||
|
||||
The plugin host. `Host.run(plugin, options)` executes the strict pipeline
|
||||
`detect → prompts → plan → apply → postInstall`, with abort propagation,
|
||||
`--dry-run` short-circuiting, and `only`/`exclude` filtering. Each stage is
|
||||
wrapped in an OpenTelemetry span (`installer.<stage>`) carrying
|
||||
`plugin.id`, `plugin.version`, and `dry_run` attributes — that
|
||||
instrumentation is what lets operators correlate apply failures with the
|
||||
specific plugin and version that produced them.
|
||||
|
||||
## Features
|
||||
|
||||
- Strict ordering — optional stages (`detect`, `prompts`, `postInstall`)
|
||||
are skipped without affecting the order of mandatory stages (`plan`,
|
||||
`apply`).
|
||||
- Abort checks at every stage boundary — if the signal aborts mid-run, the
|
||||
host raises `INSTALLER.ABORTED` and apply rolls back any partial work.
|
||||
- `--dry-run` — when set, the host returns the plan ops without invoking
|
||||
apply or postInstall.
|
||||
- `only`/`exclude` — substring filters applied to the op target path
|
||||
(`op.to` for renames, `op.path` otherwise) before apply runs.
|
||||
- `answersFromFile` channel — used by the bin's `--answers <file>` flag to
|
||||
feed pre-recorded answers into prompt validation without going
|
||||
interactive.
|
||||
|
||||
## Basic Example
|
||||
|
||||
```ts
|
||||
import { Host, MemoryFs } from "@suaveplan/installer";
|
||||
|
||||
const fs = new MemoryFs();
|
||||
const host = new Host(
|
||||
{
|
||||
cwd: "/",
|
||||
fs,
|
||||
cli: { confirm: async () => false, prompt: async () => "", write: () => undefined },
|
||||
signal: new AbortController().signal,
|
||||
logger: {
|
||||
debug: () => undefined,
|
||||
info: () => undefined,
|
||||
warn: () => undefined,
|
||||
error: () => undefined,
|
||||
},
|
||||
templates: { render: (s) => s },
|
||||
dryRun: false,
|
||||
force: false,
|
||||
noInteractive: true,
|
||||
},
|
||||
fs
|
||||
);
|
||||
const result = await host.run(myPlugin);
|
||||
console.log(result.summary);
|
||||
```
|
||||
|
||||
## Advanced Example
|
||||
|
||||
```ts
|
||||
import { Host } from "@suaveplan/installer";
|
||||
|
||||
const ac = new AbortController();
|
||||
const host = new Host({ ...ctx, signal: ac.signal, dryRun: true }, fs);
|
||||
|
||||
setTimeout(() => ac.abort(), 5_000);
|
||||
|
||||
const dryResult = await host.run(myPlugin, {
|
||||
only: ["crypto", "events"],
|
||||
exclude: ["legacy"],
|
||||
});
|
||||
console.log(`would apply ${dryResult.ops.length} ops`);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `class Host` — constructed with `(ctx: InstallerContext, fs: MutableInstallerFs)`.
|
||||
- `Host.run<TAnswers, THandle>(plugin, options): Promise<HostRunResult<THandle>>`
|
||||
- `interface HostRunOptions<TAnswers> extends RunOptions<TAnswers>` —
|
||||
adds `answersFromFile?: unknown` for the bin.
|
||||
- `interface HostRunResult<THandle>` — `{ detect, ops, summary, handle, dryRun }`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`filterOps` runs _after_ plan but _before_ apply, so the conformance
|
||||
guarantee that "every emitted op respects its conflict policy on re-run"
|
||||
applies to the post-filter set. `--dry-run` returns a synthetic summary
|
||||
(`skipped = ops.length`) so dashboards see a coherent counter even on
|
||||
hypothetical runs. Abort checks are placed at every awaitable boundary
|
||||
(after detect, after prompts, before apply) so a long-running prompt
|
||||
schema can be cancelled cleanly. `applyOps` itself owns the rollback
|
||||
journal — the host's only responsibility post-apply is to wire up
|
||||
`postInstall` with the resulting handle.
|
||||
Reference in New Issue
Block a user