Open jimjam-slam opened 4 months ago
It is not just related to project configuration. We just currently do not read an extension as a symlink - it is not resolved and we expect a directory as we check extensionDir.isDirectory
https://github.com/quarto-dev/quarto-cli/blob/78e7f847d49dfd029252a8c4b2fc80be33456436/src/extension/extension.ts#L409-L448
So currently extensions as a symlink is not supported.
Issue can be reproduced above by just
cd docs/
quarto list extensions
ERROR: Unsupported project type testproject
As a quick test, this could be a way to handle the reading for the symlink (and solves this specific issue)
diff --git a/src/extension/extension.ts b/src/extension/extension.ts
index ac081998c..47b5f8036 100644
--- a/src/extension/extension.ts
+++ b/src/extension/extension.ts
@@ -415,10 +415,14 @@ export async function readExtensions(
const extensions: Extension[] = [];
const extensionDirs = Deno.readDirSync(extensionsDirectory);
for (const extensionDir of extensionDirs) {
- if (extensionDir.isDirectory) {
- const extFile = extensionFile(
- join(extensionsDirectory, extensionDir.name),
- );
+ if (extensionDir.isDirectory || extensionDir.isSymlink) {
+ let extDir = extensionDir.name;
+ if (extensionDir.isSymlink) {
+ extDir = Deno.readLinkSync(
+ join(extensionsDirectory, extensionDir.name),
+ );
+ }
+ const extFile = extensionFile(join(extensionsDirectory, extDir));
if (extFile) {
// This is a directory that contains an extension
// This represents an 'anonymous' extension that doesn't
But I don't know enough about the extension context and resource handling to know if having other extensions files as a symlink would be problematic (thinking about templates, resources, theme files, ...)
I believe in general we do try to prevent any path handling for files that escape the root directory. Anything should be local to project usually.
Related topic on symlink
quarto render
)Makes sense! I might experiment with a project pre-render script to copy the extension in from the repo root (the extension also supports single document renders, but that wouldn't be important for this documentation site). Just trying to find a solution for an extension documentation site using that extension that keeps a single source of truth within the repo!
Unfortunately the project type is rejected before any pre-render script is executed, so I can't bolt one on to the extension site. I'd probably have to use something like cp -r ../_extensions/sverto /_extensions/sverto && quarto render
in that case.
@jimjam-slam Did you try with Quarto 1.5? There are some changes in Quarto related to pre-render scripts. (see the highlight section of the changelog)
@mcanouil he did:
Quarto: have tested on both 1.4.550 and pre-release (at commit https://github.com/quarto-dev/quarto-cli/commit/581c7e54dbf5ecc6638553d28592f6388fe6ec65)
Was referring to the last comment about pre-render.
Unfortunately the project type is rejected before any pre-render script is executed, so I can't bolt one on to the extension site. I'd probably have to use something like
cp -r ../_extensions/sverto /_extensions/sverto && quarto render
in that case.
Adding the pre-render script I've tried with the prerelease above but not with the 1.4 stable 🙂
I should add that extension documentation is a fairly narrow use case, and if you decide that the benefits of not following symlinks outweigh the downsides, I can definitely make do 😊
Huh, that's an interesting development. Tis' always good to know I'm using an edge case 😉
Thinking out loud, we recently added a make sync
directive in {quarto-countdown}
that could be used to copy the extension to relative directories. That would address the local development environment portion until the pre-render script hiccup could be fixed in 1.5 dev builds.
Outside of that, another approach would be for the CI run to copy the development extension over to other directories, e.g.
- name: Copy extension for demos
run: |
mkdir -p demos/_extensions/
cp -r ./_extensions demos/_extensions/
(Note, you could employ the make
directive inside of the CI script as well.)
Yeah, having the CI copy the extension is what I've settled on! Note that I specifically had to specify shell: bash
in order to get it to work on a Windows runner (it defaulted to PowerShell otherwise, which has a different syntax).
I should also note that my project pre-render script tries to avoid running duplicate files, so I'm also learning how much easier it is when you assume no symlinks in your relative paths 😅
Bug description
In https://github.com/quarto-dev/quarto-cli/discussions/8579 I have been discussing the best way to structure a repository for a Quarto extension alongside a documentation website that uses that extension. @coatless has had success symlinking the doc website's extension folder (whether for a single extension or several) to the parent folder (eg. so if the documentation website is in
/docs
,/docs/_extensions/testproject -> /_extensions/testproject
).I'm trying to pursue this option, but I find that if my extension involves a custom project type (see reprex extension), I get an error when I render the documentation website.
Steps to reproduce
Clone the reprex extension, then:
Expected behavior
If I delete the symlink and manually copy the files into the doc website's extension folder, it renders fine:
Your environment
Quarto check output
Using the pre-release: