@_linked/cli 1.46.2 → 1.47.0

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.
Files changed (167) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/README.md +48 -36
  3. package/hooks/drift.cjs +169 -0
  4. package/hooks/git-hook.cjs +170 -0
  5. package/hooks/hook-shim.cjs +63 -0
  6. package/hooks/lock-at-rest.cjs +268 -0
  7. package/hooks/manifests.cjs +216 -0
  8. package/hooks/platform.cjs +25 -0
  9. package/lib/esm/app-release/build-backend.d.ts.map +1 -1
  10. package/lib/esm/app-release/build-backend.js +2 -1
  11. package/lib/esm/app-release/build-backend.js.map +1 -1
  12. package/lib/esm/cli-methods.d.ts.map +1 -1
  13. package/lib/esm/cli-methods.js +166 -150
  14. package/lib/esm/cli-methods.js.map +1 -1
  15. package/lib/esm/cli.js +20 -22
  16. package/lib/esm/cli.js.map +1 -1
  17. package/lib/esm/commands/build-app.d.ts.map +1 -1
  18. package/lib/esm/commands/build-app.js +2 -1
  19. package/lib/esm/commands/build-app.js.map +1 -1
  20. package/lib/esm/commands/build-package.d.ts.map +1 -1
  21. package/lib/esm/commands/build-package.js +6 -2
  22. package/lib/esm/commands/build-package.js.map +1 -1
  23. package/lib/esm/commands/localize.d.ts +9 -15
  24. package/lib/esm/commands/localize.d.ts.map +1 -1
  25. package/lib/esm/commands/localize.js +43 -74
  26. package/lib/esm/commands/localize.js.map +1 -1
  27. package/lib/esm/commands/setup-publish.d.ts.map +1 -1
  28. package/lib/esm/commands/setup-publish.js +22 -15
  29. package/lib/esm/commands/setup-publish.js.map +1 -1
  30. package/lib/esm/commands/start.d.ts +8 -0
  31. package/lib/esm/commands/start.d.ts.map +1 -1
  32. package/lib/esm/commands/start.js +20 -8
  33. package/lib/esm/commands/start.js.map +1 -1
  34. package/lib/esm/installed-packages.d.ts +5 -13
  35. package/lib/esm/installed-packages.d.ts.map +1 -1
  36. package/lib/esm/installed-packages.js +5 -38
  37. package/lib/esm/installed-packages.js.map +1 -1
  38. package/lib/esm/lifecycle.d.ts +35 -22
  39. package/lib/esm/lifecycle.d.ts.map +1 -1
  40. package/lib/esm/lifecycle.js +62 -36
  41. package/lib/esm/lifecycle.js.map +1 -1
  42. package/lib/esm/localize/adopt.d.ts +5 -5
  43. package/lib/esm/localize/adopt.d.ts.map +1 -1
  44. package/lib/esm/localize/adopt.js +46 -55
  45. package/lib/esm/localize/adopt.js.map +1 -1
  46. package/lib/esm/localize/app-root.d.ts +16 -0
  47. package/lib/esm/localize/app-root.d.ts.map +1 -0
  48. package/lib/esm/localize/app-root.js +94 -0
  49. package/lib/esm/localize/app-root.js.map +1 -0
  50. package/lib/esm/localize/app-setup.d.ts +21 -0
  51. package/lib/esm/localize/app-setup.d.ts.map +1 -0
  52. package/lib/esm/localize/app-setup.js +178 -0
  53. package/lib/esm/localize/app-setup.js.map +1 -0
  54. package/lib/esm/localize/delocalize.d.ts.map +1 -1
  55. package/lib/esm/localize/delocalize.js +169 -104
  56. package/lib/esm/localize/delocalize.js.map +1 -1
  57. package/lib/esm/localize/drift-hook.d.ts +18 -0
  58. package/lib/esm/localize/drift-hook.d.ts.map +1 -0
  59. package/lib/esm/localize/drift-hook.js +37 -0
  60. package/lib/esm/localize/drift-hook.js.map +1 -0
  61. package/lib/esm/localize/drift.d.ts +36 -0
  62. package/lib/esm/localize/drift.d.ts.map +1 -0
  63. package/lib/esm/localize/drift.js +34 -0
  64. package/lib/esm/localize/drift.js.map +1 -0
  65. package/lib/esm/localize/errors.d.ts +14 -8
  66. package/lib/esm/localize/errors.d.ts.map +1 -1
  67. package/lib/esm/localize/errors.js +14 -8
  68. package/lib/esm/localize/errors.js.map +1 -1
  69. package/lib/esm/localize/fsops.d.ts +11 -27
  70. package/lib/esm/localize/fsops.d.ts.map +1 -1
  71. package/lib/esm/localize/fsops.js +40 -115
  72. package/lib/esm/localize/fsops.js.map +1 -1
  73. package/lib/esm/localize/git-hooks.d.ts +33 -0
  74. package/lib/esm/localize/git-hooks.d.ts.map +1 -0
  75. package/lib/esm/localize/git-hooks.js +146 -0
  76. package/lib/esm/localize/git-hooks.js.map +1 -0
  77. package/lib/esm/localize/hook-module.d.ts +6 -0
  78. package/lib/esm/localize/hook-module.d.ts.map +1 -0
  79. package/lib/esm/localize/hook-module.js +37 -0
  80. package/lib/esm/localize/hook-module.js.map +1 -0
  81. package/lib/esm/localize/index.d.ts +14 -15
  82. package/lib/esm/localize/index.d.ts.map +1 -1
  83. package/lib/esm/localize/index.js +8 -9
  84. package/lib/esm/localize/index.js.map +1 -1
  85. package/lib/esm/localize/list.d.ts +6 -10
  86. package/lib/esm/localize/list.d.ts.map +1 -1
  87. package/lib/esm/localize/list.js +49 -189
  88. package/lib/esm/localize/list.js.map +1 -1
  89. package/lib/esm/localize/localize.d.ts +46 -62
  90. package/lib/esm/localize/localize.d.ts.map +1 -1
  91. package/lib/esm/localize/localize.js +411 -285
  92. package/lib/esm/localize/localize.js.map +1 -1
  93. package/lib/esm/localize/members.d.ts +13 -0
  94. package/lib/esm/localize/members.d.ts.map +1 -0
  95. package/lib/esm/localize/members.js +46 -0
  96. package/lib/esm/localize/members.js.map +1 -0
  97. package/lib/esm/localize/resolve.d.ts +1 -2
  98. package/lib/esm/localize/resolve.d.ts.map +1 -1
  99. package/lib/esm/localize/resolve.js +3 -5
  100. package/lib/esm/localize/resolve.js.map +1 -1
  101. package/lib/esm/localize/run.d.ts +1 -0
  102. package/lib/esm/localize/run.d.ts.map +1 -1
  103. package/lib/esm/localize/run.js +11 -6
  104. package/lib/esm/localize/run.js.map +1 -1
  105. package/lib/esm/localize/setup-lockfile.d.ts +13 -0
  106. package/lib/esm/localize/setup-lockfile.d.ts.map +1 -0
  107. package/lib/esm/localize/setup-lockfile.js +80 -0
  108. package/lib/esm/localize/setup-lockfile.js.map +1 -0
  109. package/lib/esm/utils/createPackageLocation.d.ts +4 -13
  110. package/lib/esm/utils/createPackageLocation.d.ts.map +1 -1
  111. package/lib/esm/utils/createPackageLocation.js +12 -21
  112. package/lib/esm/utils/createPackageLocation.js.map +1 -1
  113. package/lib/esm/utils/packageSetup.d.ts +5 -2
  114. package/lib/esm/utils/packageSetup.d.ts.map +1 -1
  115. package/lib/esm/utils/packageSetup.js +9 -3
  116. package/lib/esm/utils/packageSetup.js.map +1 -1
  117. package/lib/esm/utils/platform.d.ts +24 -0
  118. package/lib/esm/utils/platform.d.ts.map +1 -0
  119. package/lib/esm/utils/platform.js +62 -0
  120. package/lib/esm/utils/platform.js.map +1 -0
  121. package/lib/esm/utils/shapeReferences.d.ts.map +1 -1
  122. package/lib/esm/utils/shapeReferences.js +3 -2
  123. package/lib/esm/utils/shapeReferences.js.map +1 -1
  124. package/lib/esm/utils/spawn.d.ts +65 -0
  125. package/lib/esm/utils/spawn.d.ts.map +1 -0
  126. package/lib/esm/utils/spawn.js +181 -0
  127. package/lib/esm/utils/spawn.js.map +1 -0
  128. package/lib/esm/utils.d.ts.map +1 -1
  129. package/lib/esm/utils.js +19 -5
  130. package/lib/esm/utils.js.map +1 -1
  131. package/lib/esm/vite-config.d.ts +5 -12
  132. package/lib/esm/vite-config.d.ts.map +1 -1
  133. package/lib/esm/vite-config.js +41 -33
  134. package/lib/esm/vite-config.js.map +1 -1
  135. package/package.json +4 -3
  136. package/lib/esm/localize/ensure.d.ts +0 -44
  137. package/lib/esm/localize/ensure.d.ts.map +0 -1
  138. package/lib/esm/localize/ensure.js +0 -151
  139. package/lib/esm/localize/ensure.js.map +0 -1
  140. package/lib/esm/localize/manifest.d.ts +0 -63
  141. package/lib/esm/localize/manifest.d.ts.map +0 -1
  142. package/lib/esm/localize/manifest.js +0 -133
  143. package/lib/esm/localize/manifest.js.map +0 -1
  144. package/lib/esm/localize/one-copy-hook.d.ts +0 -16
  145. package/lib/esm/localize/one-copy-hook.d.ts.map +0 -1
  146. package/lib/esm/localize/one-copy-hook.js +0 -20
  147. package/lib/esm/localize/one-copy-hook.js.map +0 -1
  148. package/lib/esm/localize/provided.d.ts +0 -28
  149. package/lib/esm/localize/provided.d.ts.map +0 -1
  150. package/lib/esm/localize/provided.js +0 -89
  151. package/lib/esm/localize/provided.js.map +0 -1
  152. package/lib/esm/localize/prune.d.ts +0 -182
  153. package/lib/esm/localize/prune.d.ts.map +0 -1
  154. package/lib/esm/localize/prune.js +0 -703
  155. package/lib/esm/localize/prune.js.map +0 -1
  156. package/lib/esm/localize/relink.d.ts +0 -13
  157. package/lib/esm/localize/relink.d.ts.map +0 -1
  158. package/lib/esm/localize/relink.js +0 -181
  159. package/lib/esm/localize/relink.js.map +0 -1
  160. package/lib/esm/localized-dedupe.d.ts +0 -26
  161. package/lib/esm/localized-dedupe.d.ts.map +0 -1
  162. package/lib/esm/localized-dedupe.js +0 -139
  163. package/lib/esm/localized-dedupe.js.map +0 -1
  164. package/lib/esm/utils/relinkHooks.d.ts +0 -19
  165. package/lib/esm/utils/relinkHooks.d.ts.map +0 -1
  166. package/lib/esm/utils/relinkHooks.js +0 -74
  167. package/lib/esm/utils/relinkHooks.js.map +0 -1
@@ -3,20 +3,19 @@
3
3
  * `commands/localize.ts`, the commander adapter) and `create-package`'s adopt
4
4
  * reach it through here.
5
5
  *
6
- * Every function takes `deps` -- `{appRoot, run, log, warn, error}` -- so a
6
+ * Every command takes `deps` -- `{appRoot, run, log, warn, error}` -- so a
7
7
  * caller can point it at another root or capture its output. `defaultDeps()`
8
8
  * builds the normal one.
9
9
  */
10
- export { localize } from './localize.js';
11
- export { adopt } from './adopt.js';
10
+ export { localize, DEFAULT_BUILD_COMMAND } from './localize.js';
11
+ export { adopt, localizeParked } from './adopt.js';
12
12
  export { delocalize } from './delocalize.js';
13
13
  export { list, collect } from './list.js';
14
- export { relink } from './relink.js';
15
- export { pruneProvided, satisfies, shouldPrune } from './prune.js';
16
- export { providedPackages } from './provided.js';
17
- export { ensure, reinstall, checkOneCopy } from './ensure.js';
14
+ export { driftProblems, describeDrift, satisfies } from './drift.js';
15
+ export { LOCAL_DIR, PARKED_DIR, localMembers, parkedMembers } from './members.js';
16
+ export { ensureAppSetup } from './app-setup.js';
17
+ export { findAppRoot } from './app-root.js';
18
18
  export { resolvePackage, normalizeGitUrl, checkoutNameFor } from './resolve.js';
19
- export { readManifest, writeManifest, manifestPath, MANIFEST_FILENAME, SCHEMA_VERSION, DEFAULT_DIR, } from './manifest.js';
20
19
  export { defaultDeps, makeRun } from './run.js';
