MCPcopy Create free account
hub / github.com/TestSprite/testsprite-cli / runCodePut

Function runCodePut

src/commands/test.ts:3329–3459  ·  view source on GitHub ↗
(
  opts: CodePutOptions,
  deps: TestDeps = {},
)

Source from the content-addressed store, hash-verified

3327 * sense (v3 → v4 bump). Matches piece-2's pattern.
3328 */
3329export async function runCodePut(
3330 opts: CodePutOptions,
3331 deps: TestDeps = {},
3332): Promise<CliPutTestCodeResponse> {
3333 assertIdempotencyKey(opts.idempotencyKey);
3334 requireNonEmpty('test-id', opts.testId);
3335 requireNonEmpty('code-file', opts.codeFile);
3336
3337 if (opts.expectedVersion !== undefined && opts.force === true) {
3338 throw localValidationError(
3339 'expected-version',
3340 'is mutually exclusive with --force; pass one or the other (or neither for auto-fetch)',
3341 );
3342 }
3343 if (opts.language !== undefined && !CODE_PUT_LANGUAGES.includes(opts.language)) {
3344 throw localValidationError('language', `must be one of: ${CODE_PUT_LANGUAGES.join(', ')}`, [
3345 ...CODE_PUT_LANGUAGES,
3346 ]);
3347 }
3348
3349 const code = opts.dryRun ? DRY_RUN_PLACEHOLDER_CODE : readCodeFileGuarded(opts.codeFile);
3350
3351 const idempotencyKey = opts.idempotencyKey ?? `cli-code-put-${randomUUID()}`;
3352 if (opts.idempotencyKey === undefined && (opts.output === 'json' || opts.verbose || opts.debug)) {
3353 const stderr = deps.stderr ?? ((line: string) => process.stderr.write(`${line}\n`));
3354 stderr(`idempotency-key: ${idempotencyKey}`);
3355 }
3356
3357 // Resolve the If-Match header. Three cases:
3358 // 1. --force → '*' (skip etag check; audit-logged)
3359 // 2. --expected-version <v> → that string verbatim
3360 // 3. neither → auto-fetch via GET /tests/{id}/code, use
3361 // returned codeVersion. Tell the user (stderr)
3362 // so an operator watching can see the race
3363 // window we just opened.
3364 const client = makeClient(opts, deps);
3365 let ifMatch: string;
3366 if (opts.force === true) {
3367 ifMatch = '*';
3368 } else if (opts.expectedVersion !== undefined) {
3369 requireNonEmpty('expected-version', opts.expectedVersion);
3370 ifMatch = opts.expectedVersion;
3371 } else {
3372 const fetched = await client.get<CliTestCode>(`/tests/${encodeURIComponent(opts.testId)}/code`);
3373 const cv = fetched.codeVersion;
3374 if (cv === null || cv === undefined) {
3375 // Server hasn't stamped a codeVersion yet (legacy row). Send `*`
3376 // so the backend's force path applies the bump. Audit will mark
3377 // force: true — visible signal that our auto-fetch hit a
3378 // legacy row, not a concurrent-write race.
3379 ifMatch = '*';
3380 const stderr = deps.stderr ?? ((line: string) => process.stderr.write(`${line}\n`));
3381 stderr(
3382 `auto-fetched codeVersion=null on legacy row; using If-Match: * for this put. Pass --expected-version explicitly to avoid this fallback.`,
3383 );
3384 } else {
3385 ifMatch = cv;
3386 const stderr = deps.stderr ?? ((line: string) => process.stderr.write(`${line}\n`));

Callers 2

test.test.tsFile · 0.85
createTestCodeCommandFunction · 0.85

Calls 11

assertIdempotencyKeyFunction · 0.85
requireNonEmptyFunction · 0.85
readCodeFileGuardedFunction · 0.85
stderrFunction · 0.85
renderCodePutTextFunction · 0.85
fromEnvelopeMethod · 0.80
printMethod · 0.80
getDetailMethod · 0.80
localValidationErrorFunction · 0.70
makeClientFunction · 0.70
makeOutputFunction · 0.70

Tested by

no test coverage detected