12 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
9caf08a277 changelog for v2.0.1
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-18 08:24:46 -05:00
8aabd93273 don't copy .files into the SSG output dir
they may be vim swap files and that kind of garbage

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-18 08:20:58 -05:00
6d7987cfae don't require the host to be in the Image tag
now that we know our base host via config, we can stop hardcoding it in
each Image tag

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-18 08:13:18 -05:00
abc05ee4e8 fix how my email address displays in gitea
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-17 13:22:30 -05:00
f623ffdd7c don't refer to my manual uploads now that I push to PyPI
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-17 13:13:25 -05:00
36 changed files with 167 additions and 107 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,27 @@
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
### Improvements
* The `Image` tag in Markdown files no longer requires the full URL to be specified. Now `Config.BASE_HOST` is
prepended to the tag value, which should be the full path to the image.
* `.files` are skipped when copying files to the SSG output directory.
## v2.0.0
### Features

View File

@@ -4,8 +4,7 @@ A lightweight static site generator for Markdown-based sites.
## Installation and Usage
I recommend getting a release from <https://git.incorporeal.org/bss/incorporeal-cms/releases> and
installing the Python package in a virtualenv. Something like the following should suffice:
Something like the following should suffice:
```
% virtualenv --python=python3.9 env-py3.9
@@ -15,19 +14,19 @@ installing the Python package in a virtualenv. Something like the following shou
% 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
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:
* 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 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.
* 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.
## Configuration
@@ -53,19 +52,18 @@ out and discuss issues and features and whatnot.
## Author and Licensing
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
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3 of the License.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General
Public License as published by the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License along with this program. If not, see
<https://www.gnu.org/licenses/>.
### 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.
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 logging

View File

@@ -1,7 +1,7 @@
"""Default configuration.
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.
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

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.
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 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.
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 logging
@@ -90,7 +90,7 @@ def handle_markdown_file_path(path: str) -> str:
return template.render(title=page_title,
config=Config,
description=get_meta_str(md, 'description'),
image=get_meta_str(md, 'image'),
image=Config.BASE_HOST + get_meta_str(md, 'image'),
content=content,
base_url=Config.BASE_HOST + instance_resource_path_to_request_path(path),
navs=parent_navs,

View File

@@ -1,5 +1,5 @@
"""Markdown extensions.
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.
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
from xml.etree.ElementTree import SubElement # nosec B405

View File

@@ -1,7 +1,7 @@
"""Serve dot diagrams inline.
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 logging

View File

@@ -1,9 +1,10 @@
"""Build an instance as a static site suitable for serving via e.g. Nginx.
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 logging
import os
import shutil
import stat
@@ -16,6 +17,8 @@ from incorporealcms.error_pages import generate_error_pages
from incorporealcms.feed import generate_feed
from incorporealcms.markdown import handle_markdown_file_path
logger = logging.getLogger(__name__)
class StaticSiteGenerator(object):
"""Generate static site output based on the instance's content."""
@@ -53,10 +56,6 @@ class StaticSiteGenerator(object):
pass
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
cprint("generating feeds", 'green')
generate_feed('atom', self.instance_dir, tmp_output_dir)
@@ -89,14 +88,19 @@ class StaticSiteGenerator(object):
cprint(f"copying files from '{source_dir}' to '{dest_dir}'", 'green')
os.chdir(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
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
for subdir in subdirs:
self.build_subdir_in_destination(source_dir, base_dir, subdir, dest_dir)
# process and copy files
for file_ in files:
if file_[0] == '.':
cprint(f"skipping {file_}", 'yellow')
continue
self.build_file_in_destination(source_dir, base_dir, file_, dest_dir, convert_markdown)
def build_subdir_in_destination(self, source_dir: str, base_dir: str, subdir: str, dest_dir: str) -> None:
@@ -138,6 +142,14 @@ class StaticSiteGenerator(object):
src = self.symlink_to_relative_dest(source_dir, os.path.join(base_dir, file_))
print(f"creating symlink '{dst}' -> '{src}'")
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:
src = os.path.join(base_dir, file_)
print(f"copying file '{src}' -> '{dst}'")
@@ -146,6 +158,7 @@ class StaticSiteGenerator(object):
# render markdown as HTML
if src.endswith('.md') and convert_markdown:
rendered_file = dst.removesuffix('.md') + '.html'
print(f"rendering file '{src}' -> '{rendered_file}'")
try:
content = handle_markdown_file_path(src)
except UnicodeDecodeError:

View File

@@ -1,6 +1,6 @@
/*
* 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 {

View File

@@ -1,6 +1,6 @@
/*
* 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 */

View File

@@ -1,6 +1,6 @@
/*
* 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 */

View File

@@ -1,6 +1,6 @@
/*
* 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 */

View File

@@ -5,7 +5,7 @@
* 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-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-License-Identifier: GPL-3.0-only
SPDX-License-Identifier: GPL-3.0-or-later
#}
{% extends "base.html" %}

View File

@@ -1,6 +1,6 @@
{#
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" %}

View File

@@ -1,6 +1,6 @@
{#
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" %}

View File

@@ -1,6 +1,6 @@
{#
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" %}
{% block site_class %}class="site-wrap site-wrap-double-width"{% endblock %}

View File

@@ -1,13 +1,13 @@
<!doctype html>{#
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">
<title>{{ title }}</title>
<meta charset="utf-8">
<meta property="og:url" content="{{ base_url }}">
{% if title %}<meta property="og:title" content="{{ title }}">{% endif %}
{% if description %}<meta property="og:description" content="{{ description }}">{% endif %}
<meta property="og:url" content="{{ base_url }}">
{% if image %}<meta property="og:image" content="{{ image }}">{% endif %}
<meta name="twitter:card" content="summary_large_image">
<meta name="viewport" content="width=device-width, initial-scale=1">

View File

@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
name = "incorporeal-cms"
description = "A lightweight static site generator for Markdown-based sites."
readme = "README.md"
license = {text = "GPL-3.0-only"}
license = {text = "GPL-3.0-or-later"}
authors = [
{name = "Brian S. Stephan", email = "bss@incorporeal.org"},
]
@@ -14,9 +14,8 @@ requires-python = ">=3.9"
dependencies = ["feedgen", "jinja2", "Markdown", "termcolor"]
dynamic = ["version"]
classifiers = [
"Framework :: Flask",
"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",
"Topic :: Text Processing :: Markup :: Markdown",
]

View File

@@ -1,7 +1,7 @@
"""Test graphviz functionality.
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 tempfile
@@ -63,3 +63,31 @@ def test_figures_are_rendered():
'<span></span></figure>') in data
assert '<figure><img alt="just a logo" src="bss-square-no-bg.png" /></figure>' in data
os.chdir(HERE)
def test_og_image():
"""Test that the og:image 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'))
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 markdown_output:
data = markdown_output.read()
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",
"handlers": ["console"]
},
"incorporealcms.pages": {
"incorporealcms.ssg": {
"level": "DEBUG",
"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

@@ -0,0 +1 @@
this is ignored

View File

@@ -1,6 +1,6 @@
Title: title for the page
Description: description of this page
made even longer
Image: http://buh.com/test.img
Image: /test.img
hello

View File

@@ -1,7 +1,7 @@
"""Test command line invocations.
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 tempfile

View File

@@ -1,7 +1,7 @@
"""Test basic configuration stuff.
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

View File

@@ -1,7 +1,7 @@
"""Test the feed methods.
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 tempfile

View File

@@ -1,7 +1,7 @@
"""Test the conversion of Markdown pages.
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
from unittest.mock import patch

View File

@@ -1,7 +1,7 @@
"""Test the high level SSG operations.
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 tempfile
@@ -52,6 +52,23 @@ def test_file_copy_symlink():
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():
"""Test the ability to sync a directory to the output dir."""
with tempfile.TemporaryDirectory() as tmpdir:
@@ -88,3 +105,13 @@ def test_build_in_destination():
assert os.path.exists(os.path.join(tmpdir, 'index.html'))
assert os.path.exists(os.path.join(tmpdir, 'subdir', 'index.md'))
assert os.path.exists(os.path.join(tmpdir, 'subdir', 'index.html'))
def test_build_in_destination_ignores_dot_files():
"""Test the ability to walk a source and populate the destination."""
with tempfile.TemporaryDirectory() as tmpdir:
src_dir = os.path.join(HERE, 'instance')
generator = ssg.StaticSiteGenerator(src_dir, tmpdir)
generator.build_in_destination(os.path.join(src_dir, 'pages'), tmpdir)
assert not os.path.exists(os.path.join(tmpdir, '.ignored-file.md'))