21
- export { LocalizeError, EXIT_BAD_FILE, EXIT_NOT_FOUND, EXIT_WARNED, EXIT_REFUSED, EXIT_INSTALL_FAILED, EXIT_MANIFEST_DIRTY, } from './errors.js';
20
+ export { LocalizeError, EXIT_DRIFT, EXIT_USAGE, EXIT_NOT_FOUND, EXIT_WARNED, EXIT_REFUSED, EXIT_INSTALL_FAILED, } from './errors.js';
22
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/localize/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AACvC,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AACjC,OAAO,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,MAAM,WAAW,CAAC;AACxC,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACnC,OAAO,EAAC,aAAa,EAAE,SAAS,EAAE,WAAW,EAAC,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAC,MAAM,aAAa,CAAC;AAM5D,OAAO,EAAC,cAAc,EAAE,eAAe,EAAE,eAAe,EAAC,MAAM,cAAc,CAAC;AAC9E,OAAO,EACL,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,WAAW,EAAE,OAAO,EAAC,MAAM,UAAU,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,aAAa,EACb,cAAc,EACd,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,aAAa,CAAC","sourcesContent":["/**\n * localize's programmatic API: `linked localize` / `linked delocalize` (see\n * `commands/localize.ts`, the commander adapter) and `create-package`'s adopt\n * reach it through here.\n *\n * Every function takes `deps` -- `{appRoot, run, log, warn, error}` -- so a\n * caller can point it at another root or capture its output. `defaultDeps()`\n * builds the normal one.\n */\nexport {localize} from './localize.js';\nexport {adopt} from './adopt.js';\nexport {delocalize} from './delocalize.js';\nexport {list, collect} from './list.js';\nexport {relink} from './relink.js';\nexport {pruneProvided, satisfies, shouldPrune} from './prune.js';\nexport type {PruneOptions, PruneScope} from './prune.js';\nexport {providedPackages} from './provided.js';\nexport type {Provided, ProvidedSkip} from './provided.js';\nexport {ensure, reinstall, checkOneCopy} from './ensure.js';\nexport type {LocalizeOptions} from './localize.js';\nexport type {ListRow} from './list.js';\nexport type {Resolved} from './resolve.js';\nexport type {Manifest, ManifestEntry} from './manifest.js';\nexport type {Deps, Run, RunOptions, RunResult} from './run.js';\nexport {resolvePackage, normalizeGitUrl, checkoutNameFor} from './resolve.js';\nexport {\n readManifest,\n writeManifest,\n manifestPath,\n MANIFEST_FILENAME,\n SCHEMA_VERSION,\n DEFAULT_DIR,\n} from './manifest.js';\nexport {defaultDeps, makeRun} from './run.js';\nexport {\n LocalizeError,\n EXIT_BAD_FILE,\n EXIT_NOT_FOUND,\n EXIT_WARNED,\n EXIT_REFUSED,\n EXIT_INSTALL_FAILED,\n EXIT_MANIFEST_DIRTY,\n} from './errors.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/localize/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAC,QAAQ,EAAE,qBAAqB,EAAC,MAAM,eAAe,CAAC;AAE9D,OAAO,EAAC,KAAK,EAAE,cAAc,EAAC,MAAM,YAAY,CAAC;AACjD,OAAO,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,MAAM,WAAW,CAAC;AAExC,OAAO,EAAC,aAAa,EAAE,aAAa,EAAE,SAAS,EAAC,MAAM,YAAY,CAAC;AAEnE,OAAO,EAAC,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAC,MAAM,cAAc,CAAC;AAEhF,OAAO,EAAC,cAAc,EAAC,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAC,cAAc,EAAE,eAAe,EAAE,eAAe,EAAC,MAAM,cAAc,CAAC;AAE9E,OAAO,EAAC,WAAW,EAAE,OAAO,EAAC,MAAM,UAAU,CAAC;AAE9C,OAAO,EACL,aAAa,EACb,UAAU,EACV,UAAU,EACV,cAAc,EACd,WAAW,EACX,YAAY,EACZ,mBAAmB,GACpB,MAAM,aAAa,CAAC","sourcesContent":["/**\n * localize's programmatic API: `linked localize` / `linked delocalize` (see\n * `commands/localize.ts`, the commander adapter) and `create-package`'s adopt\n * reach it through here.\n *\n * Every command takes `deps` -- `{appRoot, run, log, warn, error}` -- so a\n * caller can point it at another root or capture its output. `defaultDeps()`\n * builds the normal one.\n */\nexport {localize, DEFAULT_BUILD_COMMAND} from './localize.js';\nexport type {LocalizeOptions} from './localize.js';\nexport {adopt, localizeParked} from './adopt.js';\nexport {delocalize} from './delocalize.js';\nexport {list, collect} from './list.js';\nexport type {ListRow} from './list.js';\nexport {driftProblems, describeDrift, satisfies} from './drift.js';\nexport type {Drift} from './drift.js';\nexport {LOCAL_DIR, PARKED_DIR, localMembers, parkedMembers} from './members.js';\nexport type {Member} from './members.js';\nexport {ensureAppSetup} from './app-setup.js';\nexport type {SetupChange} from './app-setup.js';\nexport {findAppRoot} from './app-root.js';\nexport {resolvePackage, normalizeGitUrl, checkoutNameFor} from './resolve.js';\nexport type {Resolved} from './resolve.js';\nexport {defaultDeps, makeRun} from './run.js';\nexport type {Deps, Run, RunOptions, RunResult} from './run.js';\nexport {\n LocalizeError,\n EXIT_DRIFT,\n EXIT_USAGE,\n EXIT_NOT_FOUND,\n EXIT_WARNED,\n EXIT_REFUSED,\n EXIT_INSTALL_FAILED,\n} from './errors.js';\n"]}
@@ -1,18 +1,14 @@
1
+ import type { Drift } from './drift.js';
2
+ import type { Member } from './members.js';
1
3
  import type { Deps } from './run.js';
