@timeax/scaffold 0.0.9 → 0.0.11

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/cli.mjs CHANGED
@@ -930,6 +930,9 @@ async function applyStructure(opts) {
930
930
  interactiveDelete
931
931
  } = opts;
932
932
  const logger6 = opts.logger ?? defaultLogger.child(groupName ? `[apply:${groupName}]` : "[apply]");
933
+ const projectRootAbs = path2.resolve(projectRoot);
934
+ const baseDirAbs = path2.resolve(baseDir);
935
+ baseDirAbs.endsWith(path2.sep) ? baseDirAbs : baseDirAbs + path2.sep;
933
936
  const desiredPaths = /* @__PURE__ */ new Set();
934
937
  const threshold = sizePromptThreshold ?? config.sizePromptThreshold ?? 128 * 1024;
935
938
  async function walk(entry, inheritedStub) {
@@ -942,9 +945,9 @@ async function applyStructure(opts) {
942
945
  }
943
946
  async function handleDir(entry, inheritedStub) {
944
947
  const relFromBase = entry.path.replace(/^[./]+/, "");
945
- const absDir = path2.resolve(baseDir, relFromBase);
948
+ const absDir = path2.resolve(baseDirAbs, relFromBase);
946
949
  const relFromRoot = toPosixPath(
947
- toProjectRelativePath(projectRoot, absDir)
950
+ toProjectRelativePath(projectRootAbs, absDir)
948
951
  );
949
952
  desiredPaths.add(relFromRoot);
950
953
  ensureDirSync(absDir);
@@ -957,14 +960,14 @@ async function applyStructure(opts) {
957
960
  }
958
961
  async function handleFile(entry, inheritedStub) {
959
962
  const relFromBase = entry.path.replace(/^[./]+/, "");
960
- const absFile = path2.resolve(baseDir, relFromBase);
963
+ const absFile = path2.resolve(baseDirAbs, relFromBase);
961
964
  const relFromRoot = toPosixPath(
962
- toProjectRelativePath(projectRoot, absFile)
965
+ toProjectRelativePath(projectRootAbs, absFile)
963
966
  );
964
967
  desiredPaths.add(relFromRoot);
965
968
  const stubName = entry.stub ?? inheritedStub;
966
969
  const ctx = {
967
- projectRoot,
970
+ projectRoot: projectRootAbs,
968
971
  targetPath: relFromRoot,
969
972
  absolutePath: absFile,
970
973
  isDirectory: false,
@@ -1004,7 +1007,19 @@ async function applyStructure(opts) {
1004
1007
  await walk(entry);
1005
1008
  }
1006
1009
  for (const cachedPath of cache.allPaths()) {
1007
- if (desiredPaths.has(cachedPath)) continue;
1010
+ const entry = cache.get(cachedPath);
1011
+ if (groupName) {
1012
+ if (!entry || entry.groupName !== groupName) {
1013
+ continue;
1014
+ }
1015
+ } else {
1016
+ if (entry && entry.groupName) {
1017
+ continue;
1018
+ }
1019
+ }
1020
+ if (desiredPaths.has(cachedPath)) {
1021
+ continue;
1022
+ }
1008
1023
  const abs = path2.resolve(projectRoot, cachedPath);
1009
1024
  const stats = statSafeSync(abs);
1010
1025
  if (!stats) {
@@ -1015,7 +1030,6 @@ async function applyStructure(opts) {
1015
1030
  cache.delete(cachedPath);
1016
1031
  continue;
1017
1032
  }
1018
- const entry = cache.get(cachedPath);
1019
1033
  const ctx = {
1020
1034
  projectRoot,
1021
1035
  targetPath: cachedPath,
@@ -1530,8 +1544,9 @@ async function handleRunCommand(cwd, baseOpts) {
1530
1544
  const logger6 = createCliLogger(baseOpts);
1531
1545
  const configPath = baseOpts.config ? path2.resolve(cwd, baseOpts.config) : void 0;
1532
1546
  const scaffoldDir = baseOpts.dir ? path2.resolve(cwd, baseOpts.dir) : void 0;
1547
+ const resolvedScaffoldDir = scaffoldDir ?? path2.resolve(cwd, SCAFFOLD_ROOT_DIR);
1533
1548
  logger6.debug(
1534
- `Starting scaffold (cwd=${cwd}, config=${configPath ?? "auto"}, dir=${scaffoldDir ?? "scaffold/"}, watch=${baseOpts.watch ? "yes" : "no"})`
1549
+ `Starting scaffold (cwd=${cwd}, config=${configPath ?? "auto"}, dir=${resolvedScaffoldDir}, watch=${baseOpts.watch ? "yes" : "no"})`
1535
1550
  );
1536
1551
  const runnerOptions = {
1537
1552
  configPath,
@@ -1563,7 +1578,9 @@ async function handleScanCommand(cwd, scanOpts, baseOpts) {
1563
1578
  logger6.info("Scanning project using scaffold config/groups...");
1564
1579
  await writeScannedStructuresFromConfig(cwd, {
1565
1580
  ignore: scanOpts.ignore,
1566
- groups: scanOpts.groups
1581
+ groups: scanOpts.groups,
1582
+ scaffoldDir: baseOpts.dir,
1583
+ maxDepth: scanOpts.maxDepth
1567
1584
  });
1568
1585
  return;
1569
1586
  }
@@ -1613,19 +1630,16 @@ async function handleStructuresCommand(cwd, baseOpts) {
1613
1630
  async function main() {
1614
1631
  const cwd = process.cwd();
1615
1632
  const program = new Command();
1616
- program.name("scaffold").description("@timeax/scaffold \u2013 structure-based project scaffolding").option("-c, --config <path>", "Path to scaffold config file").option("-d, --dir <path>", "Path to scaffold directory (default: ./scaffold)").option("-w, --watch", "Watch scaffold directory for changes").option("--quiet", "Silence logs").option("--debug", "Enable debug logging");
1633
+ program.name("scaffold").description("@timeax/scaffold \u2013 structure-based project scaffolding").option("-c, --config <path>", "Path to scaffold config file").option(
1634
+ "-d, --dir <path>",
1635
+ `Path to scaffold directory (default: ./${SCAFFOLD_ROOT_DIR})`
1636
+ ).option("-w, --watch", "Watch scaffold directory for changes").option("--quiet", "Silence logs").option("--debug", "Enable debug logging");
1617
1637
  program.command("scan").description(
1618
1638
  "Generate structure.txt-style output (config-aware by default, or manual root/out)"
1619
1639
  ).option(
1620
1640
  "--from-config",
1621
- "Scan based on scaffold config/groups and write structure files into scaffold/ (default if no root/out specified)"
1622
- ).option(
1623
- "-r, --root <path>",
1624
- "Root directory to scan (manual mode)"
1625
- ).option(
1626
- "-o, --out <path>",
1627
- "Output file path (manual mode)"
1628
- ).option(
1641
+ `Scan based on scaffold config/groups and write structure files into ${SCAFFOLD_ROOT_DIR}/ (default if no root/out specified)`
1642
+ ).option("-r, --root <path>", "Root directory to scan (manual mode)").option("-o, --out <path>", "Output file path (manual mode)").option("-d, --depth <number>", "Max directory depth to scan (default: infinity, 0 = only scan root dir").option(
1629
1643
  "--ignore <patterns...>",
1630
1644
  "Additional glob patterns to ignore (relative to root)"
1631
1645
  ).option(
@@ -1635,22 +1649,24 @@ async function main() {
1635
1649
  const baseOpts = cmd.parent?.opts() ?? {};
1636
1650
  await handleScanCommand(cwd, scanOpts, baseOpts);
1637
1651
  });
1638
- program.command("init").description("Initialize scaffold folder and config/structure files").option(
1652
+ program.command("init").description(
1653
+ `Initialize ${SCAFFOLD_ROOT_DIR} folder and config/structure files`
1654
+ ).option(
1639
1655
  "--force",
1640
1656
  "Overwrite existing config/structure files if they already exist"
1641
1657
  ).action(async (initOpts, cmd) => {
1642
1658
  const baseOpts = cmd.parent?.opts() ?? {};
1643
1659
  await handleInitCommand(cwd, initOpts, baseOpts);
1644
1660
  });
1645
- program.action(async (opts) => {
1646
- await handleRunCommand(cwd, opts);
1647
- });
1648
1661
  program.command("structures").description(
1649
1662
  "Create missing structure files specified in the config (does not overwrite existing files)"
1650
1663
  ).action(async (_opts, cmd) => {
1651
1664
  const baseOpts = cmd.parent?.opts() ?? {};
1652
1665
  await handleStructuresCommand(cwd, baseOpts);
1653
1666
  });
1667
+ program.action(async (opts) => {
1668
+ await handleRunCommand(cwd, opts);
1669
+ });
1654
1670
  await program.parseAsync(process.argv);
1655
1671
  }
1656
1672
  main().catch((err) => {