@lumpcode/core 0.1.1 → 0.3.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.
- package/README.md +15 -13
- package/dist/helpers/execAsync/main.d.ts +14 -9
- package/dist/helpers/execAsync/main.d.ts.map +1 -1
- package/dist/helpers/executeStepsForContextList/main.d.ts +4 -9
- package/dist/helpers/executeStepsForContextList/main.d.ts.map +1 -1
- package/dist/index.cjs +97 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +96 -68
- package/dist/index.js.map +1 -1
- package/dist/testing/processTreeTestHelpers.d.ts +3 -0
- package/dist/testing/processTreeTestHelpers.d.ts.map +1 -1
- package/dist/types/ExecuteStepsFailureReason.d.ts +1 -1
- package/dist/types/ExecuteStepsFailureReason.d.ts.map +1 -1
- package/dist/types/GitAddCommitFn.d.ts +16 -0
- package/dist/types/GitAddCommitFn.d.ts.map +1 -0
- package/dist/types/GitPushFn.d.ts +12 -0
- package/dist/types/GitPushFn.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/usages/runLump/defaultInjectedFns.d.ts +3 -4
- package/dist/usages/runLump/defaultInjectedFns.d.ts.map +1 -1
- package/dist/usages/runLump/index.d.ts +1 -1
- package/dist/usages/runLump/index.d.ts.map +1 -1
- package/dist/usages/runLump/main.d.ts +3 -4
- package/dist/usages/runLump/main.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3584,32 +3584,54 @@ async function killProcessTree(input) {
|
|
|
3584
3584
|
}
|
|
3585
3585
|
|
|
3586
3586
|
const execAsyncBase = promisify(exec);
|
|
3587
|
+
/** Same signal Node's `exec` `timeout` option uses by default. */
|
|
3588
|
+
const EXEC_TIMEOUT_KILL_SIGNAL = 'SIGTERM';
|
|
3589
|
+
function isExecTimeout(error, timeoutMillis) {
|
|
3590
|
+
if (timeoutMillis === undefined) {
|
|
3591
|
+
return false;
|
|
3592
|
+
}
|
|
3593
|
+
if (typeof error !== 'object' || error === null) {
|
|
3594
|
+
return false;
|
|
3595
|
+
}
|
|
3596
|
+
const execError = error;
|
|
3597
|
+
if (execError.killed !== true) {
|
|
3598
|
+
return false;
|
|
3599
|
+
}
|
|
3600
|
+
// Windows has no POSIX signals; Node force-kills and `signal` is often null.
|
|
3601
|
+
if (process.platform === 'win32') {
|
|
3602
|
+
return true;
|
|
3603
|
+
}
|
|
3604
|
+
return execError.signal === EXEC_TIMEOUT_KILL_SIGNAL;
|
|
3605
|
+
}
|
|
3587
3606
|
async function execAsync(command, options) {
|
|
3588
|
-
const
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3607
|
+
const timeoutMillis = options?.timeoutMillis;
|
|
3608
|
+
try {
|
|
3609
|
+
const result = await execAsyncBase(command, {
|
|
3610
|
+
cwd: options?.cwd,
|
|
3611
|
+
...(timeoutMillis !== undefined
|
|
3612
|
+
? { timeout: timeoutMillis, killSignal: EXEC_TIMEOUT_KILL_SIGNAL }
|
|
3613
|
+
: {}),
|
|
3614
|
+
});
|
|
3615
|
+
return success({
|
|
3616
|
+
stdout: String(result.stdout),
|
|
3617
|
+
stderr: String(result.stderr),
|
|
3618
|
+
});
|
|
3619
|
+
}
|
|
3620
|
+
catch (e) {
|
|
3621
|
+
const timedOut = isExecTimeout(e, timeoutMillis);
|
|
3622
|
+
const reason = timedOut ? 'timeout' : 'exit';
|
|
3600
3623
|
return failure({
|
|
3601
|
-
message:
|
|
3624
|
+
message: timedOut
|
|
3625
|
+
? `Command ${command} timed out after ${timeoutMillis}ms`
|
|
3626
|
+
: `Command ${command} failed with error: ${e}`,
|
|
3627
|
+
reason,
|
|
3602
3628
|
info: {
|
|
3603
3629
|
command,
|
|
3604
|
-
stdout,
|
|
3605
|
-
stderr,
|
|
3630
|
+
stdout: e,
|
|
3631
|
+
stderr: e,
|
|
3606
3632
|
},
|
|
3607
3633
|
});
|
|
3608
3634
|
}
|
|
3609
|
-
return success({
|
|
3610
|
-
stdout,
|
|
3611
|
-
stderr,
|
|
3612
|
-
});
|
|
3613
3635
|
}
|
|
3614
3636
|
|
|
3615
3637
|
function execBinary(input) {
|
|
@@ -3827,28 +3849,37 @@ async function awaitUnlessAborted(work, signal) {
|
|
|
3827
3849
|
});
|
|
3828
3850
|
});
|
|
3829
3851
|
}
|
|
3830
|
-
|
|
3831
|
-
|
|
3852
|
+
/**
|
|
3853
|
+
* Result-aware runner for `gitAddCommitFn` / `gitPushFn`.
|
|
3854
|
+
* nullish Success → no-op; empty string / Failure / throw / exec fail → failed.
|
|
3855
|
+
*/
|
|
3856
|
+
async function runGitResultHook(input) {
|
|
3857
|
+
const { getResult, cwd, logger, execLabel } = input;
|
|
3832
3858
|
try {
|
|
3833
|
-
const
|
|
3834
|
-
if (command == null || command === '') {
|
|
3835
|
-
return 'ok';
|
|
3836
|
-
}
|
|
3837
|
-
const result = await execAsync(command, { cwd });
|
|
3838
|
-
logger.verbose(`${label} ${JSON.stringify(result)}`);
|
|
3859
|
+
const result = await getResult();
|
|
3839
3860
|
if (!result.success) {
|
|
3840
|
-
|
|
3841
|
-
|
|
3861
|
+
return { status: 'failed', detail: result.data };
|
|
3862
|
+
}
|
|
3863
|
+
const command = result.data;
|
|
3864
|
+
if (command == null) {
|
|
3865
|
+
return { status: 'ok' };
|
|
3866
|
+
}
|
|
3867
|
+
if (command === '') {
|
|
3868
|
+
return { status: 'failed', detail: 'empty command string' };
|
|
3869
|
+
}
|
|
3870
|
+
const execResult = await execAsync(command, { cwd });
|
|
3871
|
+
logger.verbose(`${execLabel} ${JSON.stringify(execResult)}`);
|
|
3872
|
+
if (!execResult.success) {
|
|
3873
|
+
return { status: 'failed', detail: execResult.data.message };
|
|
3842
3874
|
}
|
|
3843
|
-
return 'ok';
|
|
3875
|
+
return { status: 'ok' };
|
|
3844
3876
|
}
|
|
3845
3877
|
catch (error) {
|
|
3846
3878
|
const message = error instanceof Error ? error.message : String(error);
|
|
3847
|
-
|
|
3848
|
-
return 'failed';
|
|
3879
|
+
return { status: 'failed', detail: message };
|
|
3849
3880
|
}
|
|
3850
3881
|
}
|
|
3851
|
-
async function executeStepsForContextList({ baseBranch, branchFn, lumpVariables, contextList,
|
|
3882
|
+
async function executeStepsForContextList({ baseBranch, branchFn, lumpVariables, contextList, gitAddCommitFn, gitPushFn, gitCommitMessageFn, projectRoot, steps, setupFn, setupWorkspaceFn, teardownFn, teardownWorkspaceFn, getKeepHistoryFilePathFn, logger: loggerInput, signal, }) {
|
|
3852
3883
|
const logger = loggerInput ?? createConsoleLogger({});
|
|
3853
3884
|
const contextNames = contextList.map(context => context.name);
|
|
3854
3885
|
logger.verbose(`contextNames ${JSON.stringify(contextNames)}`);
|
|
@@ -3874,7 +3905,9 @@ async function executeStepsForContextList({ baseBranch, branchFn, lumpVariables,
|
|
|
3874
3905
|
});
|
|
3875
3906
|
logger.verbose(`setupWorkspaceCommandExec ${JSON.stringify(setupWorkspaceCommandExec)}`);
|
|
3876
3907
|
if (!setupWorkspaceCommandExec.success) {
|
|
3877
|
-
return
|
|
3908
|
+
return failure({
|
|
3909
|
+
message: `Failed to setup the workspace: ${setupWorkspaceCommandExec.data.message}`,
|
|
3910
|
+
});
|
|
3878
3911
|
}
|
|
3879
3912
|
if (afterExec) {
|
|
3880
3913
|
await afterExec({ workspacePath });
|
|
@@ -4056,43 +4089,42 @@ async function executeStepsForContextList({ baseBranch, branchFn, lumpVariables,
|
|
|
4056
4089
|
runFailure = stepWalkFailure;
|
|
4057
4090
|
break;
|
|
4058
4091
|
}
|
|
4059
|
-
const
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4092
|
+
const commitMessage = gitCommitMessageFn({ context, lumpVariables, baseBranch });
|
|
4093
|
+
const addCommitExecLabel = `git add+commit for context ${context.name}`;
|
|
4094
|
+
const addCommitOutcome = await runGitResultHook({
|
|
4095
|
+
getResult: () => gitAddCommitFn({
|
|
4096
|
+
...injectedGitAndWorkspaceFnsInput,
|
|
4097
|
+
context,
|
|
4098
|
+
commitMessage,
|
|
4099
|
+
}),
|
|
4066
4100
|
cwd: workspacePath,
|
|
4067
4101
|
logger,
|
|
4102
|
+
execLabel: addCommitExecLabel,
|
|
4068
4103
|
});
|
|
4069
|
-
if (
|
|
4104
|
+
if (addCommitOutcome.status === 'failed') {
|
|
4105
|
+
const message = `Failed to add and commit for context ${context.name}: ${addCommitOutcome.detail}`;
|
|
4106
|
+
logger.error(message);
|
|
4070
4107
|
runFailure = {
|
|
4071
4108
|
success: false,
|
|
4072
4109
|
data: {
|
|
4073
|
-
message
|
|
4110
|
+
message,
|
|
4111
|
+
reason: 'gitAddCommitFailed',
|
|
4074
4112
|
},
|
|
4075
4113
|
};
|
|
4076
4114
|
break;
|
|
4077
4115
|
}
|
|
4078
|
-
const commitMessage = gitCommitMessageFn({ context, lumpVariables, baseBranch });
|
|
4079
|
-
await runOptionalGitCommand({
|
|
4080
|
-
label: `git commit for context ${context.name}`,
|
|
4081
|
-
getCommand: () => gitCommitCommandFn({
|
|
4082
|
-
...perContextInput,
|
|
4083
|
-
commitMessage,
|
|
4084
|
-
}),
|
|
4085
|
-
cwd: workspacePath,
|
|
4086
|
-
logger,
|
|
4087
|
-
});
|
|
4088
4116
|
}
|
|
4089
4117
|
if (!runFailure) {
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4118
|
+
const pushExecLabel = `git push on branch ${branchName}`;
|
|
4119
|
+
const pushOutcome = await runGitResultHook({
|
|
4120
|
+
getResult: () => gitPushFn(injectedGitAndWorkspaceFnsInput),
|
|
4093
4121
|
cwd: workspacePath,
|
|
4094
4122
|
logger,
|
|
4123
|
+
execLabel: pushExecLabel,
|
|
4095
4124
|
});
|
|
4125
|
+
if (pushOutcome.status === 'failed') {
|
|
4126
|
+
logger.error(`Failed to ${pushExecLabel}: ${pushOutcome.detail}`);
|
|
4127
|
+
}
|
|
4096
4128
|
}
|
|
4097
4129
|
}
|
|
4098
4130
|
finally {
|
|
@@ -4357,14 +4389,11 @@ const contextStatus = ['toDo', 'branchPushed', 'finished'];
|
|
|
4357
4389
|
const defaultGitCommitMessageFn = ({ context }) => {
|
|
4358
4390
|
return `LUMP:${context.name}`;
|
|
4359
4391
|
};
|
|
4360
|
-
const
|
|
4361
|
-
return `git
|
|
4362
|
-
};
|
|
4363
|
-
const defaultGitAddCommandFn = () => {
|
|
4364
|
-
return `git add .`;
|
|
4392
|
+
const defaultGitAddCommitFn = (input) => {
|
|
4393
|
+
return success(`git add . && git commit --allow-empty -m ${shellSingleQuote(input.commitMessage)}`);
|
|
4365
4394
|
};
|
|
4366
|
-
const
|
|
4367
|
-
return `git
|
|
4395
|
+
const defaultGitPushFn = (input) => {
|
|
4396
|
+
return success(`git push origin ${shellSingleQuote(input.branchName)}`);
|
|
4368
4397
|
};
|
|
4369
4398
|
const defaultSetupWorkspaceFn = async (input) => {
|
|
4370
4399
|
const { baseBranch, branchName } = input;
|
|
@@ -4402,7 +4431,7 @@ const defaultSetupWorkspaceFnWithWorktree = async (input) => {
|
|
|
4402
4431
|
};
|
|
4403
4432
|
|
|
4404
4433
|
async function runLump(input) {
|
|
4405
|
-
const { baseBranch, branchFn, lumpVariables: lumpVariablesInput, getContextListFn,
|
|
4434
|
+
const { baseBranch, branchFn, lumpVariables: lumpVariablesInput, getContextListFn, gitAddCommitFn = defaultGitAddCommitFn, gitCommitMessageFn = defaultGitCommitMessageFn, gitPushFn = defaultGitPushFn, numberOfContextsPerBranch = 1, projectRoot, steps, setupFn = () => ({ contextRunState: {} }), setupWorkspaceFn = defaultSetupWorkspaceFn, teardownFn = () => undefined, teardownWorkspaceFn = defaultTeardownWorkspaceFn, getKeepHistoryFilePathFn = () => undefined, logger: loggerInput, signal, refreshRemoteTrackingRefsFn, } = input;
|
|
4406
4435
|
const lumpVariables = (lumpVariablesInput ?? {});
|
|
4407
4436
|
const logger = loggerInput ?? createConsoleLogger({});
|
|
4408
4437
|
const contextListToDoResult = await getToDoContextList({
|
|
@@ -4437,10 +4466,9 @@ async function runLump(input) {
|
|
|
4437
4466
|
branchFn: branchFn,
|
|
4438
4467
|
lumpVariables: lumpVariables,
|
|
4439
4468
|
contextList: nextContextsForBranchList,
|
|
4440
|
-
|
|
4441
|
-
gitCommitCommandFn,
|
|
4469
|
+
gitAddCommitFn,
|
|
4442
4470
|
gitCommitMessageFn,
|
|
4443
|
-
|
|
4471
|
+
gitPushFn,
|
|
4444
4472
|
projectRoot,
|
|
4445
4473
|
steps,
|
|
4446
4474
|
setupFn,
|
|
@@ -4459,5 +4487,5 @@ async function runLump(input) {
|
|
|
4459
4487
|
});
|
|
4460
4488
|
}
|
|
4461
4489
|
|
|
4462
|
-
export { GIT_LOG_HASH_BODY_FORMAT, appendHistoryEntry, collectStepsForContext, commitMessageIncludesMarker, contextStatus, createConsoleLogger,
|
|
4490
|
+
export { GIT_LOG_HASH_BODY_FORMAT, appendHistoryEntry, collectStepsForContext, commitMessageIncludesMarker, contextStatus, createConsoleLogger, defaultGitAddCommitFn, defaultGitCommitMessageFn, defaultGitPushFn, defaultSetupWorkspaceFn, defaultSetupWorkspaceFnWithWorktree, defaultTeardownWorkspaceFn, defaultTeardownWorkspaceFnWithWorktree, execAsync, execBinary, executeStepsForContextList, failure, formatExecFailureMessage, getCodeBasePaths, getContextStatus, getToDoContextList, historyFormatFromPath, isProcessAlive, killProcessTree, nodeErrnoCode, parseGitLogHashBodyRecords, parseGitLogHashSubjectLines, pathExists, readHistoryFile, refreshRemoteTrackingRefs, resolveSpawnExecutable, runLump, set, shellSingleQuote, success, validateContextListNames, windowsNpmCmdShimBody, writeHistoryFile };
|
|
4463
4491
|
//# sourceMappingURL=index.js.map
|