Skip to content

Commit 4068ca1

Browse files
claude: Use glob pattern to find _extension.yml at any depth
Replace manual directory scanning with expandGlobSync to find _extension.yml files, properly supporting nested organization structures like _extensions/org-name/extension/_extension.yml. Changes: - Use expandGlobSync("_extensions/**/_extension.yml") pattern - Support both flat and nested extension directory structures - Simplify logic by removing manual directory iteration - Improve error messages with cleaner relative path display 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 5773910 commit 4068ca1

File tree

1 file changed

+52
-14
lines changed
  • src/command/dev-call/build-ts-extension

1 file changed

+52
-14
lines changed

src/command/dev-call/build-ts-extension/cmd.ts

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import { execProcess } from "../../../core/process.ts";
1414
import { basename, dirname, extname, join } from "../../../deno_ral/path.ts";
1515
import { existsSync } from "../../../deno_ral/fs.ts";
16+
import { expandGlobSync } from "../../../core/deno/expand-glob.ts";
1617

1718
interface DenoConfig {
1819
compilerOptions?: Record<string, unknown>;
@@ -184,23 +185,60 @@ function inferOutputPath(entryPoint: string): string {
184185
// Get the base name without extension
185186
const fileName = basename(entryPoint, extname(entryPoint));
186187

187-
// Try to determine extension name from directory structure or use filename
188-
let extensionName = fileName;
188+
// Find the extension directory by looking for _extension.yml
189+
const extensionsDir = "_extensions";
190+
if (!existsSync(extensionsDir)) {
191+
error("Error: No _extensions/ directory found.");
192+
error("");
193+
error(
194+
"Extension projects must have an _extensions/ directory with _extension.yml.",
195+
);
196+
error("Create the extension structure:");
197+
error(` mkdir -p _extensions/${fileName}`);
198+
error(` touch _extensions/${fileName}/_extension.yml`);
199+
Deno.exit(1);
200+
}
189201

190-
// Check if _extension.yml exists to get extension name
191-
const extensionYml = "_extension.yml";
192-
if (existsSync(extensionYml)) {
193-
try {
194-
// Simple extraction - look for extension name in path or use filename
195-
// For MVP, we'll just use the filename
196-
} catch {
197-
// Ignore errors, use filename
198-
}
202+
// Find all _extension.yml files using glob pattern
203+
const extensionYmlFiles: string[] = [];
204+
for (const entry of expandGlobSync("_extensions/**/_extension.yml")) {
205+
extensionYmlFiles.push(dirname(entry.path));
206+
}
207+
208+
if (extensionYmlFiles.length === 0) {
209+
error("Error: No _extension.yml found in _extensions/ subdirectories.");
210+
error("");
211+
error(
212+
"Extension projects must have _extension.yml in a subdirectory of _extensions/.",
213+
);
214+
error("Create the extension metadata:");
215+
error(` touch _extensions/${fileName}/_extension.yml`);
216+
Deno.exit(1);
217+
}
218+
219+
if (extensionYmlFiles.length > 1) {
220+
const extensionNames = extensionYmlFiles.map((path) =>
221+
path.replace("_extensions/", "")
222+
);
223+
error(
224+
`Error: Multiple extension directories found: ${
225+
extensionNames.join(", ")
226+
}`,
227+
);
228+
error("");
229+
error("Specify the output path in deno.json:");
230+
error(" {");
231+
error(' "quartoExtension": {');
232+
error(
233+
` "outputFile": "${extensionYmlFiles[0]}/${fileName}.js"`,
234+
);
235+
error(" }");
236+
error(" }");
237+
Deno.exit(1);
199238
}
200239

201-
// Output to _extensions/<name>/<name>.js
202-
const outputDir = join("_extensions", extensionName);
203-
return join(outputDir, `${fileName}.js`);
240+
// Use the single extension directory found
241+
return join(extensionYmlFiles[0], `${fileName}.js`);
204242
}
205243

206244
async function bundle(

0 commit comments

Comments
 (0)