2
- /** One row of `--list`: a recorded package, or a link the manifest does not know. */
3
- export interface ListRow {
4
- name: string;
5
- state: 'linked' | 'checkout-missing' | 'not-linked' | 'malformed' | 'untracked' | 'unrecorded';
6
- path: string;
4
+ /** One row of `--list`. */
5
+ export interface ListRow extends Member {
6
+ state: 'localized' | 'parked';
7
7
  branch: string;
8
- note: string;
9
- /** A linked checkout: the copies pruning keeps in it, each with its reason. */
10
- kept?: string[];
11
8
  }
12
- /** @returns {{rows: object[], notLinked: number}} */
13
9
  export declare function collect(deps: Deps): {
14
10
  rows: ListRow[];
15
- notLinked: number;
11
+ drift: Drift[];
16
12
  };
17
13
  export declare function list(opts: {
18
14
  check?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/localize/list.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,UAAU,CAAC;AAEnC,qFAAqF;AACrF,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EACD,QAAQ,GACR,kBAAkB,GAClB,YAAY,GACZ,WAAW,GACX,WAAW,GACX,YAAY,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,qDAAqD;AACrD,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG;IAAC,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,CAuGxE;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAsDhE"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/localize/list.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AAStC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,UAAU,CAAC;AAEnC,2BAA2B;AAC3B,MAAM,WAAW,OAAQ,SAAQ,MAAM;IACrC,KAAK,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG;IAAC,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,KAAK,EAAE,KAAK,EAAE,CAAA;CAAC,CAarE;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAuChE"}
@@ -1,208 +1,68 @@
1
1
  /**
2
- * `--list` -- read the SYMLINKS, then reconcile against the manifest.
2
+ * `--list` -- what is localized, what is parked, and the drift (drift.ts).
3
3
  *
4
- * The manifest records INTENT; the symlink is TRUTH. They can disagree -- most
5
- * commonly because `npm ci` deleted `node_modules` and exited 0 -- so this
6
- * reads the links first and reports the disagreement rather than assuming.
7
- * The four states are distinguished deliberately: both of the silent failures
8
- * this tool was built to end were disagreements between intent and truth.
4
+ * The record is the directories: every checkout in `packages-local/` is a
5
+ * workspace member, every one in `.packages-local.parked/` is parked. A row
6
+ * per checkout -- name, directory, branch, version -- then one line per drift.
9
7
  *
10
- * It also flags a directory in the checkout directory (`packages-local/`) that
11
- * nothing records and nothing links: every checkout there is meant to be
12
- * localized, and one that is not loads nobody's code while looking as if it
13
- * did.
14
- *
15
- * For a linked checkout it also says what pruning would keep in that
16
- * checkout's `node_modules` and why (prune.ts `planPrune`, nothing removed),
17
- * or that pruning is off for it (`prune: false`): localize, adopt and
18
- * `--relink` only summarise kept copies, and this is where the reasons are.
19
- *
20
- * Never writes. Exits 0, unless `--check` and something recorded is not
21
- * actually linked.
8
+ * `--check` is for CI and scripts: it prints only the drift (nothing when
9
+ * there is none) and exits 1 when there is any. (The lock-at-rest hook reports
10
+ * drift itself, with `hooks/drift.cjs`.) It writes nothing, except that
11
+ * checkouts an interrupted set-up left in `packages-local/.setup-aside/` are
12
+ * moved back first, as `localize` and `delocalize` do.
22
13
  */
23
- import fs from 'node:fs';
24
14
  import path from 'node:path';
25
- import { MANIFEST_FILENAME, readManifest } from './manifest.js';
26
- import { isInside, linkTarget, readJson, scanLinks } from './fsops.js';
27
- import { reportError } from './localize.js';
28
- import { explainKept, planPrune, prunesEntry } from './prune.js';
29
- /** @returns {{rows: object[], notLinked: number}} */
15
+ import { describeDrift, driftProblems } from './drift.js';
16
+ import { EXIT_DRIFT } from './errors.js';
17
+ import { currentBranch, legacyManifestHint, reportError, restoreSetAside, } from './localize.js';
18
+ import { localMembers, parkedMembers } from './members.js';
30
19
  export function collect(deps) {
31
- const manifest = readManifest(deps.appRoot, deps);
32
- const dir = path.join(deps.appRoot, manifest.dir);
33
- const rows = [];
34
- for (const [name, entry] of Object.entries(manifest.entries)) {
35
- const checkout = path.join(deps.appRoot, entry.path);
36
- const target = linkTarget(deps.appRoot, name);
37
- if (target && isInside(target, dir)) {
38
- rows.push({
39
- name,
40
- state: 'linked',
41
- path: entry.path,
42
- branch: entry.branch,
43
- note: prunesEntry(entry) ? '' : 'prune: off',
44
- });
45
- }
46
- else if (!fs.existsSync(checkout)) {
47
- // Recorded, but nothing on disk. `localize <name>` re-clones it when the
48
- // entry has a repo or the package is published; otherwise it is restored by hand.
49
- rows.push({
50
- name,
51
- state: 'checkout-missing',
52
- path: entry.path,
53
- branch: '—',
54
- note: 'CHECKOUT MISSING',
55
- });
56
- }
57
- else {
58
- // Intent and checkout present, symlink gone. This is what `npm ci`
59
- // leaves behind, and it is the state that costs hours.
60
- rows.push({
61
- name,
62
- state: 'not-linked',
63
- path: entry.path,
64
- branch: entry.branch,
65
- note: 'checkout present',
66
- });
67
- }
68
- }
69
- for (const m of manifest.malformed) {
70
- rows.push({
71
- name: m.name,
72
- state: 'malformed',
73
- path: '—',
74
- branch: '—',
75
- note: `malformed entry (${m.reason})`,
76
- });
77
- }
78
- // A symlink out of node_modules that the manifest does not know about.
79
- // Reported, never touched.
80
- const untrackedTargets = [];
81
- for (const { name, target } of scanLinks(deps.appRoot)) {
82
- if (manifest.entries[name])
83
- continue;
84
- untrackedTargets.push(target);
85
- rows.push({
86
- name,
87
- state: 'untracked',
88
- path: path.relative(deps.appRoot, target),
89
- branch: '—',
90
- note: `not in ${MANIFEST_FILENAME}`,
91
- });
92
- }
93
- // A directory in the checkout directory with no record (and no link, which
94
- // the row above already reports).
95
- const recorded = Object.values(manifest.entries).map((e) => real(path.join(deps.appRoot, e.path)));
96
- for (const sub of directoriesIn(dir)) {
97
- const abs = real(path.join(dir, sub));
98
- if (recorded.some((r) => r === abs || isInside(r, abs)))
99
- continue;
100
- if (untrackedTargets.some((t) => t === abs || isInside(t, abs)))
101
- continue;
102
- const pkg = readJson(path.join(abs, 'package.json'));
103
- rows.push({
104
- name: typeof (pkg === null || pkg === void 0 ? void 0 : pkg.name) === 'string' ? pkg.name : '—',
105
- state: 'unrecorded',
106
- path: path.join(manifest.dir, sub),
107
- branch: '—',
108
- note: `directory not in ${MANIFEST_FILENAME}`,
109
- });
110
- }
111
- // What pruning keeps, per linked checkout. Informational: a failure here
112
- // must not cost the listing.
113
- try {
114
- const plan = planPrune(manifest.entries, deps);
115
- for (const row of rows) {
116
- if (row.state !== 'linked')
117
- continue;
118
- const kept = plan.keep.filter((k) => k.ownerName === row.name);
119
- if (!kept.length)
120
- continue;
121
- row.kept = kept.map(explainKept);
122
- row.note = `kept ${kept.length} own ${kept.length === 1 ? 'copy' : 'copies'}`;
123
- }
124
- }
125
- catch (_a) {
126
- /* listed without it */
127
- }
128
- const notLinked = rows.filter((r) => r.state === 'not-linked' || r.state === 'checkout-missing').length;
129
- return { rows, notLinked };
20
+ const row = (m, state) => (Object.assign(Object.assign({}, m), { state, branch: currentBranch(path.join(deps.appRoot, m.dir), deps) }));
21
+ return {
22
+ rows: [
23
+ ...localMembers(deps.appRoot).map((m) => row(m, 'localized')),
24
+ ...parkedMembers(deps.appRoot).map((m) => row(m, 'parked')),
25
+ ],
26
+ drift: driftProblems(deps.appRoot),
27
+ };
130
28
  }
131
29
  export function list(opts, deps) {
132
- let result;
30
+ legacyManifestHint(deps);
133
31
  try {
134
- result = collect(deps);
32
+ restoreSetAside(deps);
135
33
  }
136
34
  catch (e) {
137
35
  return reportError(e, deps);
138
36
  }
139
- const { rows, notLinked } = result;
140
- if (!rows.length)
141
- return 0; // nothing localized, nothing to say
142
- const pad = (n, s) => s.padEnd(n);
143
- const nameW = Math.max(...rows.map((r) => r.name.length)) + 2;
144
- const pathW = Math.max(...rows.map((r) => r.path.length)) + 2;
145
- for (const r of rows) {
146
- const label = r.state === 'linked' || r.state === 'untracked'
147
- ? 'linked'
148
- : r.state === 'unrecorded'
149
- ? 'UNRECORDED'
150
- : 'NOT LINKED';
151
- deps.log(pad(nameW, r.name) +
152
- pad(12, label) +
153
- pad(pathW, r.path) +
154
- pad(11, r.branch) +
155
- r.note);
37
+ if (opts.check) {
38
+ const drift = driftProblems(deps.appRoot);
39
+ for (const d of drift)
40
+ deps.warn(`[localize] drift: ${describeDrift(d)}`);
41
+ return drift.length ? EXIT_DRIFT : 0;
156
42
  }
157
- const withKept = rows.filter((r) => { var _a; return (_a = r.kept) === null || _a === void 0 ? void 0 : _a.length; });
158
- if (withKept.length) {
159
- deps.log('');
160
- deps.log("Kept in a checkout's own node_modules (the app's copy cannot replace them, so the app loads two):");
161
- for (const r of withKept)
162
- for (const k of r.kept)
163
- deps.log(` ${k}`);
43
+ const { rows, drift } = collect(deps);
44
+ if (!rows.length && !drift.length)
45
+ return 0; // nothing localized, nothing to say
46
+ if (rows.length) {
47
+ const nameW = Math.max(...rows.map((r) => r.name.length)) + 2;
48
+ const dirW = Math.max(...rows.map((r) => r.dir.length)) + 2;
49
+ const branchW = Math.max(...rows.map((r) => r.branch.length)) + 2;
50
+ for (const r of rows) {
51
+ deps.log(r.name.padEnd(nameW) +
52
+ r.dir.padEnd(dirW) +
53
+ r.branch.padEnd(branchW) +
54
+ (r.version || '—') +
55
+ (r.state === 'parked' ? ' (parked)' : ''));
56
+ }
164
57
  }
58
+ for (const d of drift)
59
+ deps.log(`drift: ${describeDrift(d)}`);
165
60
  const count = (s) => rows.filter((r) => r.state === s).length;
166
- const parts = [`${count('linked')} linked`, `${notLinked} not linked`];
167
- if (count('untracked'))
168
- parts.push(`${count('untracked')} untracked link`);
169
- if (count('malformed'))
170
- parts.push(`${count('malformed')} malformed entry`);
171
- const keptTotal = withKept.reduce((n, r) => n + r.kept.length, 0);
172
- if (keptTotal)
173
- parts.push(`${keptTotal} kept ${keptTotal === 1 ? 'copy' : 'copies'}`);
174
- if (count('unrecorded'))
175
- parts.push(`${count('unrecorded')} unrecorded ${count('unrecorded') === 1 ? 'directory' : 'directories'}`);
176
- deps.log('');
61
+ const parts = [`${count('localized')} localized`];
62
+ if (count('parked'))
63
+ parts.push(`${count('parked')} parked`);
64
+ parts.push(drift.length ? `${drift.length} drift` : 'no drift');
177
65
  deps.log(parts.join(' · '));
178
- return opts.check && notLinked > 0 ? 1 : 0;
179
- }
180
- /** The (non-hidden) directories directly in `dir`, following links; none when it is absent. */
181
- function directoriesIn(dir) {
182
- let names;
183
- try {
184
- names = fs.readdirSync(dir);
185
- }
186
- catch (_a) {
187
- return [];
188
- }
189
- return names.filter((n) => {
190
- if (n.startsWith('.'))
191
- return false;
192
- try {
193
- return fs.statSync(path.join(dir, n)).isDirectory();
194
- }
195
- catch (_a) {
196
- return false;
197
- }
198
- });
199
- }
200
- function real(p) {
201
- try {
202
- return fs.realpathSync(p);
203
- }
204
- catch (_a) {
205
- return p;
206
- }
66
+ return 0;
207
67
  }
208
68
  //# sourceMappingURL=list.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/localize/list.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `--list` -- read the SYMLINKS, then reconcile against the manifest.\n *\n * The manifest records INTENT; the symlink is TRUTH. They can disagree -- most\n * commonly because `npm ci` deleted `node_modules` and exited 0 -- so this\n * reads the links first and reports the disagreement rather than assuming.\n * The four states are distinguished deliberately: both of the silent failures\n * this tool was built to end were disagreements between intent and truth.\n *\n * It also flags a directory in the checkout directory (`packages-local/`) that\n * nothing records and nothing links: every checkout there is meant to be\n * localized, and one that is not loads nobody's code while looking as if it\n * did.\n *\n * For a linked checkout it also says what pruning would keep in that\n * checkout's `node_modules` and why (prune.ts `planPrune`, nothing removed),\n * or that pruning is off for it (`prune: false`): localize, adopt and\n * `--relink` only summarise kept copies, and this is where the reasons are.\n *\n * Never writes. Exits 0, unless `--check` and something recorded is not\n * actually linked.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport {MANIFEST_FILENAME, readManifest} from './manifest.js';\nimport {isInside, linkTarget, readJson, scanLinks} from './fsops.js';\nimport {reportError} from './localize.js';\nimport {explainKept, planPrune, prunesEntry} from './prune.js';\nimport type {Deps} from './run.js';\n\n/** One row of `--list`: a recorded package, or a link the manifest does not know. */\nexport interface ListRow {\n name: string;\n state:\n | 'linked'\n | 'checkout-missing'\n | 'not-linked'\n | 'malformed'\n | 'untracked'\n | 'unrecorded';\n path: string;\n branch: string;\n note: string;\n /** A linked checkout: the copies pruning keeps in it, each with its reason. */\n kept?: string[];\n}\n\n/** @returns {{rows: object[], notLinked: number}} */\nexport function collect(deps: Deps): {rows: ListRow[]; notLinked: number} {\n const manifest = readManifest(deps.appRoot, deps);\n const dir = path.join(deps.appRoot, manifest.dir);\n const rows: ListRow[] = [];\n\n for (const [name, entry] of Object.entries(manifest.entries)) {\n const checkout = path.join(deps.appRoot, entry.path);\n const target = linkTarget(deps.appRoot, name);\n\n if (target && isInside(target, dir)) {\n rows.push({\n name,\n state: 'linked',\n path: entry.path,\n branch: entry.branch,\n note: prunesEntry(entry) ? '' : 'prune: off',\n });\n } else if (!fs.existsSync(checkout)) {\n // Recorded, but nothing on disk. `localize <name>` re-clones it when the\n // entry has a repo or the package is published; otherwise it is restored by hand.\n rows.push({\n name,\n state: 'checkout-missing',\n path: entry.path,\n branch: '—',\n note: 'CHECKOUT MISSING',\n });\n } else {\n // Intent and checkout present, symlink gone. This is what `npm ci`\n // leaves behind, and it is the state that costs hours.\n rows.push({\n name,\n state: 'not-linked',\n path: entry.path,\n branch: entry.branch,\n note: 'checkout present',\n });\n }\n }\n\n for (const m of manifest.malformed) {\n rows.push({\n name: m.name,\n state: 'malformed',\n path: '—',\n branch: '—',\n note: `malformed entry (${m.reason})`,\n });\n }\n\n // A symlink out of node_modules that the manifest does not know about.\n // Reported, never touched.\n const untrackedTargets: string[] = [];\n for (const {name, target} of scanLinks(deps.appRoot)) {\n if (manifest.entries[name]) continue;\n untrackedTargets.push(target);\n rows.push({\n name,\n state: 'untracked',\n path: path.relative(deps.appRoot, target),\n branch: '—',\n note: `not in ${MANIFEST_FILENAME}`,\n });\n }\n\n // A directory in the checkout directory with no record (and no link, which\n // the row above already reports).\n const recorded = Object.values(manifest.entries).map((e) =>\n real(path.join(deps.appRoot, e.path)),\n );\n for (const sub of directoriesIn(dir)) {\n const abs = real(path.join(dir, sub));\n if (recorded.some((r) => r === abs || isInside(r, abs))) continue;\n if (untrackedTargets.some((t) => t === abs || isInside(t, abs))) continue;\n const pkg = readJson(path.join(abs, 'package.json'));\n rows.push({\n name: typeof pkg?.name === 'string' ? pkg.name : '—',\n state: 'unrecorded',\n path: path.join(manifest.dir, sub),\n branch: '—',\n note: `directory not in ${MANIFEST_FILENAME}`,\n });\n }\n\n // What pruning keeps, per linked checkout. Informational: a failure here\n // must not cost the listing.\n try {\n const plan = planPrune(manifest.entries, deps);\n for (const row of rows) {\n if (row.state !== 'linked') continue;\n const kept = plan.keep.filter((k) => k.ownerName === row.name);\n if (!kept.length) continue;\n row.kept = kept.map(explainKept);\n row.note = `kept ${kept.length} own ${kept.length === 1 ? 'copy' : 'copies'}`;\n }\n } catch {\n /* listed without it */\n }\n\n const notLinked = rows.filter(\n (r) => r.state === 'not-linked' || r.state === 'checkout-missing',\n ).length;\n return {rows, notLinked};\n}\n\nexport function list(opts: {check?: boolean}, deps: Deps): number {\n let result;\n try {\n result = collect(deps);\n } catch (e) {\n return reportError(e, deps);\n }\n const {rows, notLinked} = result;\n\n if (!rows.length) return 0; // nothing localized, nothing to say\n\n const pad = (n, s) => s.padEnd(n);\n const nameW = Math.max(...rows.map((r) => r.name.length)) + 2;\n const pathW = Math.max(...rows.map((r) => r.path.length)) + 2;\n for (const r of rows) {\n const label =\n r.state === 'linked' || r.state === 'untracked'\n ? 'linked'\n : r.state === 'unrecorded'\n ? 'UNRECORDED'\n : 'NOT LINKED';\n deps.log(\n pad(nameW, r.name) +\n pad(12, label) +\n pad(pathW, r.path) +\n pad(11, r.branch) +\n r.note,\n );\n }\n\n const withKept = rows.filter((r) => r.kept?.length);\n if (withKept.length) {\n deps.log('');\n deps.log(\n \"Kept in a checkout's own node_modules (the app's copy cannot replace them, so the app loads two):\",\n );\n for (const r of withKept) for (const k of r.kept!) deps.log(` ${k}`);\n }\n\n const count = (s) => rows.filter((r) => r.state === s).length;\n const parts = [`${count('linked')} linked`, `${notLinked} not linked`];\n if (count('untracked')) parts.push(`${count('untracked')} untracked link`);\n if (count('malformed')) parts.push(`${count('malformed')} malformed entry`);\n const keptTotal = withKept.reduce((n, r) => n + r.kept!.length, 0);\n if (keptTotal)\n parts.push(`${keptTotal} kept ${keptTotal === 1 ? 'copy' : 'copies'}`);\n if (count('unrecorded'))\n parts.push(\n `${count('unrecorded')} unrecorded ${count('unrecorded') === 1 ? 'directory' : 'directories'}`,\n );\n deps.log('');\n deps.log(parts.join(' · '));\n\n return opts.check && notLinked > 0 ? 1 : 0;\n}\n\n/** The (non-hidden) directories directly in `dir`, following links; none when it is absent. */\nfunction directoriesIn(dir: string): string[] {\n let names: string[];\n try {\n names = fs.readdirSync(dir);\n } catch {\n return [];\n }\n return names.filter((n) => {\n if (n.startsWith('.')) return false;\n try {\n return fs.statSync(path.join(dir, n)).isDirectory();\n } catch {\n return false;\n }\n });\n}\n\nfunction real(p: string): string {\n try {\n return fs.realpathSync(p);\n } catch {\n return p;\n }\n}\n"]}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/localize/list.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `--list` -- what is localized, what is parked, and the drift (drift.ts).\n *\n * The record is the directories: every checkout in `packages-local/` is a\n * workspace member, every one in `.packages-local.parked/` is parked. A row\n * per checkout -- name, directory, branch, version -- then one line per drift.\n *\n * `--check` is for CI and scripts: it prints only the drift (nothing when\n * there is none) and exits 1 when there is any. (The lock-at-rest hook reports\n * drift itself, with `hooks/drift.cjs`.) It writes nothing, except that\n * checkouts an interrupted set-up left in `packages-local/.setup-aside/` are\n * moved back first, as `localize` and `delocalize` do.\n */\nimport path from 'node:path';\n\nimport {describeDrift, driftProblems} from './drift.js';\nimport type {Drift} from './drift.js';\nimport {EXIT_DRIFT} from './errors.js';\nimport {\n currentBranch,\n legacyManifestHint,\n reportError,\n restoreSetAside,\n} from './localize.js';\nimport {localMembers, parkedMembers} from './members.js';\nimport type {Member} from './members.js';\nimport type {Deps} from './run.js';\n\n/** One row of `--list`. */\nexport interface ListRow extends Member {\n state: 'localized' | 'parked';\n branch: string;\n}\n\nexport function collect(deps: Deps): {rows: ListRow[]; drift: Drift[]} {\n const row = (m: Member, state: ListRow['state']): ListRow => ({\n ...m,\n state,\n branch: currentBranch(path.join(deps.appRoot, m.dir), deps),\n });\n return {\n rows: [\n ...localMembers(deps.appRoot).map((m) => row(m, 'localized')),\n ...parkedMembers(deps.appRoot).map((m) => row(m, 'parked')),\n ],\n drift: driftProblems(deps.appRoot),\n };\n}\n\nexport function list(opts: {check?: boolean}, deps: Deps): number {\n legacyManifestHint(deps);\n try {\n restoreSetAside(deps);\n } catch (e) {\n return reportError(e, deps);\n }\n if (opts.check) {\n const drift = driftProblems(deps.appRoot);\n for (const d of drift) deps.warn(`[localize] drift: ${describeDrift(d)}`);\n return drift.length ? EXIT_DRIFT : 0;\n }\n\n const {rows, drift} = collect(deps);\n if (!rows.length && !drift.length) return 0; // nothing localized, nothing to say\n\n if (rows.length) {\n const nameW = Math.max(...rows.map((r) => r.name.length)) + 2;\n const dirW = Math.max(...rows.map((r) => r.dir.length)) + 2;\n const branchW = Math.max(...rows.map((r) => r.branch.length)) + 2;\n for (const r of rows) {\n deps.log(\n r.name.padEnd(nameW) +\n r.dir.padEnd(dirW) +\n r.branch.padEnd(branchW) +\n (r.version || '—') +\n (r.state === 'parked' ? ' (parked)' : ''),\n );\n }\n }\n for (const d of drift) deps.log(`drift: ${describeDrift(d)}`);\n\n const count = (s: ListRow['state']) =>\n rows.filter((r) => r.state === s).length;\n const parts = [`${count('localized')} localized`];\n if (count('parked')) parts.push(`${count('parked')} parked`);\n parts.push(drift.length ? `${drift.length} drift` : 'no drift');\n deps.log(parts.join(' · '));\n return 0;\n}\n"]}
@@ -1,77 +1,60 @@
1
- import type { ManifestEntry } from './manifest.js';
1
+ import type { Member } from './members.js';
2
2
  import type { Deps } from './run.js';
3
- import type { PruneOptions } from './prune.js';
4
- /**
5
- * @param {string[]} names full npm package names
6
- * @param {object} opts `{force, dir, repo, subdir, build, prune}` -- `prune`
7
- * defaults to true; see prune.ts
8
- * @param {object} deps `{appRoot, run, log, warn, error}`
9
- * @returns {number} the process exit code: the HIGHEST of the per-name codes,
10
- * since each name is atomic and a failure on name 2 does not undo name 1.
11
- */
12
- export interface LocalizeOptions extends PruneOptions {
13
- force?: boolean;
14
- /** Where checkouts live, relative to the app root (default `packages-local`). */
3
+ /** What a new checkout is built with when `--build` does not say. */
4
+ export declare const DEFAULT_BUILD_COMMAND = "linked build";
5
+ /** The one install a run makes, at the app root. */
6
+ export declare const INSTALL_ARGS: string[];
7
+ /** The app's lockfile, kept clean of checkouts. */
8
+ export declare const LOCKFILE = "package-lock.json";
9
+ export interface LocalizeOptions {
10
+ /** Where checkouts live. Only `packages-local` is accepted: the workspace glob names it. */
15
11
  dir?: string;
16
12
  repo?: string;
17
13
  subdir?: string;
18
- /** Run in the checkout after installing; absent or empty runs nothing. */
14
+ /** Run in each new checkout after the install. Absent: the default; empty: no build. */
19
15
  build?: string;
20
16
  }
21
- /** What one name's work returns to the shared loop. */
22
- export interface OneResult {
23
- code: number;
24
- entry?: {
25
- name: string;
26
- value: ManifestEntry;
27
- };
17
+ /** A checkout ready for the install. */
18
+ export interface Prepared {
19
+ name: string;
20
+ /** App-relative, `/`-separated: `packages-local/_linked-core`. */
21
+ dir: string;
22
+ /** Build it after the install: a new clone or an adopted checkout, not a returning parked one. */
23
+ build: boolean;
28
24
  }
29
- export type OneName = (name: string, dir: string, recorded: ManifestEntry | undefined, opts: LocalizeOptions, deps: Deps) => OneResult;
25
+ /** How one name becomes a checkout in `packages-local/`; null when there is nothing to do. */
26
+ export type Prepare = (name: string, opts: LocalizeOptions, deps: Deps) => Prepared | null;
27
+ /**
28
+ * @param names full npm package names
29
+ * @returns the process exit code: the highest of the per-name codes and the
30
+ * install's, since a failure on name 2 does not undo name 1.
31
+ */
30
32
  export declare function localize(names: string[], opts: LocalizeOptions, deps: Deps): number;
31
33
  /**
32
- * The loop `localize` and `adopt` share: read the manifest once, run `one` per
33
- * name, write the manifest after each, then assert the links and the
34
- * consumer's untouched manifests.
35
- *
36
- * @param {(name: string, dir: string, recorded: object|undefined, opts: object, deps: object)
37
- * => {code: number, entry?: {name: string, value: object}}} one
34
+ * The run `localize`, `adopt` and `--parked` share: everything except how a
35
+ * name becomes a checkout. See the module header for the steps.
38
36
  */
39
- export declare function forEachName(names: string[], opts: LocalizeOptions, deps: Deps, one: OneName): number;
37
+ export declare function runLocalize(names: string[], opts: LocalizeOptions, deps: Deps, prepare: Prepare): number;
40
38
  /**
41
- * Everything after the checkout exists, shared by `localize` and `adopt`:
42
- * install inside it, run the configured build, link it, and describe the
43
- * manifest entry. Nothing here knows how the checkout got there.
44
- *
45
- * `repo` may be absent -- an adopted checkout with no remote is recorded
46
- * without one.
39
+ * Steps 4-6: git hooks, one root install, then the builds. `setupLock` is the
40
+ * lockfile the set-up captured (see `captureSetupLockfile`), written back
41
+ * over what the install left.
47
42
  */
48
- export declare function installLinkAndRecord({ npmName, clone, relPkg, pkgDir, repo, subdir, }: {
49
- npmName: string;
50
- clone: string;
51
- relPkg: string;
52
- pkgDir: string;
53
- repo?: string;
54
- subdir?: string;
55
- }, opts: LocalizeOptions, deps: Deps, code?: number): {
56
- code: number;
57
- entry: {
58
- name: string;
59
- value: ManifestEntry;
60
- };
61
- };
62
- /** Refuse when `node_modules/<name>` is already a symlink pointing outside `<dir>`. */
63
- export declare function guardForeignLink(npmName: string, dir: string, opts: {
64
- force?: boolean;
65
- }, deps: Deps): void;
43
+ export declare function installAndBuild(prepared: Prepared[], opts: Pick<LocalizeOptions, 'build'>, deps: Deps, setupLock?: string): number;
44
+ /** Move a parked checkout back into `packages-local/`. No clone, no build: it is as it was. */
45
+ export declare function unpark(member: Member, deps: Deps): Prepared;
46
+ /**
47
+ * A set-up run that was interrupted while the checkouts were in
48
+ * `SETUP_ASIDE_DIR` left them there, where npm does not see them: move them
49
+ * back, saying so. Refuses, moving nothing, when `packages-local/` already
50
+ * has an entry of the same name.
51
+ */
52
+ export declare function restoreSetAside(deps: Pick<Deps, 'appRoot' | 'log'>): void;
66
53
  /**
67
- * The property the whole design rests on: this run changed neither manifest.
68
- *
69
- * Content hashes, not `git status`. `git status` compares against HEAD, so in
70
- * any tree with an uncommitted `package.json` it reports a modification the
71
- * command did not make -- an earlier tool shipped exactly that and reported
72
- * correct runs as failures.
54
+ * One line when an app still has the retired record. It is ignored: the
55
+ * record now is the directories in `packages-local/`.
73
56
  */
74
- export declare function assertManifestsUntouched(before: Record<string, string | null>, deps: Deps): number;
57
+ export declare function legacyManifestHint(deps: Pick<Deps, 'appRoot' | 'warn'>): void;
75
58
  export declare function reportError(e: unknown, deps: Pick<Deps, 'error'>): number;
76
59
  /**
77
60
  * The checked-out branch, or `HEAD` when detached. `symbolic-ref` first,
@@ -79,6 +62,7 @@ export declare function reportError(e: unknown, deps: Pick<Deps, 'error'>): numb
79
62
  * `rev-parse --abbrev-ref` fails there, and `create-package` adopts a fresh
80
63
  * `git init` before its first commit.
81
64
  */
82
- export declare function currentBranch(clone: string, deps: Deps): string;
83
- export declare function declaredRange(name: string, deps: Pick<Deps, 'appRoot'>): string | undefined;
65
+ export declare function currentBranch(checkout: string, deps: Pick<Deps, 'run'>): string;
66
+ /** The last lines of a subprocess's output: enough to see the error, not the whole log. */
67
+ export declare function tail(output: string, lines?: number): string;
84
68
  //# sourceMappingURL=localize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"localize.d.ts","sourceRoot":"","sources":["../../../src/localize/localize.ts"],"names":[],"mappings":"AAsDA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,UAAU,CAAC;AAInC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,YAAY,CAAC;AAY7C;;;;;;;GAOG;AACH,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iFAAiF;IACjF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,uDAAuD;AACvD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,CAAA;KAAC,CAAC;CAC9C;AAED,MAAM,MAAM,OAAO,GAAG,CACpB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,aAAa,GAAG,SAAS,EACnC,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,IAAI,KACP,SAAS,CAAC;AAEf,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,IAAI,GACT,MAAM,CAER;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,OAAO,GACX,MAAM,CAsDR;AAmGD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,EACE,OAAO,EACP,KAAK,EACL,MAAM,EACN,MAAM,EACN,IAAI,EACJ,MAAM,GACP,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,EACD,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,IAAI,EACV,IAAI,SAAI,GACP;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,CAAA;KAAC,CAAA;CAAC,CAsC7D;AAiFD,uFAAuF;AACvF,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAC,EACvB,IAAI,EAAE,IAAI,GACT,IAAI,CAqBN;AA0BD;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,EACrC,IAAI,EAAE,IAAI,GACT,MAAM,CAUR;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,MAAM,CAMzE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAU/D;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,GAC1B,MAAM,GAAG,SAAS,CAQpB"}
1
+ {"version":3,"file":"localize.d.ts","sourceRoot":"","sources":["../../../src/localize/localize.ts"],"names":[],"mappings":"AA2DA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAEzC,OAAO,KAAK,EAAC,IAAI,EAAY,MAAM,UAAU,CAAC;AAG9C,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AAIpD,oDAAoD;AACpD,eAAO,MAAM,YAAY,UAAyC,CAAC;AAUnE,mDAAmD;AACnD,eAAO,MAAM,QAAQ,sBAAsB,CAAC;AAI5C,MAAM,WAAW,eAAe;IAC9B,4FAA4F;IAC5F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wCAAwC;AACxC,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,kGAAkG;IAClG,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,8FAA8F;AAC9F,MAAM,MAAM,OAAO,GAAG,CACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,IAAI,KACP,QAAQ,GAAG,IAAI,CAAC;AAErB;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,IAAI,GACT,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,GACf,MAAM,CAmDR;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,QAAQ,EAAE,EACpB,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,EACpC,IAAI,EAAE,IAAI,EACV,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAiCR;AAuGD,+FAA+F;AAC/F,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,QAAQ,CAuB3D;AAyGD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,IAAI,CA8BzE;AAsFD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,GAAG,IAAI,CAM7E;AAoCD,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,MAAM,CAMzE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,GACtB,MAAM,CAUR;AAED,2FAA2F;AAC3F,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,CAEvD"}