mirror of
https://github.com/getpelican/pelican.git
synced 2026-11-15 01:28:26 +01:00
Merge 094cb04f35 into c2fff5344b
This commit is contained in:
commit
509726881a
3 changed files with 52 additions and 7 deletions
3
RELEASE.md
Normal file
3
RELEASE.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Release type: patch
|
||||
|
||||
Process content and static files in a stable, sorted order so that build output no longer depends on the interpreter's hash seed
|
||||
|
|
@ -259,8 +259,10 @@ class Generator:
|
|||
|
||||
def _check_disabled_readers(self, paths, exclude: list[str] | None) -> None:
|
||||
"""Log warnings for files that would have been processed by disabled readers."""
|
||||
for fil in self.get_files(
|
||||
paths, exclude=exclude, extensions=self.readers.disabled_extensions
|
||||
for fil in sorted(
|
||||
self.get_files(
|
||||
paths, exclude=exclude, extensions=self.readers.disabled_extensions
|
||||
)
|
||||
):
|
||||
self.readers.check_file(fil)
|
||||
|
||||
|
|
@ -705,8 +707,11 @@ class ArticlesGenerator(CachingGenerator):
|
|||
all_articles = []
|
||||
all_drafts = []
|
||||
hidden_articles = []
|
||||
for f in self.get_files(
|
||||
self.settings["ARTICLE_PATHS"], exclude=self.settings["ARTICLE_EXCLUDES"]
|
||||
for f in sorted(
|
||||
self.get_files(
|
||||
self.settings["ARTICLE_PATHS"],
|
||||
exclude=self.settings["ARTICLE_EXCLUDES"],
|
||||
)
|
||||
):
|
||||
article = self.get_cached_data(f, None)
|
||||
if article is None:
|
||||
|
|
@ -920,8 +925,10 @@ class PagesGenerator(CachingGenerator):
|
|||
all_pages = []
|
||||
hidden_pages = []
|
||||
draft_pages = []
|
||||
for f in self.get_files(
|
||||
self.settings["PAGE_PATHS"], exclude=self.settings["PAGE_EXCLUDES"]
|
||||
for f in sorted(
|
||||
self.get_files(
|
||||
self.settings["PAGE_PATHS"], exclude=self.settings["PAGE_EXCLUDES"]
|
||||
)
|
||||
):
|
||||
page = self.get_cached_data(f, None)
|
||||
if page is None:
|
||||
|
|
@ -1039,7 +1046,7 @@ class StaticGenerator(Generator):
|
|||
exclude=self.settings["STATIC_EXCLUDES"],
|
||||
extensions=False,
|
||||
)
|
||||
for f in linked_files | found_files:
|
||||
for f in sorted(linked_files | found_files):
|
||||
# skip content source files unless the user explicitly wants them
|
||||
if self.settings["STATIC_EXCLUDE_SOURCES"]:
|
||||
if self._is_potential_source_path(f):
|
||||
|
|
|
|||
|
|
@ -1279,6 +1279,41 @@ class TestStaticGenerator(unittest.TestCase):
|
|||
def set_ancient_mtime(self, path, timestamp=1):
|
||||
os.utime(path, (timestamp, timestamp))
|
||||
|
||||
def test_static_files_processed_in_stable_order(self):
|
||||
"""Static files are processed in sorted order, not in the iteration
|
||||
order of the sets returned by get_files(), which depends on the
|
||||
interpreter's hash seed."""
|
||||
|
||||
class ReversedSet(set):
|
||||
# Iterates in reverse sorted order, standing in for an unlucky
|
||||
# PYTHONHASHSEED; set unions keep the behavior.
|
||||
def __iter__(self):
|
||||
return iter(sorted(super().__iter__(), reverse=True))
|
||||
|
||||
def __or__(self, other):
|
||||
return ReversedSet(set(self) | set(other))
|
||||
|
||||
__ror__ = __or__
|
||||
|
||||
settings = get_settings(PATH=self.content_path, STATIC_PATHS=[""])
|
||||
context = get_context(settings)
|
||||
generator = StaticGenerator(
|
||||
context=context,
|
||||
settings=settings,
|
||||
path=settings["PATH"],
|
||||
output_path=self.temp_output,
|
||||
theme=settings["THEME"],
|
||||
)
|
||||
get_files = generator.get_files
|
||||
generator.get_files = lambda *args, **kwargs: ReversedSet(
|
||||
get_files(*args, **kwargs)
|
||||
)
|
||||
generator.generate_context()
|
||||
|
||||
source_paths = [sf.source_path for sf in context["staticfiles"]]
|
||||
self.assertGreater(len(source_paths), 1)
|
||||
self.assertEqual(source_paths, sorted(source_paths))
|
||||
|
||||
def test_theme_static_paths_dirs(self):
|
||||
"""Test that StaticGenerator properly copies also files mentioned in
|
||||
TEMPLATE_STATIC_PATHS, not just directories."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue