7 Commits

Author SHA1 Message Date
201cd80804 when symlinking foo.md, also symlink foo.html if generating .html
fixes #24

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-21 08:31:31 -05:00
a327c6b89c remove the Flask classifier, since we don't do it anymore
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-21 08:23:31 -05:00
27d4d16572 go back to using the "or any later version" clause of GPLv3
I think arguments that "Such new versions will be similar in spirit to
the present version", in my own reading and readings such as in
https://www.draketo.de/software/gpl-or-later, convince me for now that
it is acceptable to allow the "or later" for compatibility and future
problem's sake

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-21 08:22:49 -05:00
b69bdb424a CHANGELOG for v2.0.2
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-18 21:28:15 -05:00
c46a1c0bae don't handle custom-static dirs specially anymore
they're just more static files among all the static files we serve, they
should go into pages/ like everything else

fixes #20

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-18 21:26:25 -05:00
359916e7d9 do some trivial cleanups in README
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-18 21:20:12 -05:00
d49b9d48a8 don't add an artificial ./ subdir due to how os.path.relpath works
this fixes stuff like og:urls of https://foo/./ or https://foo/./page
and also removes an extra layer of depth in the breadcrumb hierarchy,
just by suppressing the '.' in relpath output at the root of pages/

fixes #21

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-18 21:09:50 -05:00
34 changed files with 130 additions and 104 deletions

View File

@@ -1,24 +0,0 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: incorporeal-cms
Upstream-Contact: Brian S. Stephan <bss@incorporeal.org>
Source: https://git.incorporeal.org/bss/incorporeal-cms
# Trivial files
Files: .gitignore .gitattributes
Copyright: © 2020 Brian S. Stephan <bss@incorporeal.org>
License: GPL-3.0-only
# High level repo docs
Files: *.md
Copyright: © 2020 Brian S. Stephan <bss@incorporeal.org>
License: GPL-3.0-only
# Test data
Files: tests/instance/*
Copyright: © 2020 Brian S. Stephan <bss@incorporeal.org>
License: GPL-3.0-only
# Python packaging, scaffolding, and errata
Files: MANIFEST.in pyproject.toml tox.ini requirements/*
Copyright: © 2020 Brian S. Stephan <bss@incorporeal.org>
License: GPL-3.0-only

View File

@@ -2,6 +2,19 @@
Included is a summary of changes to the project, by version. Details can be found in the commit history. Included is a summary of changes to the project, by version. Details can be found in the commit history.
## v2.0.2
### Bugfixes
* Paths for files in the `pages/` root no longer have an extra `./` in them, which made URLs look ugly and also added an
extra blank breadcrumb in the breadcrumbs.
### Improvements
* `custom-static` in the instance dir is now ignored and has no special handling --- put static files in `pages/static/`
like all the other files that get copied. This also fixes a bug where the build errored if the directory didn't exist.
* Some README typos fixed.
## v2.0.1 ## v2.0.1
### Improvements ### Improvements

View File

@@ -14,19 +14,19 @@ Something like the following should suffice:
% incorporealcms-build ./path/to/instance ./path/to/output/www/root % incorporealcms-build ./path/to/instance ./path/to/output/www/root
``` ```
This will generate the directory suitable for serving by e.g. Nginx. This will generate the directory suitable for serving by e.g. nginx.
## Creating a Site ## Creating a Site
Put content, notably Markdown content, inside `./your-instance/pages/` and when you are ready, run the build command Put content, notably Markdown content, inside `./your-instance/pages/` and when you are ready, run the build command
above. When you run `incorporealcms-build`, the following happens: above. When you run `incorporealcms-build`, the following happens:
* Markdown files (ending in `.md`) are rendered via Python-Markdown as .html files and output to the static site * Markdown files (ending in `.md`) are rendered via Python-Markdown as `.html` files and output to the static site
directory. The `.md` files are also copied there, though this behavior may be toggleable in the future. directory. The `.md` files are also copied there, though this behavior may be toggleable in the future.
* Directory paths (e.g. a request to `/dir/`) can be served via a `/dir/index.md` file, which will generate * Directory paths (e.g. a request to `/dir/`) can be served via a `/dir/index.md` file, which will generate
`/dir/index.html`, with the appropriate web server configuration to use `index.html` for directory listings. `/dir/index.html`, with the appropriate web server configuration to use `index.html` for directory listings.
* Symlinks to files are retained and mirrored into the output directory, and handled per the web server's configuration, * Symlinks to files are retained and mirrored into the output directory, and handled per the web server's configuration,
whanever it is. whatever it is.
* All other files are copied directly, so images, text files, etc., can be referenced naturally as URLs. * All other files are copied directly, so images, text files, etc., can be referenced naturally as URLs.
## Configuration ## Configuration
@@ -54,17 +54,16 @@ out and discuss issues and features and whatnot.
Written by and copyright (C) 2025 Brian S. Stephan (bss@incorporeal.org). Written by and copyright (C) 2025 Brian S. Stephan (bss@incorporeal.org).
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify it under the terms of the GNU General
it under the terms of the GNU General Public License as published by Public License as published by the Free Software Foundation, either version 3 of the License, or (at your
the Free Software Foundation, version 3 of the License. option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
but WITHOUT ANY WARRANTY; without even the implied warranty of implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the more details.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License along with this program. If not, see
along with this program. If not, see <https://www.gnu.org/licenses/>. <https://www.gnu.org/licenses/>.
### Content Output ### Content Output

28
REUSE.toml Normal file
View File

@@ -0,0 +1,28 @@
version = 1
SPDX-PackageName = "incorporeal-cms"
SPDX-PackageSupplier = "Brian S. Stephan <bss@incorporeal.org>"
SPDX-PackageDownloadLocation = "https://git.incorporeal.org/bss/incorporeal-cms"
[[annotations]]
path = [".gitignore", ".gitattributes"]
precedence = "aggregate"
SPDX-FileCopyrightText = "© 2020 Brian S. Stephan <bss@incorporeal.org>"
SPDX-License-Identifier = "GPL-3.0-or-later"
[[annotations]]
path = "**.md"
precedence = "aggregate"
SPDX-FileCopyrightText = "© 2020 Brian S. Stephan <bss@incorporeal.org>"
SPDX-License-Identifier = "GPL-3.0-or-later"
[[annotations]]
path = "tests/instance/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "© 2020 Brian S. Stephan <bss@incorporeal.org>"
SPDX-License-Identifier = "GPL-3.0-or-later"
[[annotations]]
path = ["MANIFEST.in", "pyproject.toml", "tox.ini", "requirements/**"]
precedence = "aggregate"
SPDX-FileCopyrightText = "© 2020 Brian S. Stephan <bss@incorporeal.org>"
SPDX-License-Identifier = "GPL-3.0-or-later"

View File

@@ -1,7 +1,7 @@
"""An application for running my Markdown-based sites. """An application for running my Markdown-based sites.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import json import json
import logging import logging

View File

@@ -1,7 +1,7 @@
"""Default configuration. """Default configuration.
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """

View File

@@ -1,7 +1,7 @@
"""Process the error page templates. """Process the error page templates.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import os import os

View File

@@ -7,7 +7,7 @@ under pages/ (which may make sense for a blog) if they want, but could just
as well be pages/foo content. as well be pages/foo content.
SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import logging import logging
import os import os

View File

@@ -5,7 +5,7 @@ as is, but .md files need to be processed with a Markdown parser, so a lot of th
is our tweaks and customizations for pages my way. is our tweaks and customizations for pages my way.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import datetime import datetime
import logging import logging

View File

@@ -1,5 +1,5 @@
"""Markdown extensions. """Markdown extensions.
SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """

View File

@@ -1,7 +1,7 @@
"""Create generic figures with captions. """Create generic figures with captions.
SPDX-FileCopyrightText: © 2022 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2022 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import re import re
from xml.etree.ElementTree import SubElement # nosec B405 from xml.etree.ElementTree import SubElement # nosec B405

View File

@@ -1,7 +1,7 @@
"""Serve dot diagrams inline. """Serve dot diagrams inline.
SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import base64 import base64
import logging import logging

View File

@@ -1,9 +1,10 @@
"""Build an instance as a static site suitable for serving via e.g. Nginx. """Build an instance as a static site suitable for serving via e.g. Nginx.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import argparse import argparse
import logging
import os import os
import shutil import shutil
import stat import stat
@@ -16,6 +17,8 @@ from incorporealcms.error_pages import generate_error_pages
from incorporealcms.feed import generate_feed from incorporealcms.feed import generate_feed
from incorporealcms.markdown import handle_markdown_file_path from incorporealcms.markdown import handle_markdown_file_path
logger = logging.getLogger(__name__)
class StaticSiteGenerator(object): class StaticSiteGenerator(object):
"""Generate static site output based on the instance's content.""" """Generate static site output based on the instance's content."""
@@ -53,10 +56,6 @@ class StaticSiteGenerator(object):
pass pass
self.build_in_destination(program_static_dir, static_output_dir, convert_markdown=False) self.build_in_destination(program_static_dir, static_output_dir, convert_markdown=False)
# copy the instance's static dir --- should I deprecate this since it could just be stuff in pages/static/?
custom_static_dir = os.path.join(self.instance_dir, 'custom-static')
self.build_in_destination(custom_static_dir, static_output_dir, convert_markdown=False)
# generate the feeds # generate the feeds
cprint("generating feeds", 'green') cprint("generating feeds", 'green')
generate_feed('atom', self.instance_dir, tmp_output_dir) generate_feed('atom', self.instance_dir, tmp_output_dir)
@@ -89,8 +88,10 @@ class StaticSiteGenerator(object):
cprint(f"copying files from '{source_dir}' to '{dest_dir}'", 'green') cprint(f"copying files from '{source_dir}' to '{dest_dir}'", 'green')
os.chdir(source_dir) os.chdir(source_dir)
for base_dir, subdirs, files in os.walk(source_dir): for base_dir, subdirs, files in os.walk(source_dir):
logger.debug("starting to build against %s || %s || %s", base_dir, subdirs, files)
# remove the absolute path of the directory from the base_dir # remove the absolute path of the directory from the base_dir
base_dir = os.path.relpath(base_dir, source_dir) relpath = os.path.relpath(base_dir, source_dir)
base_dir = relpath if relpath != '.' else ''
# create subdirs seen here for subsequent depth # create subdirs seen here for subsequent depth
for subdir in subdirs: for subdir in subdirs:
self.build_subdir_in_destination(source_dir, base_dir, subdir, dest_dir) self.build_subdir_in_destination(source_dir, base_dir, subdir, dest_dir)
@@ -141,6 +142,14 @@ class StaticSiteGenerator(object):
src = self.symlink_to_relative_dest(source_dir, os.path.join(base_dir, file_)) src = self.symlink_to_relative_dest(source_dir, os.path.join(base_dir, file_))
print(f"creating symlink '{dst}' -> '{src}'") print(f"creating symlink '{dst}' -> '{src}'")
os.symlink(src, dst, target_is_directory=False) os.symlink(src, dst, target_is_directory=False)
if src.endswith('.md') and convert_markdown:
# we also need to make a .html symlink so that web server configs
# pick up the "redirect"
second_src = src.removesuffix('.md') + '.html'
second_dst = dst.removesuffix('.md') + '.html'
print(f"creating symlink '{second_dst}' -> '{second_src}'")
os.symlink(second_src, second_dst, target_is_directory=False)
else: else:
src = os.path.join(base_dir, file_) src = os.path.join(base_dir, file_)
print(f"copying file '{src}' -> '{dst}'") print(f"copying file '{src}' -> '{dst}'")
@@ -149,6 +158,7 @@ class StaticSiteGenerator(object):
# render markdown as HTML # render markdown as HTML
if src.endswith('.md') and convert_markdown: if src.endswith('.md') and convert_markdown:
rendered_file = dst.removesuffix('.md') + '.html' rendered_file = dst.removesuffix('.md') + '.html'
print(f"rendering file '{src}' -> '{rendered_file}'")
try: try:
content = handle_markdown_file_path(src) content = handle_markdown_file_path(src)
except UnicodeDecodeError: except UnicodeDecodeError:

View File

@@ -1,6 +1,6 @@
/* /*
* SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> * SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-only * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
html { html {

View File

@@ -1,6 +1,6 @@
/* /*
* SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> * SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-only * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
/* common styling via the base.css, used in light and dark */ /* common styling via the base.css, used in light and dark */

View File

@@ -1,6 +1,6 @@
/* /*
* SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> * SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-only * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
/* common styling via the base.css, used in light and dark */ /* common styling via the base.css, used in light and dark */

View File

@@ -1,6 +1,6 @@
/* /*
* SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> * SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-only * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
/* specify almost no styling, just fix some image and nav rendering */ /* specify almost no styling, just fix some image and nav rendering */

View File

@@ -5,7 +5,7 @@
* of my CMS, so I want to keep it around even in the static site. * of my CMS, so I want to keep it around even in the static site.
* *
* SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> * SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
* SPDX-License-Identifier: GPL-3.0-only * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
/** /**

View File

@@ -1,6 +1,6 @@
{# {#
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
#} #}
{% extends "base.html" %} {% extends "base.html" %}

View File

@@ -1,6 +1,6 @@
{# {#
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
#} #}
{% extends "base.html" %} {% extends "base.html" %}

View File

@@ -1,6 +1,6 @@
{# {#
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
#} #}
{% extends "base.html" %} {% extends "base.html" %}

View File

@@ -1,6 +1,6 @@
{# {#
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
#} #}
{% extends "base.html" %} {% extends "base.html" %}
{% block site_class %}class="site-wrap site-wrap-double-width"{% endblock %} {% block site_class %}class="site-wrap site-wrap-double-width"{% endblock %}

View File

@@ -1,6 +1,6 @@
<!doctype html>{# <!doctype html>{#
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
#} #}
<html lang="en"> <html lang="en">
<title>{{ title }}</title> <title>{{ title }}</title>

View File

@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
name = "incorporeal-cms" name = "incorporeal-cms"
description = "A lightweight static site generator for Markdown-based sites." description = "A lightweight static site generator for Markdown-based sites."
readme = "README.md" readme = "README.md"
license = {text = "GPL-3.0-only"} license = {text = "GPL-3.0-or-later"}
authors = [ authors = [
{name = "Brian S. Stephan", email = "bss@incorporeal.org"}, {name = "Brian S. Stephan", email = "bss@incorporeal.org"},
] ]
@@ -14,9 +14,8 @@ requires-python = ">=3.9"
dependencies = ["feedgen", "jinja2", "Markdown", "termcolor"] dependencies = ["feedgen", "jinja2", "Markdown", "termcolor"]
dynamic = ["version"] dynamic = ["version"]
classifiers = [ classifiers = [
"Framework :: Flask",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Operating System :: OS Independent", "Operating System :: OS Independent",
"Topic :: Text Processing :: Markup :: Markdown", "Topic :: Text Processing :: Markup :: Markdown",
] ]

View File

@@ -1,7 +1,7 @@
"""Test graphviz functionality. """Test graphviz functionality.
SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import os import os
import tempfile import tempfile
@@ -73,6 +73,21 @@ def test_og_image():
os.chdir(os.path.join(src_dir, 'pages')) os.chdir(os.path.join(src_dir, 'pages'))
ssg.build_file_in_destination(os.path.join(HERE, 'instance', 'pages'), '', 'more-metadata.md', tmpdir, True) ssg.build_file_in_destination(os.path.join(HERE, 'instance', 'pages'), '', 'more-metadata.md', tmpdir, True)
with open(os.path.join(tmpdir, 'more-metadata.html'), 'r') as graphviz_output: with open(os.path.join(tmpdir, 'more-metadata.html'), 'r') as markdown_output:
data = graphviz_output.read() data = markdown_output.read()
assert ('<meta property="og:image" content="http://example.org/test.img') in data assert ('<meta property="og:image" content="http://example.org/test.img">') in data
def test_og_url():
"""Test that the og:url meta tag is present as expected."""
with tempfile.TemporaryDirectory() as tmpdir:
src_dir = os.path.join(HERE, 'instance')
ssg = StaticSiteGenerator(src_dir, tmpdir)
os.chdir(os.path.join(src_dir, 'pages'))
# testing a whole build run because of bugs in how I handle pathing adding a "./" in
# the generated URLs for content in the pages/ root
ssg.build_in_destination(os.path.join(HERE, 'instance', 'pages'), tmpdir, True)
with open(os.path.join(tmpdir, 'index.html'), 'r') as markdown_output:
data = markdown_output.read()
assert ('<meta property="og:url" content="http://example.org/">') in data

View File

@@ -18,7 +18,7 @@
"level": "DEBUG", "level": "DEBUG",
"handlers": ["console"] "handlers": ["console"]
}, },
"incorporealcms.pages": { "incorporealcms.ssg": {
"level": "DEBUG", "level": "DEBUG",
"handlers": ["console"] "handlers": ["console"]
} }

View File

@@ -1,31 +0,0 @@
"""Configure the test application.
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only
"""
LOGGING = {
'version': 1,
'formatters': {
'default': {
'format': '[%(asctime)s %(levelname)-7s %(name)s] %(message)s',
},
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'default',
},
},
'loggers': {
'incorporealcms.mdx': {
'level': 'DEBUG',
'handlers': ['console'],
},
'incorporealcms.pages': {
'level': 'DEBUG',
'handlers': ['console'],
},
},
}

View File

@@ -1,7 +1,7 @@
"""Test command line invocations. """Test command line invocations.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import os import os
import tempfile import tempfile

View File

@@ -1,7 +1,7 @@
"""Test basic configuration stuff. """Test basic configuration stuff.
SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2020 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import os import os

View File

@@ -1,7 +1,7 @@
"""Test the feed methods. """Test the feed methods.
SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2023 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import os import os
import tempfile import tempfile

View File

@@ -1,7 +1,7 @@
"""Test the conversion of Markdown pages. """Test the conversion of Markdown pages.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import os import os
from unittest.mock import patch from unittest.mock import patch

View File

@@ -1,7 +1,7 @@
"""Test the high level SSG operations. """Test the high level SSG operations.
SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org> SPDX-FileCopyrightText: © 2025 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: GPL-3.0-only SPDX-License-Identifier: GPL-3.0-or-later
""" """
import os import os
import tempfile import tempfile
@@ -52,6 +52,23 @@ def test_file_copy_symlink():
assert os.path.islink(os.path.join(tmpdir, 'symlink-to-foo.txt')) assert os.path.islink(os.path.join(tmpdir, 'symlink-to-foo.txt'))
def test_file_copy_symlink_of_markdown_also_has_html_symlink():
"""Test the ability to sync source and generated symlinks to the output dir."""
with tempfile.TemporaryDirectory() as tmpdir:
src_dir = os.path.join(HERE, 'instance')
generator = ssg.StaticSiteGenerator(src_dir, tmpdir)
os.chdir(os.path.join(instance_dir, 'pages'))
generator.build_file_in_destination(os.path.join(instance_dir, 'pages'), '', 'symlink-to-no-title.md', tmpdir,
True)
# need to copy the destination for os.path.exists to be happy with this
generator.build_file_in_destination(os.path.join(instance_dir, 'pages'), '', 'no-title.md', tmpdir, True)
assert os.path.exists(os.path.join(tmpdir, 'symlink-to-no-title.md'))
assert os.path.islink(os.path.join(tmpdir, 'symlink-to-no-title.md'))
# a .md symlink should also create the .html symlink (see issue #24)
assert os.path.exists(os.path.join(tmpdir, 'symlink-to-no-title.html'))
assert os.path.islink(os.path.join(tmpdir, 'symlink-to-no-title.html'))
def test_dir_copy(): def test_dir_copy():
"""Test the ability to sync a directory to the output dir.""" """Test the ability to sync a directory to the output dir."""
with tempfile.TemporaryDirectory() as tmpdir: with tempfile.TemporaryDirectory() as tmpdir: