Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(astro): handle symlinked content collection directories #11236

Merged
merged 12 commits into from
Jun 12, 2024
Merged

Conversation

ascorbic
Copy link
Contributor

@ascorbic ascorbic commented Jun 11, 2024

Changes

Currently if you try to use a symlink in a content collection directory it will break the build. This is because Vite resolves the path to the symlink target, which is then outside of the content directory.

This PR tracks symlinks in the content directory, and then reverses them when transforming the content. This works out as a more robust way than intercepting the module resolution, which seemed to break many things in various places.

Fixes #9088

Testing

Adds fixtures and test cases with symlinks

Docs

This should be documented. I'm not sure if we document the limitation currently. This only supports symlinks at the top level (i.e. the link is src/content/blog -> /Path/to/real/content/blog).

Copy link

changeset-bot bot commented Jun 11, 2024

🦋 Changeset detected

Latest commit: 35d50f6

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added the pkg: astro Related to the core `astro` package (scope) label Jun 11, 2024
@ascorbic ascorbic marked this pull request as draft June 11, 2024 18:11
@ascorbic
Copy link
Contributor Author

Hm. Looks like it's broken with caching.

@ascorbic ascorbic marked this pull request as ready for review June 12, 2024 09:39
Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few nits, otherwise it looks good!

.changeset/fifty-clouds-clean.md Outdated Show resolved Hide resolved
Comment on lines 180 to 187
const contentDirEntries = await fsMod.promises.readdir(contentDir, { withFileTypes: true });
for (const entry of contentDirEntries) {
if (entry.isSymbolicLink()) {
const entryPath = path.join(contentDirPath, entry.name);
const realPath = await fsMod.promises.realpath(entryPath);
contentPaths.set(normalizePath(realPath), entry.name);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: file system operations can come with runtime errors (permissions, etc.), I tend to wrap these operations in a try/catch to be more safe

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. As a rule, would you silently ignore any errors there, log a warning, or fail the build?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd lean towards silently ignoring them here, because we're just looking for symlinks and a failure probably means it's not a symlink.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It really depends on the use case, really. In this case we could just ignore the error, and maybe log and error/warning using the logger (you should have access to it).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where would I find a logger instance? I'm calling this in vite-plugin-content-imports.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems we don't pass it down to this plugin (the logger arrived after this plugin was created). You'll have to pass it like in this case:

astroInjectEnvTsPlugin({ settings, logger, fs }),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, thanks. I just pushed an update with error handling and renamed funciton, but no logging. I'll add the logs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I've added logging now

return contentPaths;
}

export function reverseSymlinks({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: reverseSymlinks -> reverseSymlink singular, because it returns a string, and not a stringp[]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I did the plural is because there are multiple symlinks. But I can see what you mean.

@ascorbic ascorbic merged commit 39bc3a5 into main Jun 12, 2024
4 checks passed
@ascorbic ascorbic deleted the plt-2183 branch June 12, 2024 12:45
@astrobot-houston astrobot-houston mentioned this pull request Jun 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: astro Related to the core `astro` package (scope)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unknown Content Collection Error when content directory is a symlink
3 participants