rolldown-pnpm-config 1.0.11 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/bin/rolldown-pnpm-config.js +2 -12
- package/cli/commands/export.js +23 -20
- package/cli/commands/preview.js +23 -20
- package/cli/commands/upgrade.js +273 -181
- package/cli/cwd.js +25 -0
- package/cli/diff/render.js +19 -37
- package/cli/load-config.js +4 -5
- package/cli/main.js +37 -0
- package/cli/preview-views.js +2 -2
- package/cli/render/legend.js +42 -0
- package/cli/render/print.js +50 -0
- package/cli/render/report.js +38 -0
- package/cli/render/tone.js +43 -0
- package/cli/root.js +22 -0
- package/cli/simulated-view.js +12 -53
- package/cli/summary.js +19 -96
- package/cli/ui/preview-screen.js +93 -0
- package/cli/ui/progress-view.js +47 -0
- package/cli/ui/progress.js +31 -0
- package/cli/ui/screens.js +40 -0
- package/cli/ui/walk-screen.js +176 -0
- package/cli/version.js +12 -0
- package/cli/walk-reducer.js +13 -24
- package/package.json +11 -9
- package/cli/ui/Preview.js +0 -65
- package/cli/ui/Walk.js +0 -89
- package/cli/ui/ansi.js +0 -20
- package/cli/ui/env.js +0 -18
- package/cli/ui/legend.js +0 -80
- package/cli/ui/run-preview.js +0 -22
- package/cli/ui/run-walk.js +0 -33
- package/cli/ui/styled.js +0 -36
package/README.md
CHANGED
|
@@ -89,6 +89,8 @@ For repos that develop the plugin itself and cannot consume it as a config depen
|
|
|
89
89
|
|
|
90
90
|
The `rolldown-pnpm-config preview` command opens an interactive tabbed view — Changes, Full and Simulated — without writing anything. In a non-interactive terminal it falls back to printing the Changes diff, so it is safe to run in CI.
|
|
91
91
|
|
|
92
|
+
Every command adapts its output to who is reading it: colour and interactive screens for a person, plain escape-free text for a coding agent (`--agent`) or a CI job (`--ci`), detected automatically when no flag is given. Exit codes are scriptable — `0` success, `1` drift or failure, `64` a usage error, `130` a quit from an interactive screen. See [upgrading catalogs](https://github.com/spencerbeggs/rolldown-pnpm-config/blob/main/docs/05-upgrading-catalogs.md#output-audience-and-exit-codes).
|
|
93
|
+
|
|
92
94
|
The optional `local` field on `PluginConfig` adjusts managed settings for this repo's export only — the built pnpmfile and its runtime behavior are unaffected. A bare value overwrites the managed value; the directive form merges it:
|
|
93
95
|
|
|
94
96
|
```ts
|
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { previewCommand } from "../cli/commands/preview.js";
|
|
4
|
-
import { upgradeCommand } from "../cli/commands/upgrade.js";
|
|
5
|
-
import { Effect } from "effect";
|
|
6
|
-
import { NodeRuntime, NodeServices } from "@effect/platform-node";
|
|
7
|
-
import { Command } from "effect/cli";
|
|
2
|
+
import { main } from "../cli/main.js";
|
|
8
3
|
|
|
9
4
|
//#region src/cli/bin.ts
|
|
10
|
-
|
|
11
|
-
upgradeCommand,
|
|
12
|
-
exportCommand,
|
|
13
|
-
previewCommand
|
|
14
|
-
]));
|
|
15
|
-
Command.run(root, { version: "1.0.11" }).pipe(Effect.provide(NodeServices.layer), NodeRuntime.runMain);
|
|
5
|
+
main();
|
|
16
6
|
|
|
17
7
|
//#endregion
|
|
18
8
|
export { };
|
package/cli/commands/export.js
CHANGED
|
@@ -2,20 +2,22 @@ import { discoverOwnedPatches, withResolvedBuildPatches } from "../../patches/bu
|
|
|
2
2
|
import { DESCRIPTORS } from "../../descriptors/index.js";
|
|
3
3
|
import { freeze } from "../../plugin/freeze.js";
|
|
4
4
|
import { resolveRootName } from "../../runtime/ctx.js";
|
|
5
|
+
import { canonicalize, renderWorkspace } from "../workspace-file.js";
|
|
6
|
+
import { WorkingDirectory, resolveWorkspacePath } from "../cwd.js";
|
|
5
7
|
import { reconcilePatches } from "../../patches/reconcile.js";
|
|
6
8
|
import { buildDiff } from "../diff/build.js";
|
|
7
9
|
import { renderExportDiff } from "../diff/render.js";
|
|
8
10
|
import { effectiveManaged } from "../effective.js";
|
|
9
|
-
import { canonicalize, renderWorkspace } from "../workspace-file.js";
|
|
10
11
|
import { loadConfigAndWorkspace } from "../load-config.js";
|
|
12
|
+
import { legend } from "../render/legend.js";
|
|
13
|
+
import { printView } from "../render/print.js";
|
|
14
|
+
import { failureDoc } from "../render/report.js";
|
|
11
15
|
import { findConfigFiles, pickConfigCandidate } from "../select-file.js";
|
|
12
|
-
import { toAnsi } from "../ui/ansi.js";
|
|
13
|
-
import { detectCapabilities } from "../ui/env.js";
|
|
14
|
-
import { legendLines } from "../ui/legend.js";
|
|
15
16
|
import { overlayWorkspace } from "../workspace-overlay.js";
|
|
16
17
|
import { Data, Effect, Option, Predicate } from "effect";
|
|
17
18
|
import { existsSync, writeFileSync } from "node:fs";
|
|
18
19
|
import { dirname, relative } from "node:path";
|
|
20
|
+
import { CliDoc, CliMessage } from "@effected/cli";
|
|
19
21
|
import { Argument, Command, Flag } from "effect/cli";
|
|
20
22
|
|
|
21
23
|
//#region src/cli/commands/export.ts
|
|
@@ -24,7 +26,12 @@ import { Argument, Command, Flag } from "effect/cli";
|
|
|
24
26
|
*
|
|
25
27
|
* @internal
|
|
26
28
|
*/
|
|
27
|
-
var ExportError = class extends Data.TaggedError("ExportError") {
|
|
29
|
+
var ExportError = class extends Data.TaggedError("ExportError") {
|
|
30
|
+
/** The failure report `CliRuntime.main` prints: the message, without the class name. */
|
|
31
|
+
[CliDoc]() {
|
|
32
|
+
return failureDoc(this.message);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
28
35
|
/**
|
|
29
36
|
* The set of pnpm config keys that belong in pnpm-workspace.yaml
|
|
30
37
|
* (i.e. descriptors with `workspaceYaml: true`).
|
|
@@ -96,9 +103,9 @@ function runExport(opts) {
|
|
|
96
103
|
};
|
|
97
104
|
});
|
|
98
105
|
}
|
|
99
|
-
const pathArg = Argument.File("path").pipe(Argument.optional);
|
|
100
|
-
const dryRunFlag = Flag.Boolean("dry-run").pipe(Flag.withDefault(false));
|
|
101
|
-
const fullFlag = Flag.Boolean("full").pipe(Flag.withDefault(false));
|
|
106
|
+
const pathArg = Argument.File("path").pipe(Argument.withDescription("The pnpm-workspace.yaml to write (the nearest one upward when omitted)"), Argument.optional);
|
|
107
|
+
const dryRunFlag = Flag.Boolean("dry-run").pipe(Flag.withDescription("Print the diff instead of writing the file"), Flag.withDefault(false));
|
|
108
|
+
const fullFlag = Flag.Boolean("full").pipe(Flag.withDescription("Show every line of the diff, not just the changes and their context"), Flag.withDefault(false));
|
|
102
109
|
/**
|
|
103
110
|
* The "export" command. Materializes the plugin config into pnpm-workspace.yaml.
|
|
104
111
|
* An optional path argument overrides the auto-detected workspace file. --dry-run
|
|
@@ -112,26 +119,22 @@ const exportCommand = Command.make("export", {
|
|
|
112
119
|
dryRun: dryRunFlag,
|
|
113
120
|
full: fullFlag
|
|
114
121
|
}, ({ path, dryRun, full }) => Effect.gen(function* () {
|
|
115
|
-
const matches = yield* findConfigFiles(
|
|
122
|
+
const matches = yield* findConfigFiles(yield* WorkingDirectory);
|
|
116
123
|
const picked = pickConfigCandidate(matches);
|
|
117
124
|
if (!picked.ok) return yield* Effect.fail(new ExportError({ message: picked.message }));
|
|
118
|
-
const workspacePath = Option.getOrUndefined(path);
|
|
119
125
|
const result = yield* runExport({
|
|
120
126
|
configFile: picked.file,
|
|
121
|
-
|
|
127
|
+
workspacePath: yield* resolveWorkspacePath(Option.getOrUndefined(path)),
|
|
122
128
|
preview: dryRun,
|
|
123
129
|
full
|
|
124
130
|
});
|
|
125
|
-
yield*
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
process.stdout.write(`${result.path} (dry run — not written)\n\n`);
|
|
129
|
-
const legend = caps.color ? `${toAnsi(legendLines(), { color: caps.color })}\n\n` : "";
|
|
130
|
-
process.stdout.write(`${legend}${toAnsi(result.diff, { color: caps.color })}\n`);
|
|
131
|
-
} else process.stdout.write(`Exported to ${result.path}\n`);
|
|
132
|
-
for (const k of result.report.staleEntries) process.stderr.write(`warning: patch entry "${k}" has no file on disk\n`);
|
|
133
|
-
for (const k of result.report.keyMismatches) process.stderr.write(`warning: patch entry "${k}" does not match its filename\n`);
|
|
131
|
+
if (dryRun) yield* printView(result.diff, {
|
|
132
|
+
legend: legend(),
|
|
133
|
+
heading: `${result.path} (dry run — not written)`
|
|
134
134
|
});
|
|
135
|
+
else yield* CliMessage.success(`Exported to ${result.path}`);
|
|
136
|
+
for (const k of result.report.staleEntries) yield* CliMessage.warning(`patch entry "${k}" has no file on disk`);
|
|
137
|
+
for (const k of result.report.keyMismatches) yield* CliMessage.warning(`patch entry "${k}" does not match its filename`);
|
|
135
138
|
})).pipe(Command.withDescription("Materialize the plugin config into pnpm-workspace.yaml (--dry-run to preview)"));
|
|
136
139
|
|
|
137
140
|
//#endregion
|
package/cli/commands/preview.js
CHANGED
|
@@ -1,22 +1,31 @@
|
|
|
1
1
|
import { freeze } from "../../plugin/freeze.js";
|
|
2
2
|
import { resolveRootName } from "../../runtime/ctx.js";
|
|
3
|
+
import { WorkingDirectory, resolveWorkspacePath } from "../cwd.js";
|
|
3
4
|
import { loadConfigAndWorkspace } from "../load-config.js";
|
|
5
|
+
import { legend } from "../render/legend.js";
|
|
6
|
+
import { printView } from "../render/print.js";
|
|
7
|
+
import { failureDoc } from "../render/report.js";
|
|
4
8
|
import { findConfigFiles, pickConfigCandidate } from "../select-file.js";
|
|
5
|
-
import { toAnsi } from "../ui/ansi.js";
|
|
6
|
-
import { detectCapabilities } from "../ui/env.js";
|
|
7
|
-
import { legendLines } from "../ui/legend.js";
|
|
8
9
|
import { WORKSPACE_FIELDS } from "./export.js";
|
|
9
10
|
import { buildPreviewViews } from "../preview-views.js";
|
|
11
|
+
import { previewScreen } from "../ui/screens.js";
|
|
10
12
|
import { Data, Effect, Option } from "effect";
|
|
11
13
|
import { dirname } from "node:path";
|
|
14
|
+
import { CliDoc, CliInteractive } from "@effected/cli";
|
|
12
15
|
import { Argument, Command } from "effect/cli";
|
|
16
|
+
import { CliUi } from "@effected/cli/ui";
|
|
13
17
|
|
|
14
18
|
//#region src/cli/commands/preview.ts
|
|
15
19
|
/** Typed failure for the preview run. @internal */
|
|
16
|
-
var PreviewError = class extends Data.TaggedError("PreviewError") {
|
|
20
|
+
var PreviewError = class extends Data.TaggedError("PreviewError") {
|
|
21
|
+
/** The failure report `CliRuntime.main` prints: the message, without the class name. */
|
|
22
|
+
[CliDoc]() {
|
|
23
|
+
return failureDoc(this.message);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
17
26
|
/**
|
|
18
27
|
* Build the three preview views from a config + workspace file. Pure of any
|
|
19
|
-
* terminal interaction; the command wraps this with interactive/non-
|
|
28
|
+
* terminal interaction; the command wraps this with interactive/non-interactive output.
|
|
20
29
|
*
|
|
21
30
|
* @internal
|
|
22
31
|
*/
|
|
@@ -35,31 +44,25 @@ function runPreviewViews(opts) {
|
|
|
35
44
|
});
|
|
36
45
|
});
|
|
37
46
|
}
|
|
38
|
-
const pathArg = Argument.File("path").pipe(Argument.optional);
|
|
47
|
+
const pathArg = Argument.File("path").pipe(Argument.withDescription("The pnpm-workspace.yaml to preview against (the nearest one upward when omitted)"), Argument.optional);
|
|
39
48
|
/**
|
|
40
|
-
* The "preview" command: interactive
|
|
41
|
-
* (Changes / Full / Simulated).
|
|
42
|
-
* the
|
|
49
|
+
* The "preview" command: an interactive tabbed explorer of the export diff
|
|
50
|
+
* (Changes / Full / Simulated). When the run cannot prompt — a pipe, CI, an
|
|
51
|
+
* agent — it prints the Changes view instead. The explorer is read-only, so
|
|
52
|
+
* closing it any way (q, Enter, Esc, Ctrl-C) is a normal exit.
|
|
43
53
|
*
|
|
44
54
|
* @internal
|
|
45
55
|
*/
|
|
46
56
|
const previewCommand = Command.make("preview", { path: pathArg }, ({ path }) => Effect.gen(function* () {
|
|
47
|
-
const matches = yield* findConfigFiles(
|
|
57
|
+
const matches = yield* findConfigFiles(yield* WorkingDirectory);
|
|
48
58
|
const picked = pickConfigCandidate(matches);
|
|
49
59
|
if (!picked.ok) return yield* Effect.fail(new PreviewError({ message: picked.message }));
|
|
50
|
-
const workspacePath = Option.getOrUndefined(path);
|
|
51
60
|
const views = yield* runPreviewViews({
|
|
52
61
|
configFile: picked.file,
|
|
53
|
-
|
|
54
|
-
});
|
|
55
|
-
const caps = detectCapabilities();
|
|
56
|
-
if (caps.interactive) {
|
|
57
|
-
const { runPreview } = yield* Effect.promise(() => import("../ui/run-preview.js"));
|
|
58
|
-
yield* runPreview(views);
|
|
59
|
-
} else yield* Effect.sync(() => {
|
|
60
|
-
const legend = caps.color ? `${toAnsi(legendLines(), { color: caps.color })}\n\n` : "";
|
|
61
|
-
process.stdout.write(`${legend}${toAnsi(views.changes, { color: caps.color })}\n`);
|
|
62
|
+
workspacePath: yield* resolveWorkspacePath(Option.getOrUndefined(path))
|
|
62
63
|
});
|
|
64
|
+
if (!(yield* CliInteractive)) return yield* printView(views.changes, { legend: legend() });
|
|
65
|
+
yield* CliUi.run(previewScreen(views)).pipe(Effect.catchTag("Cancelled", () => Effect.void));
|
|
63
66
|
})).pipe(Command.withDescription("Interactively preview how pnpm-workspace.yaml would change"));
|
|
64
67
|
|
|
65
68
|
//#endregion
|