@ebay-dt/bonfire-node 0.2.0-alpha.0 → 0.2.0-alpha.10

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 (32) hide show
  1. package/dist/deployment-provider.d.ts +1 -0
  2. package/dist/deployment-provider.d.ts.map +1 -1
  3. package/dist/deployment-provider.js +1 -0
  4. package/dist/deployment-provider.js.map +1 -1
  5. package/dist/git-repository.d.ts +3 -1
  6. package/dist/git-repository.d.ts.map +1 -1
  7. package/dist/git-repository.js +30 -0
  8. package/dist/git-repository.js.map +1 -1
  9. package/dist/github-cli.d.ts.map +1 -1
  10. package/dist/github-cli.js +3 -1
  11. package/dist/github-cli.js.map +1 -1
  12. package/dist/lifecycle/deployment-worktree.d.ts +35 -0
  13. package/dist/lifecycle/deployment-worktree.d.ts.map +1 -0
  14. package/dist/lifecycle/deployment-worktree.js +302 -0
  15. package/dist/lifecycle/deployment-worktree.js.map +1 -0
  16. package/dist/lifecycle/local-prototype-lifecycle.d.ts +2 -0
  17. package/dist/lifecycle/local-prototype-lifecycle.d.ts.map +1 -1
  18. package/dist/lifecycle/local-prototype-lifecycle.js +170 -54
  19. package/dist/lifecycle/local-prototype-lifecycle.js.map +1 -1
  20. package/dist/lifecycle/repository-summary.d.ts +2 -0
  21. package/dist/lifecycle/repository-summary.d.ts.map +1 -1
  22. package/dist/lifecycle/repository-summary.js +14 -4
  23. package/dist/lifecycle/repository-summary.js.map +1 -1
  24. package/dist/lifecycle/repository-synchronization.d.ts +1 -0
  25. package/dist/lifecycle/repository-synchronization.d.ts.map +1 -1
  26. package/dist/lifecycle/repository-synchronization.js +54 -10
  27. package/dist/lifecycle/repository-synchronization.js.map +1 -1
  28. package/dist/lifecycle/runtime-context.d.ts +2 -0
  29. package/dist/lifecycle/runtime-context.d.ts.map +1 -1
  30. package/dist/lifecycle/runtime-context.js +5 -1
  31. package/dist/lifecycle/runtime-context.js.map +1 -1
  32. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  import { lstat } from "node:fs/promises";
2
2
  import { isAbsolute, resolve } from "node:path";
3
- import { GitRepositoryError, } from "../git-repository.js";
3
+ import { GitRepositoryError, restorePathFromRef, } from "../git-repository.js";
4
4
  const OPERATION_MARKERS = [
5
5
  "MERGE_HEAD",
6
6
  "CHERRY_PICK_HEAD",
@@ -36,7 +36,10 @@ async function markerExists(repository, marker) {
36
36
  return true;
37
37
  }
38
38
  catch (error) {
39
- if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
39
+ if (error &&
40
+ typeof error === "object" &&
41
+ "code" in error &&
42
+ error.code === "ENOENT") {
40
43
  return false;
41
44
  }
42
45
  throw error;
@@ -54,7 +57,11 @@ function hasUnmergedFiles(files) {
54
57
  return files.some((file) => file.index.includes("U") || file.workingDirectory.includes("U"));
55
58
  }
56
59
  async function refCommit(repository, ref) {
57
- const value = await repository.raw(["rev-parse", "--verify", `${ref}^{commit}`]);
60
+ const value = await repository.raw([
61
+ "rev-parse",
62
+ "--verify",
63
+ `${ref}^{commit}`,
64
+ ]);
58
65
  const commit = value.trim();
59
66
  if (!/^[0-9a-f]{40}$/iu.test(commit)) {
60
67
  throw new GitRepositoryError("malformed-output", "ref-commit");
@@ -141,15 +148,12 @@ export async function synchronizeIdentityBranch(repository, options) {
141
148
  if (await hasUnresolvedRepositoryOperation(repository)) {
142
149
  return unsafe(currentBranch, "unresolved-operation");
143
150
  }
144
- const status = await repository.status();
151
+ let status = await repository.status();
145
152
  if (hasUnmergedFiles(status.files)) {
146
153
  return unsafe(currentBranch, "unresolved-operation", {
147
154
  affectedPaths: status.files.map((file) => file.path),
148
155
  });
149
156
  }
150
- if (!status.clean) {
151
- return deferred(currentBranch, "dirty-worktree", status.files.map((file) => file.path));
152
- }
153
157
  const configuredRemote = (await repository.remotes()).some((remote) => remote.name === options.remote);
154
158
  if (configuredRemote) {
155
159
  try {
@@ -190,7 +194,27 @@ export async function synchronizeIdentityBranch(repository, options) {
190
194
  }
191
195
  }
192
196
  const sourceRef = remotePrimary ? primaryRemote : options.primaryBranch;
197
+ const managedPaths = new Set(options.managedPaths ?? []);
198
+ const managedChanges = status.files.flatMap((file) => [file.path, ...(file.from === undefined ? [] : [file.from])].filter((path) => managedPaths.has(path)));
199
+ if (managedChanges.length > 0) {
200
+ for (const path of managedChanges) {
201
+ await restorePathFromRef(repository, sourceRef, path);
202
+ }
203
+ status = await repository.status();
204
+ }
205
+ const remainingDirtyPaths = status.files
206
+ .flatMap((file) => [
207
+ file.path,
208
+ ...(file.from === undefined ? [] : [file.from]),
209
+ ])
210
+ .filter((path) => !managedPaths.has(path));
211
+ if (remainingDirtyPaths.length > 0 ||
212
+ (!status.clean && status.files.length === 0)) {
213
+ return deferred(currentBranch, "dirty-worktree", remainingDirtyPaths);
214
+ }
215
+ let identityCreated = false;
193
216
  if (!localIdentity) {
217
+ identityCreated = true;
194
218
  if (remoteIdentity) {
195
219
  await repository.checkout([
196
220
  "-b",
@@ -242,13 +266,30 @@ export async function synchronizeIdentityBranch(repository, options) {
242
266
  }
243
267
  const afterMerge = await refCommit(repository, options.identityBranch);
244
268
  const changed = beforeMerge !== afterMerge;
269
+ const mergedPaths = changed
270
+ ? (await repository.raw([
271
+ "diff",
272
+ "--name-only",
273
+ "-z",
274
+ `${beforeMerge}..${afterMerge}`,
275
+ ]))
276
+ .split("\0")
277
+ .filter((path) => path.length > 0)
278
+ : [];
279
+ const affectedPaths = [
280
+ ...new Set([
281
+ ...managedChanges,
282
+ ...mergedPaths,
283
+ ...(identityCreated ? [...managedPaths] : []),
284
+ ]),
285
+ ];
245
286
  if (!changed || !configuredRemote) {
246
287
  return {
247
288
  status: "synchronized",
248
289
  branch: options.identityBranch,
249
290
  changed,
250
291
  pushed: false,
251
- affectedPaths: [],
292
+ affectedPaths,
252
293
  };
253
294
  }
254
295
  try {
@@ -257,14 +298,17 @@ export async function synchronizeIdentityBranch(repository, options) {
257
298
  ]);
258
299
  }
259
300
  catch {
260
- return unsafe(options.identityBranch, "push-failed", { changed });
301
+ return unsafe(options.identityBranch, "push-failed", {
302
+ changed,
303
+ affectedPaths,
304
+ });
261
305
  }
262
306
  return {
263
307
  status: "synchronized",
264
308
  branch: options.identityBranch,
265
309
  changed: true,
266
310
  pushed: true,
267
- affectedPaths: [],
311
+ affectedPaths,
268
312
  };
269
313
  }
270
314
  //# sourceMappingURL=repository-synchronization.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"repository-synchronization.js","sourceRoot":"","sources":["../../src/lifecycle/repository-synchronization.ts"],"names":[],"mappings":"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","sourcesContent":["import { lstat } from \"node:fs/promises\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport {\n GitRepositoryError,\n type GitRepository,\n} from \"../git-repository.js\";\n\nexport type SynchronizationDeferredReason =\n | \"dirty-worktree\"\n | \"fetch-failed\"\n | \"merge-conflict\";\n\nexport type SynchronizationUnsafeReason =\n | \"detached-head\"\n | \"unresolved-operation\"\n | \"missing-primary\"\n | \"identity-divergence\"\n | \"failed-abort\"\n | \"merge-failed\"\n | \"push-failed\";\n\ntype SynchronizationBase = {\n branch: string | null;\n changed: boolean;\n pushed: boolean;\n affectedPaths: readonly string[];\n};\n\nexport type RepositorySynchronizationResult =\n | (SynchronizationBase & {\n status: \"synchronized\";\n })\n | (SynchronizationBase & {\n status: \"deferred\";\n reason: SynchronizationDeferredReason;\n })\n | (SynchronizationBase & {\n status: \"unsafe\";\n reason: SynchronizationUnsafeReason;\n });\n\nexport type SynchronizeIdentityBranchOptions = {\n identityBranch: string;\n primaryBranch: string;\n remote: string;\n};\n\nconst OPERATION_MARKERS = [\n \"MERGE_HEAD\",\n \"CHERRY_PICK_HEAD\",\n \"REVERT_HEAD\",\n \"rebase-merge\",\n \"rebase-apply\",\n] as const;\n\nfunction assertBranch(value: string, option: string) {\n if (\n value.length === 0 ||\n value.startsWith(\"-\") ||\n value.includes(\"\\0\") ||\n /\\s/u.test(value) ||\n value.includes(\"@{\") ||\n value.split(/[\\\\/]/u).some((segment) => segment === \"..\")\n ) {\n throw new GitRepositoryError(\"invalid-configuration\", option);\n }\n}\n\nfunction remoteRef(remote: string, branch: string) {\n return `remotes/${remote}/${branch}`;\n}\n\nfunction branchRef(branch: string) {\n return `refs/heads/${branch}`;\n}\n\nasync function markerExists(repository: GitRepository, marker: string) {\n const markerPath = (await repository.raw([\"rev-parse\", \"--git-path\", marker])).trim();\n if (markerPath.length === 0) return false;\n const absolutePath = isAbsolute(markerPath)\n ? markerPath\n : resolve(repository.repositoryRoot, markerPath);\n try {\n await lstat(absolutePath);\n return true;\n } catch (error) {\n if (error && typeof error === \"object\" && \"code\" in error && error.code === \"ENOENT\") {\n return false;\n }\n throw error;\n }\n}\n\nexport async function hasUnresolvedRepositoryOperation(\n repository: GitRepository,\n) {\n for (const marker of OPERATION_MARKERS) {\n if (await markerExists(repository, marker)) return true;\n }\n const status = await repository.status();\n return hasUnmergedFiles(status.files);\n}\n\nfunction hasUnmergedFiles(files: readonly { index: string; workingDirectory: string }[]) {\n return files.some(\n (file) => file.index.includes(\"U\") || file.workingDirectory.includes(\"U\"),\n );\n}\n\nasync function refCommit(repository: GitRepository, ref: string) {\n const value = await repository.raw([\"rev-parse\", \"--verify\", `${ref}^{commit}`]);\n const commit = value.trim();\n if (!/^[0-9a-f]{40}$/iu.test(commit)) {\n throw new GitRepositoryError(\"malformed-output\", \"ref-commit\");\n }\n return commit;\n}\n\nasync function compareRefs(\n repository: GitRepository,\n left: string,\n right: string,\n) {\n const output = await repository.raw([\n \"rev-list\",\n \"--left-right\",\n \"--count\",\n `${left}...${right}`,\n ]);\n const values = output.trim().split(/\\s+/u).map(Number);\n if (\n values.length !== 2 ||\n values.some((value) => !Number.isSafeInteger(value) || value < 0)\n ) {\n throw new GitRepositoryError(\"malformed-output\", \"ref-relation\");\n }\n return { ahead: values[0]!, behind: values[1]! };\n}\n\nasync function safelyAdvanceLocalPrimary(\n repository: GitRepository,\n primaryBranch: string,\n primaryRemoteRef: string,\n localPrimaryCommit: string,\n) {\n await repository.raw([\n \"update-ref\",\n branchRef(primaryBranch),\n primaryRemoteRef,\n localPrimaryCommit,\n ]);\n}\n\nfunction deferred(\n branch: string | null,\n reason: SynchronizationDeferredReason,\n affectedPaths: readonly string[] = [],\n): RepositorySynchronizationResult {\n return {\n status: \"deferred\",\n branch,\n changed: false,\n pushed: false,\n affectedPaths,\n reason,\n };\n}\n\nfunction unsafe(\n branch: string | null,\n reason: SynchronizationUnsafeReason,\n options: Partial<SynchronizationBase> = {},\n): RepositorySynchronizationResult {\n return {\n status: \"unsafe\",\n branch,\n changed: options.changed ?? false,\n pushed: options.pushed ?? false,\n affectedPaths: options.affectedPaths ?? [],\n reason,\n };\n}\n\nexport async function assertIdentityBranchReady(\n repository: GitRepository,\n identityBranch: string,\n): Promise<void> {\n assertBranch(identityBranch, \"identity-branch\");\n const currentBranch = await repository.currentBranch();\n if (currentBranch === \"HEAD\" || currentBranch.length === 0) {\n throw new GitRepositoryError(\"conflict\", \"current-branch\");\n }\n if (currentBranch !== identityBranch) {\n throw new GitRepositoryError(\"conflict\", \"identity-branch\");\n }\n if (await hasUnresolvedRepositoryOperation(repository)) {\n throw new GitRepositoryError(\"conflict\", \"unresolved-operation\");\n }\n const status = await repository.status();\n if (hasUnmergedFiles(status.files)) {\n throw new GitRepositoryError(\"conflict\", \"unresolved-operation\");\n }\n}\n\n/**\n * Synchronize an identity branch from primary without checking out local\n * primary. Remote-tracking refs are the source of truth whenever a configured\n * remote is available. The result distinguishes non-blocking attention from\n * unsafe repository state so callers can keep authentication/read-only flows\n * available.\n */\nexport async function synchronizeIdentityBranch(\n repository: GitRepository,\n options: SynchronizeIdentityBranchOptions,\n): Promise<RepositorySynchronizationResult> {\n assertBranch(options.identityBranch, \"identity-branch\");\n assertBranch(options.primaryBranch, \"primary-branch\");\n assertBranch(options.remote, \"remote\");\n\n if (options.identityBranch === options.primaryBranch) {\n throw new GitRepositoryError(\"invalid-configuration\", \"identity-primary-branch\");\n }\n\n const currentBranch = await repository.currentBranch();\n if (currentBranch === \"HEAD\" || currentBranch.length === 0) {\n return unsafe(null, \"detached-head\");\n }\n\n if (await hasUnresolvedRepositoryOperation(repository)) {\n return unsafe(currentBranch, \"unresolved-operation\");\n }\n\n const status = await repository.status();\n if (hasUnmergedFiles(status.files)) {\n return unsafe(currentBranch, \"unresolved-operation\", {\n affectedPaths: status.files.map((file) => file.path),\n });\n }\n if (!status.clean) {\n return deferred(\n currentBranch,\n \"dirty-worktree\",\n status.files.map((file) => file.path),\n );\n }\n\n const configuredRemote = (await repository.remotes()).some(\n (remote) => remote.name === options.remote,\n );\n if (configuredRemote) {\n try {\n await repository.fetch(options.remote);\n } catch (error) {\n if (\n error instanceof GitRepositoryError &&\n error.kind === \"invalid-configuration\"\n ) {\n throw error;\n }\n return deferred(currentBranch, \"fetch-failed\");\n }\n }\n\n const branches = await repository.branches();\n const localPrimary = branches.all.includes(options.primaryBranch);\n const primaryRemote = remoteRef(options.remote, options.primaryBranch);\n const remotePrimary = configuredRemote && branches.all.includes(primaryRemote);\n if (configuredRemote ? !remotePrimary : !localPrimary) {\n return unsafe(currentBranch, \"missing-primary\");\n }\n\n const localIdentity = branches.all.includes(options.identityBranch);\n const identityRemote = remoteRef(options.remote, options.identityBranch);\n const remoteIdentity =\n configuredRemote && branches.all.includes(identityRemote);\n\n if (localIdentity && remoteIdentity) {\n const relation = await compareRefs(\n repository,\n options.identityBranch,\n identityRemote,\n );\n if (relation.ahead > 0 && relation.behind > 0) {\n return unsafe(currentBranch, \"identity-divergence\");\n }\n }\n\n let primaryAdvance:\n | { localCommit: string; remoteRef: string }\n | undefined;\n if (localPrimary && remotePrimary) {\n const relation = await compareRefs(\n repository,\n options.primaryBranch,\n primaryRemote,\n );\n if (relation.ahead === 0 && relation.behind > 0) {\n primaryAdvance = {\n localCommit: await refCommit(repository, options.primaryBranch),\n remoteRef: primaryRemote,\n };\n }\n }\n\n const sourceRef = remotePrimary ? primaryRemote : options.primaryBranch;\n if (!localIdentity) {\n if (remoteIdentity) {\n await repository.checkout([\n \"-b\",\n options.identityBranch,\n \"--track\",\n `${options.remote}/${options.identityBranch}`,\n ]);\n } else {\n await repository.checkout([\"-b\", options.identityBranch, sourceRef]);\n }\n } else if (currentBranch !== options.identityBranch) {\n await repository.checkout([options.identityBranch]);\n }\n\n if (primaryAdvance && currentBranch !== options.primaryBranch) {\n await safelyAdvanceLocalPrimary(\n repository,\n options.primaryBranch,\n primaryAdvance.remoteRef,\n primaryAdvance.localCommit,\n );\n }\n\n if (localIdentity && remoteIdentity) {\n const relation = await compareRefs(\n repository,\n options.identityBranch,\n identityRemote,\n );\n if (relation.ahead === 0 && relation.behind > 0) {\n await repository.merge([identityRemote, \"--ff-only\"]);\n }\n }\n\n const beforeMerge = await refCommit(repository, options.identityBranch);\n try {\n await repository.merge([sourceRef, \"--no-edit\"]);\n } catch (error) {\n if (!(error instanceof GitRepositoryError) || error.kind !== \"conflict\") {\n return unsafe(options.identityBranch, \"merge-failed\");\n }\n let affectedPaths: readonly string[] = [];\n try {\n affectedPaths = (await repository.status()).files.map((file) => file.path);\n } catch {\n // Preserve the conflict classification even if status cannot be read.\n }\n try {\n await repository.raw([\"merge\", \"--abort\"]);\n } catch {\n return unsafe(options.identityBranch, \"failed-abort\", {\n affectedPaths,\n });\n }\n return deferred(options.identityBranch, \"merge-conflict\", affectedPaths);\n }\n\n const afterMerge = await refCommit(repository, options.identityBranch);\n const changed = beforeMerge !== afterMerge;\n if (!changed || !configuredRemote) {\n return {\n status: \"synchronized\",\n branch: options.identityBranch,\n changed,\n pushed: false,\n affectedPaths: [],\n };\n }\n\n try {\n await repository.push(options.remote, options.identityBranch, [\n \"--set-upstream\",\n ]);\n } catch {\n return unsafe(options.identityBranch, \"push-failed\", { changed });\n }\n\n return {\n status: \"synchronized\",\n branch: options.identityBranch,\n changed: true,\n pushed: true,\n affectedPaths: [],\n };\n}\n"]}
1
+ {"version":3,"file":"repository-synchronization.js","sourceRoot":"","sources":["../../src/lifecycle/repository-synchronization.ts"],"names":[],"mappings":"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","sourcesContent":["import { lstat } from \"node:fs/promises\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport {\n GitRepositoryError,\n restorePathFromRef,\n type GitRepository,\n} from \"../git-repository.js\";\n\nexport type SynchronizationDeferredReason =\n \"dirty-worktree\" | \"fetch-failed\" | \"merge-conflict\";\n\nexport type SynchronizationUnsafeReason =\n | \"detached-head\"\n | \"unresolved-operation\"\n | \"missing-primary\"\n | \"identity-divergence\"\n | \"failed-abort\"\n | \"merge-failed\"\n | \"push-failed\";\n\ntype SynchronizationBase = {\n branch: string | null;\n changed: boolean;\n pushed: boolean;\n affectedPaths: readonly string[];\n};\n\nexport type RepositorySynchronizationResult =\n | (SynchronizationBase & {\n status: \"synchronized\";\n })\n | (SynchronizationBase & {\n status: \"deferred\";\n reason: SynchronizationDeferredReason;\n })\n | (SynchronizationBase & {\n status: \"unsafe\";\n reason: SynchronizationUnsafeReason;\n });\n\nexport type SynchronizeIdentityBranchOptions = {\n identityBranch: string;\n primaryBranch: string;\n remote: string;\n managedPaths?: readonly string[];\n};\n\nconst OPERATION_MARKERS = [\n \"MERGE_HEAD\",\n \"CHERRY_PICK_HEAD\",\n \"REVERT_HEAD\",\n \"rebase-merge\",\n \"rebase-apply\",\n] as const;\n\nfunction assertBranch(value: string, option: string) {\n if (\n value.length === 0 ||\n value.startsWith(\"-\") ||\n value.includes(\"\\0\") ||\n /\\s/u.test(value) ||\n value.includes(\"@{\") ||\n value.split(/[\\\\/]/u).some((segment) => segment === \"..\")\n ) {\n throw new GitRepositoryError(\"invalid-configuration\", option);\n }\n}\n\nfunction remoteRef(remote: string, branch: string) {\n return `remotes/${remote}/${branch}`;\n}\n\nfunction branchRef(branch: string) {\n return `refs/heads/${branch}`;\n}\n\nasync function markerExists(repository: GitRepository, marker: string) {\n const markerPath = (\n await repository.raw([\"rev-parse\", \"--git-path\", marker])\n ).trim();\n if (markerPath.length === 0) return false;\n const absolutePath = isAbsolute(markerPath)\n ? markerPath\n : resolve(repository.repositoryRoot, markerPath);\n try {\n await lstat(absolutePath);\n return true;\n } catch (error) {\n if (\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return false;\n }\n throw error;\n }\n}\n\nexport async function hasUnresolvedRepositoryOperation(\n repository: GitRepository,\n) {\n for (const marker of OPERATION_MARKERS) {\n if (await markerExists(repository, marker)) return true;\n }\n const status = await repository.status();\n return hasUnmergedFiles(status.files);\n}\n\nfunction hasUnmergedFiles(\n files: readonly { index: string; workingDirectory: string }[],\n) {\n return files.some(\n (file) => file.index.includes(\"U\") || file.workingDirectory.includes(\"U\"),\n );\n}\n\nasync function refCommit(repository: GitRepository, ref: string) {\n const value = await repository.raw([\n \"rev-parse\",\n \"--verify\",\n `${ref}^{commit}`,\n ]);\n const commit = value.trim();\n if (!/^[0-9a-f]{40}$/iu.test(commit)) {\n throw new GitRepositoryError(\"malformed-output\", \"ref-commit\");\n }\n return commit;\n}\n\nasync function compareRefs(\n repository: GitRepository,\n left: string,\n right: string,\n) {\n const output = await repository.raw([\n \"rev-list\",\n \"--left-right\",\n \"--count\",\n `${left}...${right}`,\n ]);\n const values = output.trim().split(/\\s+/u).map(Number);\n if (\n values.length !== 2 ||\n values.some((value) => !Number.isSafeInteger(value) || value < 0)\n ) {\n throw new GitRepositoryError(\"malformed-output\", \"ref-relation\");\n }\n return { ahead: values[0]!, behind: values[1]! };\n}\n\nasync function safelyAdvanceLocalPrimary(\n repository: GitRepository,\n primaryBranch: string,\n primaryRemoteRef: string,\n localPrimaryCommit: string,\n) {\n await repository.raw([\n \"update-ref\",\n branchRef(primaryBranch),\n primaryRemoteRef,\n localPrimaryCommit,\n ]);\n}\n\nfunction deferred(\n branch: string | null,\n reason: SynchronizationDeferredReason,\n affectedPaths: readonly string[] = [],\n): RepositorySynchronizationResult {\n return {\n status: \"deferred\",\n branch,\n changed: false,\n pushed: false,\n affectedPaths,\n reason,\n };\n}\n\nfunction unsafe(\n branch: string | null,\n reason: SynchronizationUnsafeReason,\n options: Partial<SynchronizationBase> = {},\n): RepositorySynchronizationResult {\n return {\n status: \"unsafe\",\n branch,\n changed: options.changed ?? false,\n pushed: options.pushed ?? false,\n affectedPaths: options.affectedPaths ?? [],\n reason,\n };\n}\n\nexport async function assertIdentityBranchReady(\n repository: GitRepository,\n identityBranch: string,\n): Promise<void> {\n assertBranch(identityBranch, \"identity-branch\");\n const currentBranch = await repository.currentBranch();\n if (currentBranch === \"HEAD\" || currentBranch.length === 0) {\n throw new GitRepositoryError(\"conflict\", \"current-branch\");\n }\n if (currentBranch !== identityBranch) {\n throw new GitRepositoryError(\"conflict\", \"identity-branch\");\n }\n if (await hasUnresolvedRepositoryOperation(repository)) {\n throw new GitRepositoryError(\"conflict\", \"unresolved-operation\");\n }\n const status = await repository.status();\n if (hasUnmergedFiles(status.files)) {\n throw new GitRepositoryError(\"conflict\", \"unresolved-operation\");\n }\n}\n\n/**\n * Synchronize an identity branch from primary without checking out local\n * primary. Remote-tracking refs are the source of truth whenever a configured\n * remote is available. The result distinguishes non-blocking attention from\n * unsafe repository state so callers can keep authentication/read-only flows\n * available.\n */\nexport async function synchronizeIdentityBranch(\n repository: GitRepository,\n options: SynchronizeIdentityBranchOptions,\n): Promise<RepositorySynchronizationResult> {\n assertBranch(options.identityBranch, \"identity-branch\");\n assertBranch(options.primaryBranch, \"primary-branch\");\n assertBranch(options.remote, \"remote\");\n\n if (options.identityBranch === options.primaryBranch) {\n throw new GitRepositoryError(\n \"invalid-configuration\",\n \"identity-primary-branch\",\n );\n }\n\n const currentBranch = await repository.currentBranch();\n if (currentBranch === \"HEAD\" || currentBranch.length === 0) {\n return unsafe(null, \"detached-head\");\n }\n\n if (await hasUnresolvedRepositoryOperation(repository)) {\n return unsafe(currentBranch, \"unresolved-operation\");\n }\n\n let status = await repository.status();\n if (hasUnmergedFiles(status.files)) {\n return unsafe(currentBranch, \"unresolved-operation\", {\n affectedPaths: status.files.map((file) => file.path),\n });\n }\n\n const configuredRemote = (await repository.remotes()).some(\n (remote) => remote.name === options.remote,\n );\n if (configuredRemote) {\n try {\n await repository.fetch(options.remote);\n } catch (error) {\n if (\n error instanceof GitRepositoryError &&\n error.kind === \"invalid-configuration\"\n ) {\n throw error;\n }\n return deferred(currentBranch, \"fetch-failed\");\n }\n }\n\n const branches = await repository.branches();\n const localPrimary = branches.all.includes(options.primaryBranch);\n const primaryRemote = remoteRef(options.remote, options.primaryBranch);\n const remotePrimary =\n configuredRemote && branches.all.includes(primaryRemote);\n if (configuredRemote ? !remotePrimary : !localPrimary) {\n return unsafe(currentBranch, \"missing-primary\");\n }\n\n const localIdentity = branches.all.includes(options.identityBranch);\n const identityRemote = remoteRef(options.remote, options.identityBranch);\n const remoteIdentity =\n configuredRemote && branches.all.includes(identityRemote);\n\n if (localIdentity && remoteIdentity) {\n const relation = await compareRefs(\n repository,\n options.identityBranch,\n identityRemote,\n );\n if (relation.ahead > 0 && relation.behind > 0) {\n return unsafe(currentBranch, \"identity-divergence\");\n }\n }\n\n let primaryAdvance: { localCommit: string; remoteRef: string } | undefined;\n if (localPrimary && remotePrimary) {\n const relation = await compareRefs(\n repository,\n options.primaryBranch,\n primaryRemote,\n );\n if (relation.ahead === 0 && relation.behind > 0) {\n primaryAdvance = {\n localCommit: await refCommit(repository, options.primaryBranch),\n remoteRef: primaryRemote,\n };\n }\n }\n\n const sourceRef = remotePrimary ? primaryRemote : options.primaryBranch;\n const managedPaths = new Set(options.managedPaths ?? []);\n const managedChanges = status.files.flatMap((file) =>\n [file.path, ...(file.from === undefined ? [] : [file.from])].filter(\n (path) => managedPaths.has(path),\n ),\n );\n if (managedChanges.length > 0) {\n for (const path of managedChanges) {\n await restorePathFromRef(repository, sourceRef, path);\n }\n status = await repository.status();\n }\n const remainingDirtyPaths = status.files\n .flatMap((file) => [\n file.path,\n ...(file.from === undefined ? [] : [file.from]),\n ])\n .filter((path) => !managedPaths.has(path));\n if (\n remainingDirtyPaths.length > 0 ||\n (!status.clean && status.files.length === 0)\n ) {\n return deferred(currentBranch, \"dirty-worktree\", remainingDirtyPaths);\n }\n\n let identityCreated = false;\n if (!localIdentity) {\n identityCreated = true;\n if (remoteIdentity) {\n await repository.checkout([\n \"-b\",\n options.identityBranch,\n \"--track\",\n `${options.remote}/${options.identityBranch}`,\n ]);\n } else {\n await repository.checkout([\"-b\", options.identityBranch, sourceRef]);\n }\n } else if (currentBranch !== options.identityBranch) {\n await repository.checkout([options.identityBranch]);\n }\n\n if (primaryAdvance && currentBranch !== options.primaryBranch) {\n await safelyAdvanceLocalPrimary(\n repository,\n options.primaryBranch,\n primaryAdvance.remoteRef,\n primaryAdvance.localCommit,\n );\n }\n\n if (localIdentity && remoteIdentity) {\n const relation = await compareRefs(\n repository,\n options.identityBranch,\n identityRemote,\n );\n if (relation.ahead === 0 && relation.behind > 0) {\n await repository.merge([identityRemote, \"--ff-only\"]);\n }\n }\n\n const beforeMerge = await refCommit(repository, options.identityBranch);\n try {\n await repository.merge([sourceRef, \"--no-edit\"]);\n } catch (error) {\n if (!(error instanceof GitRepositoryError) || error.kind !== \"conflict\") {\n return unsafe(options.identityBranch, \"merge-failed\");\n }\n let affectedPaths: readonly string[] = [];\n try {\n affectedPaths = (await repository.status()).files.map(\n (file) => file.path,\n );\n } catch {\n // Preserve the conflict classification even if status cannot be read.\n }\n try {\n await repository.raw([\"merge\", \"--abort\"]);\n } catch {\n return unsafe(options.identityBranch, \"failed-abort\", {\n affectedPaths,\n });\n }\n return deferred(options.identityBranch, \"merge-conflict\", affectedPaths);\n }\n\n const afterMerge = await refCommit(repository, options.identityBranch);\n const changed = beforeMerge !== afterMerge;\n const mergedPaths = changed\n ? (\n await repository.raw([\n \"diff\",\n \"--name-only\",\n \"-z\",\n `${beforeMerge}..${afterMerge}`,\n ])\n )\n .split(\"\\0\")\n .filter((path) => path.length > 0)\n : [];\n const affectedPaths = [\n ...new Set([\n ...managedChanges,\n ...mergedPaths,\n ...(identityCreated ? [...managedPaths] : []),\n ]),\n ];\n if (!changed || !configuredRemote) {\n return {\n status: \"synchronized\",\n branch: options.identityBranch,\n changed,\n pushed: false,\n affectedPaths,\n };\n }\n\n try {\n await repository.push(options.remote, options.identityBranch, [\n \"--set-upstream\",\n ]);\n } catch {\n return unsafe(options.identityBranch, \"push-failed\", {\n changed,\n affectedPaths,\n });\n }\n\n return {\n status: \"synchronized\",\n branch: options.identityBranch,\n changed: true,\n pushed: true,\n affectedPaths,\n };\n}\n"]}
@@ -7,6 +7,7 @@ export type PrototypeLifecycleRuntimeOptions = PrototypeCatalogOptions & {
7
7
  commitIdentity?: GitCommitIdentity;
8
8
  automaticBranchSwitch?: AutomaticBranchSwitchMode;
9
9
  gitMode?: GitMode;
10
+ managedRepositoryPaths?: readonly string[];
10
11
  gitRepository?: GitRepository;
11
12
  };
12
13
  export type PrototypeLifecycleRuntimeContext = ResolvedPrototypeCatalogPaths & {
@@ -15,6 +16,7 @@ export type PrototypeLifecycleRuntimeContext = ResolvedPrototypeCatalogPaths & {
15
16
  primaryBranch: string;
16
17
  automaticBranchSwitch: AutomaticBranchSwitchMode;
17
18
  gitMode: GitMode;
19
+ managedRepositoryPaths: readonly string[];
18
20
  commitIdentity: Readonly<GitCommitIdentity>;
19
21
  gitRepository: GitRepository;
20
22
  };
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-context.d.ts","sourceRoot":"","sources":["../../src/lifecycle/runtime-context.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,OAAO,EACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,6BAA6B,EACnC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAS9B,MAAM,MAAM,gCAAgC,GAAG,uBAAuB,GAAG;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,iBAAiB,CAAC;IACnC,qBAAqB,CAAC,EAAE,yBAAyB,CAAC;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,6BAA6B,GAAG;IAC7E,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,yBAAyB,CAAC;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC5C,aAAa,EAAE,aAAa,CAAC;CAC9B,CAAC;AASF,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,gCAAgC,GACxC,gCAAgC,CA8BlC","sourcesContent":["import { realpathSync } from \"node:fs\";\nimport {\n parseGitModeSetting,\n type AutomaticBranchSwitchMode,\n type GitMode,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n resolvePrototypeCatalogPaths,\n type PrototypeCatalogOptions,\n type ResolvedPrototypeCatalogPaths,\n} from \"../prototype-paths.js\";\nimport {\n createGitRepository,\n type GitCommitIdentity,\n type GitRepository,\n} from \"../git-repository.js\";\n\nconst DEFAULT_REMOTE = \"origin\";\nconst DEFAULT_PRIMARY_BRANCH = \"main\";\nconst DEFAULT_COMMIT_IDENTITY: GitCommitIdentity = {\n name: \"Bonfire\",\n email: \"bonfire@localhost\",\n};\n\nexport type PrototypeLifecycleRuntimeOptions = PrototypeCatalogOptions & {\n remote?: string;\n primaryBranch?: string;\n commitIdentity?: GitCommitIdentity;\n automaticBranchSwitch?: AutomaticBranchSwitchMode;\n gitMode?: GitMode;\n gitRepository?: GitRepository;\n};\n\nexport type PrototypeLifecycleRuntimeContext = ResolvedPrototypeCatalogPaths & {\n repositoryRealPath: string;\n remote: string;\n primaryBranch: string;\n automaticBranchSwitch: AutomaticBranchSwitchMode;\n gitMode: GitMode;\n commitIdentity: Readonly<GitCommitIdentity>;\n gitRepository: GitRepository;\n};\n\nfunction requireNonEmptyOption(value: string | undefined, option: string) {\n if (value !== undefined && value.length === 0) {\n throw new TypeError(`${option} must be a nonempty string`);\n }\n return value;\n}\n\nexport function createPrototypeLifecycleRuntime(\n options: PrototypeLifecycleRuntimeOptions,\n): PrototypeLifecycleRuntimeContext {\n const paths = resolvePrototypeCatalogPaths(options);\n const repositoryRealPath = realpathSync(paths.repositoryRoot);\n const remote =\n requireNonEmptyOption(options.remote, \"remote\") ?? DEFAULT_REMOTE;\n const primaryBranch =\n requireNonEmptyOption(options.primaryBranch, \"primaryBranch\") ??\n DEFAULT_PRIMARY_BRANCH;\n const automaticBranchSwitch = options.automaticBranchSwitch ?? \"enabled\";\n const gitMode = parseGitModeSetting(options.gitMode);\n const commitIdentity = Object.freeze({\n ...DEFAULT_COMMIT_IDENTITY,\n ...options.commitIdentity,\n });\n\n return {\n ...paths,\n repositoryRealPath,\n remote,\n primaryBranch,\n automaticBranchSwitch,\n gitMode,\n commitIdentity,\n gitRepository:\n options.gitRepository ??\n createGitRepository({\n repositoryRoot: paths.repositoryRoot,\n commitIdentity,\n }),\n };\n}\n"]}
1
+ {"version":3,"file":"runtime-context.d.ts","sourceRoot":"","sources":["../../src/lifecycle/runtime-context.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,yBAAyB,EAC9B,KAAK,OAAO,EACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,6BAA6B,EACnC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAS9B,MAAM,MAAM,gCAAgC,GAAG,uBAAuB,GAAG;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,iBAAiB,CAAC;IACnC,qBAAqB,CAAC,EAAE,yBAAyB,CAAC;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sBAAsB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,6BAA6B,GAAG;IAC7E,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,yBAAyB,CAAC;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,sBAAsB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,cAAc,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC5C,aAAa,EAAE,aAAa,CAAC;CAC9B,CAAC;AASF,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,gCAAgC,GACxC,gCAAgC,CAkClC","sourcesContent":["import { realpathSync } from \"node:fs\";\nimport {\n MANAGED_REPOSITORY_PATHS,\n parseGitModeSetting,\n type AutomaticBranchSwitchMode,\n type GitMode,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n resolvePrototypeCatalogPaths,\n type PrototypeCatalogOptions,\n type ResolvedPrototypeCatalogPaths,\n} from \"../prototype-paths.js\";\nimport {\n createGitRepository,\n type GitCommitIdentity,\n type GitRepository,\n} from \"../git-repository.js\";\n\nconst DEFAULT_REMOTE = \"origin\";\nconst DEFAULT_PRIMARY_BRANCH = \"main\";\nconst DEFAULT_COMMIT_IDENTITY: GitCommitIdentity = {\n name: \"Bonfire\",\n email: \"bonfire@localhost\",\n};\n\nexport type PrototypeLifecycleRuntimeOptions = PrototypeCatalogOptions & {\n remote?: string;\n primaryBranch?: string;\n commitIdentity?: GitCommitIdentity;\n automaticBranchSwitch?: AutomaticBranchSwitchMode;\n gitMode?: GitMode;\n managedRepositoryPaths?: readonly string[];\n gitRepository?: GitRepository;\n};\n\nexport type PrototypeLifecycleRuntimeContext = ResolvedPrototypeCatalogPaths & {\n repositoryRealPath: string;\n remote: string;\n primaryBranch: string;\n automaticBranchSwitch: AutomaticBranchSwitchMode;\n gitMode: GitMode;\n managedRepositoryPaths: readonly string[];\n commitIdentity: Readonly<GitCommitIdentity>;\n gitRepository: GitRepository;\n};\n\nfunction requireNonEmptyOption(value: string | undefined, option: string) {\n if (value !== undefined && value.length === 0) {\n throw new TypeError(`${option} must be a nonempty string`);\n }\n return value;\n}\n\nexport function createPrototypeLifecycleRuntime(\n options: PrototypeLifecycleRuntimeOptions,\n): PrototypeLifecycleRuntimeContext {\n const paths = resolvePrototypeCatalogPaths(options);\n const repositoryRealPath = realpathSync(paths.repositoryRoot);\n const remote =\n requireNonEmptyOption(options.remote, \"remote\") ?? DEFAULT_REMOTE;\n const primaryBranch =\n requireNonEmptyOption(options.primaryBranch, \"primaryBranch\") ??\n DEFAULT_PRIMARY_BRANCH;\n const automaticBranchSwitch = options.automaticBranchSwitch ?? \"enabled\";\n const gitMode = parseGitModeSetting(options.gitMode);\n const managedRepositoryPaths = Object.freeze([\n ...(options.managedRepositoryPaths ?? MANAGED_REPOSITORY_PATHS),\n ]);\n const commitIdentity = Object.freeze({\n ...DEFAULT_COMMIT_IDENTITY,\n ...options.commitIdentity,\n });\n\n return {\n ...paths,\n repositoryRealPath,\n remote,\n primaryBranch,\n automaticBranchSwitch,\n gitMode,\n managedRepositoryPaths,\n commitIdentity,\n gitRepository:\n options.gitRepository ??\n createGitRepository({\n repositoryRoot: paths.repositoryRoot,\n commitIdentity,\n }),\n };\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { realpathSync } from "node:fs";
2
- import { parseGitModeSetting, } from "@ebay-dt/bonfire-core";
2
+ import { MANAGED_REPOSITORY_PATHS, parseGitModeSetting, } from "@ebay-dt/bonfire-core";
3
3
  import { resolvePrototypeCatalogPaths, } from "../prototype-paths.js";
4
4
  import { createGitRepository, } from "../git-repository.js";
5
5
  const DEFAULT_REMOTE = "origin";
@@ -22,6 +22,9 @@ export function createPrototypeLifecycleRuntime(options) {
22
22
  DEFAULT_PRIMARY_BRANCH;
23
23
  const automaticBranchSwitch = options.automaticBranchSwitch ?? "enabled";
24
24
  const gitMode = parseGitModeSetting(options.gitMode);
25
+ const managedRepositoryPaths = Object.freeze([
26
+ ...(options.managedRepositoryPaths ?? MANAGED_REPOSITORY_PATHS),
27
+ ]);
25
28
  const commitIdentity = Object.freeze({
26
29
  ...DEFAULT_COMMIT_IDENTITY,
27
30
  ...options.commitIdentity,
@@ -33,6 +36,7 @@ export function createPrototypeLifecycleRuntime(options) {
33
36
  primaryBranch,
34
37
  automaticBranchSwitch,
35
38
  gitMode,
39
+ managedRepositoryPaths,
36
40
  commitIdentity,
37
41
  gitRepository: options.gitRepository ??
38
42
  createGitRepository({
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-context.js","sourceRoot":"","sources":["../../src/lifecycle/runtime-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EACL,mBAAmB,GAGpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,4BAA4B,GAG7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,GAGpB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,cAAc,GAAG,QAAQ,CAAC;AAChC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AACtC,MAAM,uBAAuB,GAAsB;IACjD,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,mBAAmB;CAC3B,CAAC;AAqBF,SAAS,qBAAqB,CAAC,KAAyB,EAAE,MAAc;IACtE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,SAAS,CAAC,GAAG,MAAM,4BAA4B,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,OAAyC;IAEzC,MAAM,KAAK,GAAG,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,kBAAkB,GAAG,YAAY,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9D,MAAM,MAAM,GACV,qBAAqB,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,cAAc,CAAC;IACpE,MAAM,aAAa,GACjB,qBAAqB,CAAC,OAAO,CAAC,aAAa,EAAE,eAAe,CAAC;QAC7D,sBAAsB,CAAC;IACzB,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,IAAI,SAAS,CAAC;IACzE,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;QACnC,GAAG,uBAAuB;QAC1B,GAAG,OAAO,CAAC,cAAc;KAC1B,CAAC,CAAC;IAEH,OAAO;QACL,GAAG,KAAK;QACR,kBAAkB;QAClB,MAAM;QACN,aAAa;QACb,qBAAqB;QACrB,OAAO;QACP,cAAc;QACd,aAAa,EACX,OAAO,CAAC,aAAa;YACrB,mBAAmB,CAAC;gBAClB,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,cAAc;aACf,CAAC;KACL,CAAC;AACJ,CAAC","sourcesContent":["import { realpathSync } from \"node:fs\";\nimport {\n parseGitModeSetting,\n type AutomaticBranchSwitchMode,\n type GitMode,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n resolvePrototypeCatalogPaths,\n type PrototypeCatalogOptions,\n type ResolvedPrototypeCatalogPaths,\n} from \"../prototype-paths.js\";\nimport {\n createGitRepository,\n type GitCommitIdentity,\n type GitRepository,\n} from \"../git-repository.js\";\n\nconst DEFAULT_REMOTE = \"origin\";\nconst DEFAULT_PRIMARY_BRANCH = \"main\";\nconst DEFAULT_COMMIT_IDENTITY: GitCommitIdentity = {\n name: \"Bonfire\",\n email: \"bonfire@localhost\",\n};\n\nexport type PrototypeLifecycleRuntimeOptions = PrototypeCatalogOptions & {\n remote?: string;\n primaryBranch?: string;\n commitIdentity?: GitCommitIdentity;\n automaticBranchSwitch?: AutomaticBranchSwitchMode;\n gitMode?: GitMode;\n gitRepository?: GitRepository;\n};\n\nexport type PrototypeLifecycleRuntimeContext = ResolvedPrototypeCatalogPaths & {\n repositoryRealPath: string;\n remote: string;\n primaryBranch: string;\n automaticBranchSwitch: AutomaticBranchSwitchMode;\n gitMode: GitMode;\n commitIdentity: Readonly<GitCommitIdentity>;\n gitRepository: GitRepository;\n};\n\nfunction requireNonEmptyOption(value: string | undefined, option: string) {\n if (value !== undefined && value.length === 0) {\n throw new TypeError(`${option} must be a nonempty string`);\n }\n return value;\n}\n\nexport function createPrototypeLifecycleRuntime(\n options: PrototypeLifecycleRuntimeOptions,\n): PrototypeLifecycleRuntimeContext {\n const paths = resolvePrototypeCatalogPaths(options);\n const repositoryRealPath = realpathSync(paths.repositoryRoot);\n const remote =\n requireNonEmptyOption(options.remote, \"remote\") ?? DEFAULT_REMOTE;\n const primaryBranch =\n requireNonEmptyOption(options.primaryBranch, \"primaryBranch\") ??\n DEFAULT_PRIMARY_BRANCH;\n const automaticBranchSwitch = options.automaticBranchSwitch ?? \"enabled\";\n const gitMode = parseGitModeSetting(options.gitMode);\n const commitIdentity = Object.freeze({\n ...DEFAULT_COMMIT_IDENTITY,\n ...options.commitIdentity,\n });\n\n return {\n ...paths,\n repositoryRealPath,\n remote,\n primaryBranch,\n automaticBranchSwitch,\n gitMode,\n commitIdentity,\n gitRepository:\n options.gitRepository ??\n createGitRepository({\n repositoryRoot: paths.repositoryRoot,\n commitIdentity,\n }),\n };\n}\n"]}
1
+ {"version":3,"file":"runtime-context.js","sourceRoot":"","sources":["../../src/lifecycle/runtime-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EACL,wBAAwB,EACxB,mBAAmB,GAGpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,4BAA4B,GAG7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,GAGpB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,cAAc,GAAG,QAAQ,CAAC;AAChC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AACtC,MAAM,uBAAuB,GAAsB;IACjD,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,mBAAmB;CAC3B,CAAC;AAuBF,SAAS,qBAAqB,CAAC,KAAyB,EAAE,MAAc;IACtE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,SAAS,CAAC,GAAG,MAAM,4BAA4B,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,OAAyC;IAEzC,MAAM,KAAK,GAAG,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,kBAAkB,GAAG,YAAY,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9D,MAAM,MAAM,GACV,qBAAqB,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,cAAc,CAAC;IACpE,MAAM,aAAa,GACjB,qBAAqB,CAAC,OAAO,CAAC,aAAa,EAAE,eAAe,CAAC;QAC7D,sBAAsB,CAAC;IACzB,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,IAAI,SAAS,CAAC;IACzE,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC;QAC3C,GAAG,CAAC,OAAO,CAAC,sBAAsB,IAAI,wBAAwB,CAAC;KAChE,CAAC,CAAC;IACH,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;QACnC,GAAG,uBAAuB;QAC1B,GAAG,OAAO,CAAC,cAAc;KAC1B,CAAC,CAAC;IAEH,OAAO;QACL,GAAG,KAAK;QACR,kBAAkB;QAClB,MAAM;QACN,aAAa;QACb,qBAAqB;QACrB,OAAO;QACP,sBAAsB;QACtB,cAAc;QACd,aAAa,EACX,OAAO,CAAC,aAAa;YACrB,mBAAmB,CAAC;gBAClB,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,cAAc;aACf,CAAC;KACL,CAAC;AACJ,CAAC","sourcesContent":["import { realpathSync } from \"node:fs\";\nimport {\n MANAGED_REPOSITORY_PATHS,\n parseGitModeSetting,\n type AutomaticBranchSwitchMode,\n type GitMode,\n} from \"@ebay-dt/bonfire-core\";\nimport {\n resolvePrototypeCatalogPaths,\n type PrototypeCatalogOptions,\n type ResolvedPrototypeCatalogPaths,\n} from \"../prototype-paths.js\";\nimport {\n createGitRepository,\n type GitCommitIdentity,\n type GitRepository,\n} from \"../git-repository.js\";\n\nconst DEFAULT_REMOTE = \"origin\";\nconst DEFAULT_PRIMARY_BRANCH = \"main\";\nconst DEFAULT_COMMIT_IDENTITY: GitCommitIdentity = {\n name: \"Bonfire\",\n email: \"bonfire@localhost\",\n};\n\nexport type PrototypeLifecycleRuntimeOptions = PrototypeCatalogOptions & {\n remote?: string;\n primaryBranch?: string;\n commitIdentity?: GitCommitIdentity;\n automaticBranchSwitch?: AutomaticBranchSwitchMode;\n gitMode?: GitMode;\n managedRepositoryPaths?: readonly string[];\n gitRepository?: GitRepository;\n};\n\nexport type PrototypeLifecycleRuntimeContext = ResolvedPrototypeCatalogPaths & {\n repositoryRealPath: string;\n remote: string;\n primaryBranch: string;\n automaticBranchSwitch: AutomaticBranchSwitchMode;\n gitMode: GitMode;\n managedRepositoryPaths: readonly string[];\n commitIdentity: Readonly<GitCommitIdentity>;\n gitRepository: GitRepository;\n};\n\nfunction requireNonEmptyOption(value: string | undefined, option: string) {\n if (value !== undefined && value.length === 0) {\n throw new TypeError(`${option} must be a nonempty string`);\n }\n return value;\n}\n\nexport function createPrototypeLifecycleRuntime(\n options: PrototypeLifecycleRuntimeOptions,\n): PrototypeLifecycleRuntimeContext {\n const paths = resolvePrototypeCatalogPaths(options);\n const repositoryRealPath = realpathSync(paths.repositoryRoot);\n const remote =\n requireNonEmptyOption(options.remote, \"remote\") ?? DEFAULT_REMOTE;\n const primaryBranch =\n requireNonEmptyOption(options.primaryBranch, \"primaryBranch\") ??\n DEFAULT_PRIMARY_BRANCH;\n const automaticBranchSwitch = options.automaticBranchSwitch ?? \"enabled\";\n const gitMode = parseGitModeSetting(options.gitMode);\n const managedRepositoryPaths = Object.freeze([\n ...(options.managedRepositoryPaths ?? MANAGED_REPOSITORY_PATHS),\n ]);\n const commitIdentity = Object.freeze({\n ...DEFAULT_COMMIT_IDENTITY,\n ...options.commitIdentity,\n });\n\n return {\n ...paths,\n repositoryRealPath,\n remote,\n primaryBranch,\n automaticBranchSwitch,\n gitMode,\n managedRepositoryPaths,\n commitIdentity,\n gitRepository:\n options.gitRepository ??\n createGitRepository({\n repositoryRoot: paths.repositoryRoot,\n commitIdentity,\n }),\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ebay-dt/bonfire-node",
3
- "version": "0.2.0-alpha.0",
3
+ "version": "0.2.0-alpha.10",
4
4
  "description": "Node.js adapters for Bonfire.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -31,7 +31,7 @@
31
31
  "access": "public"
32
32
  },
33
33
  "dependencies": {
34
- "@ebay-dt/bonfire-core": "0.2.0-alpha.0",
34
+ "@ebay-dt/bonfire-core": "0.2.0-alpha.10",
35
35
  "chokidar": "^5.0.0",
36
36
  "simple-git": "^3.36.0"
37
37
  },