@vzn/vx-lockfile 0.0.596 → 0.0.597

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 CHANGED
@@ -55,7 +55,7 @@ Declaring any of the four plugins adds `vx prune` (the `commands` seam): the wor
55
55
  vx prune <project...> [--out-dir <dir>] [--docker]
56
56
  ```
57
57
 
58
- The out dir (default `out/`, relative to the cwd) gets the root `package.json` with `workspaces` rewritten to the subset's dirs, `pnpm-workspace.yaml` with `packages` rewritten (every other key as written), each lockfile at the root **pruned** to what the subset installs, the install config (`.npmrc`, `.yarnrc.yml`, `.pnpmfile.cjs`, `bunfig.toml`, `.nvmrc`, `.node-version`, the patch files `patchedDependencies` names, Yarn's `yarnPath` and plugins), `vx.workspace.*`, the root `vx.config.*`, and each project directory less `node_modules`, `.git`, `.vx` and `.turbo`. A workspace package a copied vx config imports (a local plugin) comes along with its closure: the config loads before any task. A relative config import that leaves the subset is warned about. `--docker` writes `json/` — the root install files and each project's `package.json`, the cacheable install layer — and `full/`, everything:
58
+ The out dir (default `out/`, relative to the cwd) gets the root `package.json` with `workspaces` rewritten to the subset's dirs (a glob character in a dir name bracketed, `a[1]` → `a[[]1]`, so the pattern matches that dir alone), `pnpm-workspace.yaml` with `packages` rewritten (every other key as written), each lockfile at the root **pruned** to what the subset installs, the install config (`.npmrc`, `.yarnrc.yml`, `.pnpmfile.cjs`, `bunfig.toml`, `.nvmrc`, `.node-version`, the patch files `patchedDependencies` names, Yarn's `yarnPath` and plugins), `vx.workspace.*`, the root `vx.config.*`, and each project directory less `node_modules`, `.git`, `.vx` and `.turbo`. A workspace package a copied vx config imports (a local plugin) comes along with its closure: the config loads before any task. A relative config import that leaves the subset is warned about. `--docker` writes `json/` — the root install files and each project's `package.json`, the cacheable install layer — and `full/`, everything:
59
59
 
60
60
  ```dockerfile
61
61
  COPY out/json/ .
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx-lockfile",
3
- "version": "0.0.596",
3
+ "version": "0.0.597",
4
4
  "license": "MIT",
5
5
  "description": "Lockfile plugins for vx — pnpm(), bun(), npm(), yarn(): each keys every task on its project's own resolved dependency closure from the package manager's lockfile, so a lockfile change re-keys only the projects it reaches; --affected follows the same answer; `vx prune` cuts the workspace and the lockfile to a Docker subset.",
6
6
  "keywords": [
@@ -37,7 +37,7 @@
37
37
  "access": "public"
38
38
  },
39
39
  "peerDependencies": {
40
- "@vzn/vx": "^0.0.596"
40
+ "@vzn/vx": "^0.0.597"
41
41
  },
42
42
  "repository": {
43
43
  "type": "git",
package/src/prune.ts CHANGED
@@ -195,7 +195,8 @@ export async function prune(argv: readonly string[], ctx: CommandContext): Promi
195
195
  const listed = Array.isArray(field)
196
196
  ? (field as string[])
197
197
  : ((field as { packages?: string[] } | undefined)?.packages ?? undefined)
198
- const workspaces = listed?.includes('.') ? ['.', ...rels] : rels
198
+ const patterns = rels.map(literalGlob)
199
+ const workspaces = listed?.includes('.') ? ['.', ...patterns] : patterns
199
200
  if (listed !== undefined) {
200
201
  rootManifest['workspaces'] = Array.isArray(field)
201
202
  ? workspaces
@@ -237,7 +238,7 @@ export async function prune(argv: readonly string[], ctx: CommandContext): Promi
237
238
  if (await exists(workspaceYaml)) {
238
239
  written.set(
239
240
  'pnpm-workspace.yaml',
240
- rewriteWorkspaceYaml(await Bun.file(workspaceYaml).text(), rels),
241
+ rewriteWorkspaceYaml(await Bun.file(workspaceYaml).text(), patterns),
241
242
  )
242
243
  }
243
244
  // A manifest with no `workspaces` (pnpm's) is copied byte for byte.
@@ -287,10 +288,21 @@ export async function prune(argv: readonly string[], ctx: CommandContext): Promi
287
288
  return 0
288
289
  }
289
290
 
290
- /** `packages:` cut to the subset's dirs; every other key as written. */
291
- function rewriteWorkspaceYaml(text: string, rels: readonly string[]): string {
291
+ /**
292
+ * A dir as a workspace pattern that matches only itself: every package
293
+ * manager and vx read the list as globs, and `packages/a[1]` matched
294
+ * `packages/a1`, so the pruned copy had no such member. A class of one
295
+ * (`[[]`) is the escape bun, npm, pnpm, yarn and `Bun.Glob` all read;
296
+ * a backslash is not (bun found no workspace).
297
+ */
298
+ function literalGlob(rel: string): string {
299
+ return rel.replace(/[*?[{]/g, '[$&]')
300
+ }
301
+
302
+ /** `packages:` cut to the subset's member patterns; every other key as written. */
303
+ function rewriteWorkspaceYaml(text: string, members: readonly string[]): string {
292
304
  const lines = text.split('\n')
293
- const list = ['packages:', ...rels.map((r) => ` - ${JSON.stringify(r)}`)]
305
+ const list = ['packages:', ...members.map((r) => ` - ${JSON.stringify(r)}`)]
294
306
  const at = lines.findIndex((l) => /^packages\s*:/.test(l))
295
307
  if (at === -1) return [...list, ...lines].join('\n')
296
308
  let end = at + 1