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 #908: Omit shadowed assets from build #1147

Merged
merged 9 commits into from Jun 6, 2023

Conversation

dairiki
Copy link
Contributor

@dairiki dairiki commented Jun 3, 2023

Issue(s) Resolved

Fixes #908
Fixes #1111

Related Issues / Links

Description of Changes

  • Wrote at least one-line docstrings (for any new functions)
  • Added unit test(s) covering the changes (if testable)

The issue described in #908 happens when themes (and so multiple asset trees) are in play. If there is an asset in one asset tree at the same path as an asset in a second asset tree, both are currently built. Besides being inefficient (one overwrites the other) the order of building seems not to be completely deterministic, so that it's not clear which version wins.

Currently, when themes are in play, so that there are multiple on-disk directory trees of assets to be merged to a single output tree, Lektor keeps a list of the multiple assets tree roots, and traverses each of those separately to find all the assets to be built.

In this PR we refactor lektor.assets.Directory so that it can represent a logically merged asset directory. After this PR a single lektor.assets.Directory instance can represent an overlayed set of directories. This gets us back to having a single asset root which represents the merged asset tree.

@dairiki
Copy link
Contributor Author

dairiki commented Jun 3, 2023

I am going to have now refactored this.

Having slept on it, I think the right solution is to prevent the asset tree as a single merged tree containing the directories/files accessible via any of the asset directories.

This will be was a significant refactor of lektor.assets, but will solve solves the problem of Directory assets having children that should be ignored.

@dairiki dairiki force-pushed the fix.908-omit-shadowed-assets branch 3 times, most recently from 6e4b1a6 to 7f3026f Compare June 4, 2023 16:43
@dairiki dairiki marked this pull request as ready for review June 4, 2023 17:00
@dairiki dairiki force-pushed the fix.908-omit-shadowed-assets branch from 7f3026f to aec573e Compare June 4, 2023 20:45
When themes are in use, assets can be located in one of multiple asset
directories.

Previously, in this case, we dealt with multiple asset roots, each
with their own heirarchy of descendant assets. Some of these
descendants can be shadowed by assets in one of the other asset roots,
and should be ignored. This is difficult to manage.

Here we refactor the code in `lektor.assets` to present a single
logical merged asset tree which overlays the assets from the primary
project `assets` directory with the `assets` directories of any
themes.
This cleans up the logic for detecting cases where the URL (or asset)
name differs from the source file name. (There are cases where the
suffixes of the names can differ.)

This disuses and deprecates the `from_url` parameter to
`Asset.get_child`.
`Asset.build_asset` is an undocumented no-op. It appears to be
unreferenced by Lektor itself as well as all Lektor plugins that I've
been able to find.
This was breaking the (imperfect) logic in
`lektor.builder.PathCache.to_source_file` which checks that source
files are contained within the project tree.
Optimization.

Since Assets are tied to a Pad, the cache lifetime will match that of
the Pad. This seems appropriate.
@dairiki dairiki force-pushed the fix.908-omit-shadowed-assets branch from aec573e to 0116d2e Compare June 5, 2023 05:42
@dairiki dairiki merged commit 998e50d into lektor:master Jun 6, 2023
15 checks passed
@dairiki dairiki deleted the fix.908-omit-shadowed-assets branch June 6, 2023 18:30
dairiki added a commit to dairiki/lektor that referenced this pull request Sep 11, 2023
* test: add test to exercise lektor#908

* refactor(lektor.assets): present a single merged asset tree

When themes are in use, assets can be located in one of multiple asset
directories.

Previously, in this case, we dealt with multiple asset roots, each
with their own heirarchy of descendant assets. Some of these
descendants can be shadowed by assets in one of the other asset roots,
and should be ignored. This is difficult to manage.

Here we refactor the code in `lektor.assets` to present a single
logical merged asset tree which overlays the assets from the primary
project `assets` directory with the `assets` directories of any
themes.

* refactor(lektor.assets): be more careful about validating path components

* refactor(lektor.assets): refactor Asset.resolve_url_path

This cleans up the logic for detecting cases where the URL (or asset)
name differs from the source file name. (There are cases where the
suffixes of the names can differ.)

This disuses and deprecates the `from_url` parameter to
`Asset.get_child`.

* refactor(lektor.assets)!: remove vestigial method `Asset.build_asset`

`Asset.build_asset` is an undocumented no-op. It appears to be
unreferenced by Lektor itself as well as all Lektor plugins that I've
been able to find.

* tests(lektor.assets): enough annotations to get mypy to pass

* tests(lektor.assets): increase test coverage

* fix: do not Path.resolve() asset roots

This was breaking the (imperfect) logic in
`lektor.builder.PathCache.to_source_file` which checks that source
files are contained within the project tree.

* refactor(lektor.assets): cache child assets on Directory

Optimization.

Since Assets are tied to a Pad, the cache lifetime will match that of
the Pad. This seems appropriate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Buglet with lowercasing of asset file extensions Custom css file inconsistent behavior during deployment
1 participant