@dezkareid/osddt 1.11.13 → 1.12.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/dist/commands/copy-env.d.ts +2 -0
- package/dist/index.js +119 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -254,13 +254,24 @@ ${npxCommand} start-worktree <feature-name> --dir <package-path>
|
|
|
254
254
|
|
|
255
255
|
4. Parse the command output to extract \`worktreePath\` and \`workingDir\`.
|
|
256
256
|
|
|
257
|
-
5.
|
|
257
|
+
5. Copy environment files into the new worktree. Read \`bare-path\` and \`mainBranch\` from \`.osddtrc\` to construct the source path:
|
|
258
|
+
- Single repo (\`repoType: "single"\`):
|
|
259
|
+
\`\`\`
|
|
260
|
+
${npxCommand} copy-env --source <bare-path>/<mainBranch> --target <worktreePath>
|
|
261
|
+
\`\`\`
|
|
262
|
+
- Monorepo (\`repoType: "monorepo"\`):
|
|
263
|
+
\`\`\`
|
|
264
|
+
${npxCommand} copy-env --source <bare-path>/<mainBranch>/<package-path> --target <worktreePath>/<package-path>
|
|
265
|
+
\`\`\`
|
|
266
|
+
If the command finds no files, it exits silently — this is not an error.
|
|
267
|
+
|
|
268
|
+
6. Navigate into the worktree directory to locate the project:
|
|
258
269
|
- Enter \`<worktreePath>\` — this is the isolated git worktree for this feature.
|
|
259
270
|
- If \`repoType\` is \`"single"\`: the project root is \`<worktreePath>\`.
|
|
260
271
|
- If \`repoType\` is \`"monorepo"\`: the project root is \`<worktreePath>/<package-path>\`.
|
|
261
272
|
- The planning files will live under \`<workingDir>\` (i.e. \`<project-root>/working-on/<feature-name>/\`).
|
|
262
273
|
|
|
263
|
-
|
|
274
|
+
7. Report the branch name, worktree path, project root, and working directory.
|
|
264
275
|
|
|
265
276
|
---
|
|
266
277
|
|
|
@@ -519,6 +530,17 @@ ${npxCommand} start-worktree <feature-name> --dir <package-path>
|
|
|
519
530
|
|
|
520
531
|
4. Parse the command output to extract \`worktreePath\` and \`workingDir\`. Navigate into \`<worktreePath>\` to locate the project root.
|
|
521
532
|
|
|
533
|
+
5. Copy environment files into the new worktree. Read \`bare-path\` and \`mainBranch\` from \`.osddtrc\` to construct the source path:
|
|
534
|
+
- Single repo (\`repoType: "single"\`):
|
|
535
|
+
\`\`\`
|
|
536
|
+
${npxCommand} copy-env --source <bare-path>/<mainBranch> --target <worktreePath>
|
|
537
|
+
\`\`\`
|
|
538
|
+
- Monorepo (\`repoType: "monorepo"\`):
|
|
539
|
+
\`\`\`
|
|
540
|
+
${npxCommand} copy-env --source <bare-path>/<mainBranch>/<package-path> --target <worktreePath>/<package-path>
|
|
541
|
+
\`\`\`
|
|
542
|
+
If the command finds no files, it exits silently — this is not an error.
|
|
543
|
+
|
|
522
544
|
#### If \`worktree-repository\` is **absent** — Standard workflow
|
|
523
545
|
|
|
524
546
|
3. Check whether the branch already exists locally or remotely:
|
|
@@ -603,21 +625,13 @@ ${npxCommand} worktree-info <feature-name>
|
|
|
603
625
|
|
|
604
626
|
**If it exits with code 0 (worktree feature):** parse the JSON to get \`worktreePath\` and \`branch\`, derive \`<project-path>\` from \`workingDir\`, then continue below.
|
|
605
627
|
|
|
606
|
-
4.
|
|
607
|
-
\`\`\`
|
|
608
|
-
${npxCommand} done <feature-name> --dir <project-path> --worktree
|
|
609
|
-
\`\`\`
|
|
610
|
-
|
|
611
|
-
5. The command will automatically prefix the destination folder name with today's date in \`YYYY-MM-DD\` format.
|
|
612
|
-
For example, \`working-on/feature-a\` will be moved to \`done/YYYY-MM-DD-feature-a\`.
|
|
613
|
-
|
|
614
|
-
6. Check for uncommitted changes inside the worktree:
|
|
628
|
+
4. Check for uncommitted changes inside the worktree:
|
|
615
629
|
|
|
616
630
|
\`\`\`
|
|
617
631
|
git -C <worktreePath> status --porcelain
|
|
618
632
|
\`\`\`
|
|
619
633
|
|
|
620
|
-
|
|
634
|
+
5. If there are **uncommitted changes**:
|
|
621
635
|
1. Run \`git -C <worktreePath> diff\` to inspect them.
|
|
622
636
|
2. Derive a concise commit message in **conventional commit** format (e.g. \`feat: add payment gateway integration\`) based on the diff.
|
|
623
637
|
3. Present the proposed message to the user: _"Use this commit message, or provide your own?"_
|
|
@@ -627,12 +641,20 @@ ${npxCommand} worktree-info <feature-name>
|
|
|
627
641
|
git -C <worktreePath> commit -m "<confirmed-message>"
|
|
628
642
|
\`\`\`
|
|
629
643
|
|
|
630
|
-
|
|
644
|
+
6. Push the branch to remote (covers both first push and subsequent pushes):
|
|
631
645
|
|
|
632
646
|
\`\`\`
|
|
633
647
|
git -C <worktreePath> push --set-upstream origin <branch>
|
|
634
648
|
\`\`\`
|
|
635
649
|
|
|
650
|
+
7. Run the done command with the \`--worktree\` flag:
|
|
651
|
+
\`\`\`
|
|
652
|
+
${npxCommand} done <feature-name> --dir <project-path> --worktree
|
|
653
|
+
\`\`\`
|
|
654
|
+
|
|
655
|
+
8. The command will automatically prefix the destination folder name with today's date in \`YYYY-MM-DD\` format.
|
|
656
|
+
For example, \`working-on/feature-a\` will be moved to \`done/YYYY-MM-DD-feature-a\`.
|
|
657
|
+
|
|
636
658
|
9. Report the result of the command, including the full destination path
|
|
637
659
|
|
|
638
660
|
${getCustomContextStep(npxCommand, 'done')}`,
|
|
@@ -1019,6 +1041,19 @@ async function runDone(featureName, cwd, worktree) {
|
|
|
1019
1041
|
console.error(`Error: working-on/${featureName} does not exist.`);
|
|
1020
1042
|
process.exit(1);
|
|
1021
1043
|
}
|
|
1044
|
+
if (worktree && worktreePath && (await fs.pathExists(worktreePath))) {
|
|
1045
|
+
try {
|
|
1046
|
+
const status = execSync('git status --porcelain', { cwd: worktreePath, encoding: 'utf8', stdio: 'pipe' });
|
|
1047
|
+
if (status.trim().length > 0) {
|
|
1048
|
+
console.error('Error: Worktree has uncommitted changes. Commit or stash them before running osddt done.');
|
|
1049
|
+
process.exit(1);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
catch {
|
|
1053
|
+
console.error('Error: Could not verify worktree status. Ensure the worktree is a valid git repository and has no uncommitted changes before proceeding.');
|
|
1054
|
+
process.exit(1);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1022
1057
|
await fs.ensureDir(path.dirname(dest));
|
|
1023
1058
|
await fs.move(src, dest);
|
|
1024
1059
|
console.log(`Moved: working-on/${featureName} → done/${destName}`);
|
|
@@ -1379,6 +1414,76 @@ function worktreeInfoCommand() {
|
|
|
1379
1414
|
return cmd;
|
|
1380
1415
|
}
|
|
1381
1416
|
|
|
1417
|
+
function matchesPatterns(filename, patterns) {
|
|
1418
|
+
return patterns.some((pattern) => {
|
|
1419
|
+
// Convert glob pattern to regex: only support leading/trailing * and literal chars
|
|
1420
|
+
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*');
|
|
1421
|
+
return new RegExp(`^${escaped}$`).test(filename);
|
|
1422
|
+
});
|
|
1423
|
+
}
|
|
1424
|
+
async function readRc(cwd) {
|
|
1425
|
+
const rcPath = path.join(cwd, '.osddtrc');
|
|
1426
|
+
if (await fs.pathExists(rcPath)) {
|
|
1427
|
+
return await fs.readJson(rcPath);
|
|
1428
|
+
}
|
|
1429
|
+
return {};
|
|
1430
|
+
}
|
|
1431
|
+
async function copyFile(src, dest, force, dryRun) {
|
|
1432
|
+
if (dryRun) {
|
|
1433
|
+
console.log(`[dry-run] Would copy: ${src} → ${dest}`);
|
|
1434
|
+
return;
|
|
1435
|
+
}
|
|
1436
|
+
if ((await fs.pathExists(dest)) && !force) {
|
|
1437
|
+
console.log(`Skipped: ${dest} (already exists)`);
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1440
|
+
await fs.copy(src, dest, { overwrite: true });
|
|
1441
|
+
console.log(`Copied: ${src} → ${dest}`);
|
|
1442
|
+
}
|
|
1443
|
+
async function findMatchedFiles(source, patterns) {
|
|
1444
|
+
if (!(await fs.pathExists(source)))
|
|
1445
|
+
return [];
|
|
1446
|
+
const entries = await fs.readdir(source);
|
|
1447
|
+
return entries.filter(entry => matchesPatterns(entry, patterns));
|
|
1448
|
+
}
|
|
1449
|
+
async function runCopyEnv(options) {
|
|
1450
|
+
const cwd = process.cwd();
|
|
1451
|
+
if (!options.target)
|
|
1452
|
+
return;
|
|
1453
|
+
const rc = await readRc(cwd);
|
|
1454
|
+
const source = options.source ?? rc['copy-env']?.source;
|
|
1455
|
+
if (!source)
|
|
1456
|
+
return;
|
|
1457
|
+
const rawPattern = options.pattern ?? rc['copy-env']?.pattern ?? '.env*';
|
|
1458
|
+
const patterns = rawPattern.split(',').map(p => p.trim()).filter(Boolean);
|
|
1459
|
+
const matched = await findMatchedFiles(source, patterns);
|
|
1460
|
+
if (matched.length === 0)
|
|
1461
|
+
return;
|
|
1462
|
+
await fs.ensureDir(options.target);
|
|
1463
|
+
for (const filename of matched) {
|
|
1464
|
+
await copyFile(path.join(source, filename), path.join(options.target, filename), options.force ?? false, options.dryRun ?? false);
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
function copyEnvCommand() {
|
|
1468
|
+
const cmd = new Command('copy-env');
|
|
1469
|
+
cmd
|
|
1470
|
+
.description('Copy environment files from a source directory to a target directory')
|
|
1471
|
+
.option('--source <path>', 'source directory to copy env files from')
|
|
1472
|
+
.option('--target <path>', 'target directory to copy env files into')
|
|
1473
|
+
.option('--pattern <globs>', 'comma-separated glob patterns (default: .env*)')
|
|
1474
|
+
.option('--force', 'overwrite existing files in target')
|
|
1475
|
+
.option('--dry-run', 'print what would be copied without writing')
|
|
1476
|
+
.action(async (options) => {
|
|
1477
|
+
try {
|
|
1478
|
+
await runCopyEnv(options);
|
|
1479
|
+
}
|
|
1480
|
+
catch {
|
|
1481
|
+
// fail silently
|
|
1482
|
+
}
|
|
1483
|
+
});
|
|
1484
|
+
return cmd;
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1382
1487
|
const __filename$1 = fileURLToPath(import.meta.url);
|
|
1383
1488
|
const __dirname$1 = path.dirname(__filename$1);
|
|
1384
1489
|
const pkgPath = path.join(__dirname$1, '..', 'package.json');
|
|
@@ -1395,4 +1500,5 @@ program.addCommand(updateCommand());
|
|
|
1395
1500
|
program.addCommand(contextCommand());
|
|
1396
1501
|
program.addCommand(startWorktreeCommand());
|
|
1397
1502
|
program.addCommand(worktreeInfoCommand());
|
|
1503
|
+
program.addCommand(copyEnvCommand());
|
|
1398
1504
|
program.parse(process.argv);
|