mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
f4b64b8700
17 changed files with 215 additions and 113 deletions
36
.travis.yml
36
.travis.yml
|
|
@ -2,11 +2,18 @@ language: python
|
|||
python:
|
||||
- "3.6"
|
||||
env:
|
||||
- TOX_ENV=docs
|
||||
- TOX_ENV=flake8
|
||||
- TOX_ENV=py27
|
||||
- TOX_ENV=py35
|
||||
- TOX_ENV=py36
|
||||
global:
|
||||
- PYPI_USERNAME=autopub
|
||||
- secure: "h5V/+YL+CrqvfAesNkSb824Ngk5x+f0eFzj/LBbmnzjvArKAmc6R6WGyx8SDD7WF/PlaTf0M1fH3a7pjIS8Ee+TS1Rb0Lt1HPqUs1yntg1+Js2ZQp3p20wfsDc+bZ4/2g8xLsSMv1EJ4np7/GJ5fXqpSxjr/Xs5LYA7ZLwNNwDw="
|
||||
- secure: "GiDFfmjH7uzYNnkjQMV/mIkbRdmgkGmtbFPeaj9taBNA5tPp3IBt3GOOS6UL/zm9xiwu9Xo6sxZWkGzY19Hsdv28YPH34N3abo0QSnz4IGiHs152Hi7Qi6Tb0QkT5D3OxuSIm8LmFL7+su89Q7vBFowrT6HL1Mn8CDDWSj3eqbo="
|
||||
- TWINE_USERNAME=$PYPI_USERNAME
|
||||
- TWINE_PASSWORD=$PYPI_PASSWORD
|
||||
matrix:
|
||||
- TOX_ENV=docs
|
||||
- TOX_ENV=flake8
|
||||
- TOX_ENV=py27
|
||||
- TOX_ENV=py35
|
||||
- TOX_ENV=py36
|
||||
matrix:
|
||||
include:
|
||||
- python: 3.7
|
||||
|
|
@ -23,8 +30,25 @@ before_install:
|
|||
install:
|
||||
- pip install tox==2.5.0
|
||||
script: tox -e $TOX_ENV
|
||||
before_deploy:
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then travis_terminate 0; fi'
|
||||
- pip install githubrelease
|
||||
- pip install --pre autopub
|
||||
- autopub check || travis_terminate 0
|
||||
- pip install poetry
|
||||
- pip install twine
|
||||
- git checkout ${TRAVIS_BRANCH}
|
||||
- git remote set-url origin https://$GITHUB_TOKEN@github.com/$TRAVIS_REPO_SLUG
|
||||
deploy:
|
||||
provider: script
|
||||
script: autopub deploy
|
||||
skip_cleanup: true
|
||||
on:
|
||||
branch: master
|
||||
python: "3.7"
|
||||
# The channel name "irc.freenode.org#pelican" is encrypted against getpelican/pelican to prevent IRC spam of forks
|
||||
notifications:
|
||||
irc:
|
||||
channels:
|
||||
- "irc.freenode.org#pelican"
|
||||
- secure: "JP57f61QovrhmLoAF6oPOzIK2aXGfSO06FHg7yiuKBOWMiaxQejZUGJX919muCLhWJXDugsviIqCMoAWwNV3o1WQbqIr+G5TR+N9MrtCs4Zi6vpGj09bR8giKUKx+PPKEoe1Ew56E4y2LxzGO4Lj9hZx8M2YVdwPNWrWZgp6WXE="
|
||||
on_success: change
|
||||
|
|
|
|||
|
|
@ -97,6 +97,14 @@ Using Git and GitHub
|
|||
For example, if you're hacking on a new feature and find a bugfix that
|
||||
doesn't *require* your new feature, **make a new distinct branch and pull
|
||||
request** for the bugfix.
|
||||
* Add a ``RELEASE.md`` file in the root of the project that contains the
|
||||
release type (major, minor, patch) and a summary of the changes that will be
|
||||
used as the release changelog entry. For example::
|
||||
|
||||
Release type: minor
|
||||
|
||||
Reload browser window upon changes to content, settings, or theme
|
||||
|
||||
* Check for unnecessary whitespace via ``git diff --check`` before committing.
|
||||
* First line of your commit message should start with present-tense verb, be 50
|
||||
characters or less, and include the relevant issue number(s) if applicable.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,30 @@
|
|||
Release history
|
||||
###############
|
||||
|
||||
4.1.3 - 2019-10-09
|
||||
==================
|
||||
|
||||
* Fix quick-start docs regarding `pelican --listen`
|
||||
* Set default listen address to 127.0.0.1
|
||||
* Add extra/optional Markdown dependency to setup.py
|
||||
* Use correct SSH port syntax for rsync in tasks.py
|
||||
* Place all deprecated settings handling together
|
||||
* Add related project URLs for display on PyPI
|
||||
* Skip some tests on Windows that can't pass due to filesystem differences
|
||||
|
||||
4.1.2 - 2019-09-23
|
||||
==================
|
||||
|
||||
Fix pelican.settings.load_source to avoid caching issues - PR #2621
|
||||
|
||||
4.1.1 - 2019-08-23
|
||||
==================
|
||||
|
||||
* Add AutoPub to auto-publish releases on PR merge
|
||||
* Add CSS classes for reStructuredText figures
|
||||
* Pass `argv` to Pelican `main` entrypoint
|
||||
* Set default content status to a blank string rather than `None`
|
||||
|
||||
4.1.0 - 2019-07-14
|
||||
==================
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ You can install Pelican via several different methods. The simplest is via
|
|||
|
||||
pip install pelican
|
||||
|
||||
Or, if you plan on using Markdown::
|
||||
|
||||
pip install pelican[Markdown]
|
||||
|
||||
(Keep in mind that operating systems will often require you to prefix the above
|
||||
command with ``sudo`` in order to install Pelican system-wide.)
|
||||
|
||||
|
|
@ -40,7 +44,11 @@ Optional packages
|
|||
-----------------
|
||||
|
||||
If you plan on using `Markdown <http://pypi.python.org/pypi/Markdown>`_ as a
|
||||
markup format, you'll need to install the Markdown library::
|
||||
markup format, you can install Pelican with Markdown support::
|
||||
|
||||
pip install pelican[Markdown]
|
||||
|
||||
Or you might need to install it a posteriori::
|
||||
|
||||
pip install Markdown
|
||||
|
||||
|
|
|
|||
|
|
@ -54,20 +54,12 @@ HTML files directly::
|
|||
firefox output/index.html
|
||||
|
||||
Because the above method may have trouble locating your CSS and other linked
|
||||
assets, running a simple web server using Python will often provide a more
|
||||
reliable previewing experience.
|
||||
assets, running Pelican's simple built-in web server will often provide a more
|
||||
reliable previewing experience::
|
||||
|
||||
For Python 2, run::
|
||||
pelican --listen
|
||||
|
||||
cd output
|
||||
python -m SimpleHTTPServer
|
||||
|
||||
For Python 3, run::
|
||||
|
||||
cd output
|
||||
python -m http.server
|
||||
|
||||
Once the basic server has been started, you can preview your site at
|
||||
Once the web server has been started, you can preview your site at:
|
||||
http://localhost:8000/
|
||||
|
||||
Deployment
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ Installation
|
|||
------------
|
||||
|
||||
Install Pelican (and optionally Markdown if you intend to use it) on Python
|
||||
2.7.x or Python 3.3+ by running the following command in your preferred
|
||||
2.7.x or Python 3.5+ by running the following command in your preferred
|
||||
terminal, prefixing with ``sudo`` if permissions warrant::
|
||||
|
||||
pip install pelican markdown
|
||||
pip install pelican[Markdown]
|
||||
|
||||
Create a project
|
||||
----------------
|
||||
|
|
@ -50,18 +50,18 @@ Given that this example article is in Markdown format, save it as
|
|||
Generate your site
|
||||
------------------
|
||||
|
||||
From your site directory, run the ``pelican`` command to generate your site::
|
||||
From your project root directory, run the ``pelican`` command to generate your site::
|
||||
|
||||
pelican content
|
||||
|
||||
Your site has now been generated inside the ``output`` directory. (You may see
|
||||
Your site has now been generated inside the ``output/`` directory. (You may see
|
||||
a warning related to feeds, but that is normal when developing locally and can
|
||||
be ignored for now.)
|
||||
|
||||
Preview your site
|
||||
-----------------
|
||||
|
||||
Open a new terminal session, navigate to your generated output directory and
|
||||
Open a new terminal session, navigate to your project root directory, and
|
||||
run the following command to launch Pelican's web server::
|
||||
|
||||
pelican --listen
|
||||
|
|
|
|||
|
|
@ -991,7 +991,7 @@ By default, pages subsequent to ``.../foo.html`` are created as
|
|||
``.../foo2.html``, etc. The ``PAGINATION_PATTERNS`` setting can be used to
|
||||
change this. It takes a sequence of triples, where each triple consists of::
|
||||
|
||||
(minimum_page, page_url, page_save_as,)
|
||||
(minimum_page, page_url, page_save_as,)
|
||||
|
||||
For ``page_url`` and ``page_save_as``, you may use a number of variables.
|
||||
``{url}`` and ``{save_as}`` correspond respectively to the ``*_URL`` and
|
||||
|
|
@ -1005,7 +1005,7 @@ subsequent pages at ``.../page/2/`` etc, you could set ``PAGINATION_PATTERNS``
|
|||
as follows::
|
||||
|
||||
PAGINATION_PATTERNS = (
|
||||
(1, '{url}', '{save_as}`,
|
||||
(1, '{url}', '{save_as}',
|
||||
(2, '{base_name}/page/{number}/', '{base_name}/page/{number}/index.html'),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ output_file The name of the file currently being generated. For
|
|||
articles The list of articles, ordered descending by date.
|
||||
All the elements are `Article` objects, so you can
|
||||
access their attributes (e.g. title, summary, author
|
||||
etc.). Sometimes this is shadowed (for instance in
|
||||
etc.). Sometimes this is shadowed (for instance, in
|
||||
the tags page). You will then find info about it
|
||||
in the `all_articles` variable.
|
||||
dates The same list of articles, but ordered by date,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import logging
|
|||
import multiprocessing
|
||||
import os
|
||||
import pprint
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
|
|
@ -52,7 +51,6 @@ class Pelican(object):
|
|||
|
||||
# define the default settings
|
||||
self.settings = settings
|
||||
self._handle_deprecation()
|
||||
|
||||
self.path = settings['PATH']
|
||||
self.theme = settings['THEME']
|
||||
|
|
@ -94,65 +92,6 @@ class Pelican(object):
|
|||
logger.debug('Restoring system path')
|
||||
sys.path = _sys_path
|
||||
|
||||
def _handle_deprecation(self):
|
||||
|
||||
if self.settings.get('CLEAN_URLS', False):
|
||||
logger.warning('Found deprecated `CLEAN_URLS` in settings.'
|
||||
' Modifying the following settings for the'
|
||||
' same behaviour.')
|
||||
|
||||
self.settings['ARTICLE_URL'] = '{slug}/'
|
||||
self.settings['ARTICLE_LANG_URL'] = '{slug}-{lang}/'
|
||||
self.settings['PAGE_URL'] = 'pages/{slug}/'
|
||||
self.settings['PAGE_LANG_URL'] = 'pages/{slug}-{lang}/'
|
||||
|
||||
for setting in ('ARTICLE_URL', 'ARTICLE_LANG_URL', 'PAGE_URL',
|
||||
'PAGE_LANG_URL'):
|
||||
logger.warning("%s = '%s'", setting, self.settings[setting])
|
||||
|
||||
if self.settings.get('AUTORELOAD_IGNORE_CACHE'):
|
||||
logger.warning('Found deprecated `AUTORELOAD_IGNORE_CACHE` in '
|
||||
'settings. Use --ignore-cache instead.')
|
||||
self.settings.pop('AUTORELOAD_IGNORE_CACHE')
|
||||
|
||||
if self.settings.get('ARTICLE_PERMALINK_STRUCTURE', False):
|
||||
logger.warning('Found deprecated `ARTICLE_PERMALINK_STRUCTURE` in'
|
||||
' settings. Modifying the following settings for'
|
||||
' the same behaviour.')
|
||||
|
||||
structure = self.settings['ARTICLE_PERMALINK_STRUCTURE']
|
||||
|
||||
# Convert %(variable) into {variable}.
|
||||
structure = re.sub(r'%\((\w+)\)s', r'{\g<1>}', structure)
|
||||
|
||||
# Convert %x into {date:%x} for strftime
|
||||
structure = re.sub(r'(%[A-z])', r'{date:\g<1>}', structure)
|
||||
|
||||
# Strip a / prefix
|
||||
structure = re.sub('^/', '', structure)
|
||||
|
||||
for setting in ('ARTICLE_URL', 'ARTICLE_LANG_URL', 'PAGE_URL',
|
||||
'PAGE_LANG_URL', 'DRAFT_URL', 'DRAFT_LANG_URL',
|
||||
'ARTICLE_SAVE_AS', 'ARTICLE_LANG_SAVE_AS',
|
||||
'DRAFT_SAVE_AS', 'DRAFT_LANG_SAVE_AS',
|
||||
'PAGE_SAVE_AS', 'PAGE_LANG_SAVE_AS'):
|
||||
self.settings[setting] = os.path.join(structure,
|
||||
self.settings[setting])
|
||||
logger.warning("%s = '%s'", setting, self.settings[setting])
|
||||
|
||||
for new, old in [('FEED', 'FEED_ATOM'), ('TAG_FEED', 'TAG_FEED_ATOM'),
|
||||
('CATEGORY_FEED', 'CATEGORY_FEED_ATOM'),
|
||||
('TRANSLATION_FEED', 'TRANSLATION_FEED_ATOM')]:
|
||||
if self.settings.get(new, False):
|
||||
logger.warning(
|
||||
'Found deprecated `%(new)s` in settings. Modify %(new)s '
|
||||
'to %(old)s in your settings and theme for the same '
|
||||
'behavior. Temporarily setting %(old)s for backwards '
|
||||
'compatibility.',
|
||||
{'new': new, 'old': old}
|
||||
)
|
||||
self.settings[old] = self.settings[new]
|
||||
|
||||
def run(self):
|
||||
"""Run the generators and return"""
|
||||
start_time = time.time()
|
||||
|
|
@ -307,7 +246,7 @@ class PrintSettings(argparse.Action):
|
|||
parser.exit()
|
||||
|
||||
|
||||
def parse_arguments():
|
||||
def parse_arguments(argv=None):
|
||||
parser = argparse.ArgumentParser(
|
||||
description='A tool to generate a static blog, '
|
||||
' with restructured text input files.',
|
||||
|
|
@ -400,7 +339,7 @@ def parse_arguments():
|
|||
help='IP to bind to when serving files via HTTP '
|
||||
'(default: 127.0.0.1)')
|
||||
|
||||
args = parser.parse_args()
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
if args.port is not None and not args.listen:
|
||||
logger.warning('--port without --listen has no effect')
|
||||
|
|
@ -560,8 +499,8 @@ def listen(server, port, output, excqueue=None):
|
|||
return
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_arguments()
|
||||
def main(argv=None):
|
||||
args = parse_arguments(argv)
|
||||
logs_dedup_min_level = getattr(logging, args.logs_dedup_min_level)
|
||||
init_logging(args.verbosity, args.fatal,
|
||||
logs_dedup_min_level=logs_dedup_min_level)
|
||||
|
|
|
|||
|
|
@ -141,7 +141,8 @@ class Content(object):
|
|||
|
||||
# manage status
|
||||
if not hasattr(self, 'status'):
|
||||
self.status = getattr(self, 'default_status', None)
|
||||
# Previous default of None broke comment plugins and perhaps others
|
||||
self.status = getattr(self, 'default_status', '')
|
||||
|
||||
# store the summary metadata if it is set
|
||||
if 'summary' in metadata:
|
||||
|
|
|
|||
|
|
@ -14,12 +14,16 @@ import six
|
|||
|
||||
from pelican.log import LimitFilter
|
||||
|
||||
|
||||
try:
|
||||
# SourceFileLoader is the recommended way in Python 3.3+
|
||||
from importlib.machinery import SourceFileLoader
|
||||
# spec_from_file_location is the recommended way in Python 3.5+
|
||||
import importlib.util
|
||||
|
||||
def load_source(name, path):
|
||||
return SourceFileLoader(name, path).load_module()
|
||||
spec = importlib.util.spec_from_file_location(name, path)
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(mod)
|
||||
return mod
|
||||
except ImportError:
|
||||
# but it does not exist in Python 2.7, so fall back to imp
|
||||
import imp
|
||||
|
|
@ -167,7 +171,7 @@ DEFAULT_CONFIG = {
|
|||
'WRITE_SELECTED': [],
|
||||
'FORMATTED_FIELDS': ['summary'],
|
||||
'PORT': 8000,
|
||||
'BIND': '',
|
||||
'BIND': '127.0.0.1',
|
||||
}
|
||||
|
||||
PYGMENTS_RST_OPTIONS = None
|
||||
|
|
@ -439,6 +443,67 @@ def handle_deprecated_settings(settings):
|
|||
'Falling back to default.', key)
|
||||
settings[key] = DEFAULT_CONFIG[key]
|
||||
|
||||
# CLEAN_URLS
|
||||
if settings.get('CLEAN_URLS', False):
|
||||
logger.warning('Found deprecated `CLEAN_URLS` in settings.'
|
||||
' Modifying the following settings for the'
|
||||
' same behaviour.')
|
||||
|
||||
settings['ARTICLE_URL'] = '{slug}/'
|
||||
settings['ARTICLE_LANG_URL'] = '{slug}-{lang}/'
|
||||
settings['PAGE_URL'] = 'pages/{slug}/'
|
||||
settings['PAGE_LANG_URL'] = 'pages/{slug}-{lang}/'
|
||||
|
||||
for setting in ('ARTICLE_URL', 'ARTICLE_LANG_URL', 'PAGE_URL',
|
||||
'PAGE_LANG_URL'):
|
||||
logger.warning("%s = '%s'", setting, settings[setting])
|
||||
|
||||
# AUTORELOAD_IGNORE_CACHE -> --ignore-cache
|
||||
if settings.get('AUTORELOAD_IGNORE_CACHE'):
|
||||
logger.warning('Found deprecated `AUTORELOAD_IGNORE_CACHE` in '
|
||||
'settings. Use --ignore-cache instead.')
|
||||
settings.pop('AUTORELOAD_IGNORE_CACHE')
|
||||
|
||||
# ARTICLE_PERMALINK_STRUCTURE
|
||||
if settings.get('ARTICLE_PERMALINK_STRUCTURE', False):
|
||||
logger.warning('Found deprecated `ARTICLE_PERMALINK_STRUCTURE` in'
|
||||
' settings. Modifying the following settings for'
|
||||
' the same behaviour.')
|
||||
|
||||
structure = settings['ARTICLE_PERMALINK_STRUCTURE']
|
||||
|
||||
# Convert %(variable) into {variable}.
|
||||
structure = re.sub(r'%\((\w+)\)s', r'{\g<1>}', structure)
|
||||
|
||||
# Convert %x into {date:%x} for strftime
|
||||
structure = re.sub(r'(%[A-z])', r'{date:\g<1>}', structure)
|
||||
|
||||
# Strip a / prefix
|
||||
structure = re.sub('^/', '', structure)
|
||||
|
||||
for setting in ('ARTICLE_URL', 'ARTICLE_LANG_URL', 'PAGE_URL',
|
||||
'PAGE_LANG_URL', 'DRAFT_URL', 'DRAFT_LANG_URL',
|
||||
'ARTICLE_SAVE_AS', 'ARTICLE_LANG_SAVE_AS',
|
||||
'DRAFT_SAVE_AS', 'DRAFT_LANG_SAVE_AS',
|
||||
'PAGE_SAVE_AS', 'PAGE_LANG_SAVE_AS'):
|
||||
settings[setting] = os.path.join(structure,
|
||||
settings[setting])
|
||||
logger.warning("%s = '%s'", setting, settings[setting])
|
||||
|
||||
# {,TAG,CATEGORY,TRANSLATION}_FEED -> {,TAG,CATEGORY,TRANSLATION}_FEED_ATOM
|
||||
for new, old in [('FEED', 'FEED_ATOM'), ('TAG_FEED', 'TAG_FEED_ATOM'),
|
||||
('CATEGORY_FEED', 'CATEGORY_FEED_ATOM'),
|
||||
('TRANSLATION_FEED', 'TRANSLATION_FEED_ATOM')]:
|
||||
if settings.get(new, False):
|
||||
logger.warning(
|
||||
'Found deprecated `%(new)s` in settings. Modify %(new)s '
|
||||
'to %(old)s in your settings and theme for the same '
|
||||
'behavior. Temporarily setting %(old)s for backwards '
|
||||
'compatibility.',
|
||||
{'new': new, 'old': old}
|
||||
)
|
||||
settings[old] = settings[new]
|
||||
|
||||
return settings
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,10 @@ import six
|
|||
from pelican.contents import Article, Author, Category, Page, Static
|
||||
from pelican.settings import DEFAULT_CONFIG
|
||||
from pelican.signals import content_object_init
|
||||
from pelican.tests.support import LoggedTestCase, get_context, get_settings,\
|
||||
unittest
|
||||
from pelican.utils import SafeDatetime, path_to_url, truncate_html_words
|
||||
from pelican.tests.support import (LoggedTestCase, get_context, get_settings,
|
||||
unittest)
|
||||
from pelican.utils import (SafeDatetime, path_to_url, posixize_path,
|
||||
truncate_html_words)
|
||||
|
||||
|
||||
# generate one paragraph, enclosed with <p>
|
||||
|
|
@ -943,7 +944,7 @@ class TestStatic(LoggedTestCase):
|
|||
source_path=os.path.join('dir', 'foo.jpg'),
|
||||
context=self.settings.copy())
|
||||
|
||||
expected_save_as = os.path.join('dir', 'foo.jpg')
|
||||
expected_save_as = posixize_path(os.path.join('dir', 'foo.jpg'))
|
||||
self.assertEqual(static.status, 'draft')
|
||||
self.assertEqual(static.save_as, expected_save_as)
|
||||
self.assertEqual(static.url, path_to_url(expected_save_as))
|
||||
|
|
|
|||
|
|
@ -1089,7 +1089,12 @@ class TestStaticGenerator(unittest.TestCase):
|
|||
os.mkdir(os.path.join(self.temp_output, "static"))
|
||||
self.generator.fallback_to_symlinks = True
|
||||
self.generator.generate_context()
|
||||
self.generator.generate_output(None)
|
||||
try:
|
||||
self.generator.generate_output(None)
|
||||
except OSError as e:
|
||||
# On Windows, possibly others, due to not holding symbolic link
|
||||
# privilege
|
||||
self.skipTest(e)
|
||||
self.assertTrue(os.path.islink(self.endfile))
|
||||
|
||||
def test_existing_symlink_is_considered_up_to_date(self):
|
||||
|
|
@ -1097,7 +1102,11 @@ class TestStaticGenerator(unittest.TestCase):
|
|||
with open(self.startfile, "w") as f:
|
||||
f.write("staticcontent")
|
||||
os.mkdir(os.path.join(self.temp_output, "static"))
|
||||
os.symlink(self.startfile, self.endfile)
|
||||
try:
|
||||
os.symlink(self.startfile, self.endfile)
|
||||
except OSError as e:
|
||||
# On Windows, possibly others
|
||||
self.skipTest(e)
|
||||
staticfile = MagicMock()
|
||||
staticfile.source_path = self.startfile
|
||||
staticfile.save_as = self.endfile
|
||||
|
|
@ -1109,7 +1118,11 @@ class TestStaticGenerator(unittest.TestCase):
|
|||
with open(self.startfile, "w") as f:
|
||||
f.write("staticcontent")
|
||||
os.mkdir(os.path.join(self.temp_output, "static"))
|
||||
os.symlink("invalid", self.endfile)
|
||||
try:
|
||||
os.symlink("invalid", self.endfile)
|
||||
except OSError as e:
|
||||
# On Windows, possibly others
|
||||
self.skipTest(e)
|
||||
staticfile = MagicMock()
|
||||
staticfile.source_path = self.startfile
|
||||
staticfile.save_as = self.endfile
|
||||
|
|
|
|||
|
|
@ -717,6 +717,8 @@ class TestDateFormatter(unittest.TestCase):
|
|||
|
||||
|
||||
class TestSanitisedJoin(unittest.TestCase):
|
||||
@unittest.skipIf(platform == 'win32',
|
||||
"Different filesystem root on Windows")
|
||||
def test_detect_parent_breakout(self):
|
||||
with six.assertRaisesRegex(
|
||||
self,
|
||||
|
|
@ -727,6 +729,8 @@ class TestSanitisedJoin(unittest.TestCase):
|
|||
"../test"
|
||||
)
|
||||
|
||||
@unittest.skipIf(platform == 'win32',
|
||||
"Different filesystem root on Windows")
|
||||
def test_detect_root_breakout(self):
|
||||
with six.assertRaisesRegex(
|
||||
self,
|
||||
|
|
@ -737,6 +741,8 @@ class TestSanitisedJoin(unittest.TestCase):
|
|||
"/test"
|
||||
)
|
||||
|
||||
@unittest.skipIf(platform == 'win32',
|
||||
"Different filesystem root on Windows")
|
||||
def test_pass_deep_subpaths(self):
|
||||
self.assertEqual(
|
||||
utils.sanitised_join(
|
||||
|
|
|
|||
|
|
@ -23,8 +23,10 @@ CONFIG = {
|
|||
'deploy_path': SETTINGS['OUTPUT_PATH'],
|
||||
{% if ssh %}
|
||||
# Remote server configuration
|
||||
'production': '{{ssh_user}}@{{ssh_host}}:{{ssh_port}}',
|
||||
'dest_path': '{{ssh_target_dir}}',
|
||||
'ssh_user': '{{ssh_user}}',
|
||||
'ssh_host': '{{ssh_host}}',
|
||||
'ssh_port': '{{ssh_port}}',
|
||||
'ssh_path': '{{ssh_target_dir}}',
|
||||
{% endif %}
|
||||
{% if cloudfiles %}
|
||||
# Rackspace Cloud Files configuration settings
|
||||
|
|
@ -130,7 +132,8 @@ def publish(c):
|
|||
c.run('pelican -s {settings_publish}'.format(**CONFIG))
|
||||
c.run(
|
||||
'rsync --delete --exclude ".DS_Store" -pthrvz -c '
|
||||
'{} {production}:{dest_path}'.format(
|
||||
'-e "ssh -p {ssh_port}" '
|
||||
'{} {ssh_user}@{ssh_host}:{ssh_path}'.format(
|
||||
CONFIG['deploy_path'].rstrip('/') + '/',
|
||||
**CONFIG))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "pelican"
|
||||
version = "4.1.0"
|
||||
version = "4.1.3"
|
||||
description = "Static site generator supporting Markdown and reStructuredText"
|
||||
authors = ["Justin Mayer <entrop@gmail.com>"]
|
||||
license = "AGPLv3"
|
||||
|
|
@ -59,6 +59,15 @@ markdown = ["markdown"]
|
|||
[tool.poetry.scripts]
|
||||
pelican = "pelican.__main__:main"
|
||||
|
||||
[tool.autopub]
|
||||
project-name = "Pelican"
|
||||
git-username = "botpub"
|
||||
git-email = "botpub@autopub.rocks"
|
||||
changelog-file = "docs/changelog.rst"
|
||||
changelog-header = "###############"
|
||||
version-header = "="
|
||||
version-strings = ["setup.py"]
|
||||
build-system = "setuptools"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry>=0.12"]
|
||||
build-backend = "poetry.masonry.api"
|
||||
requires = ["setuptools >= 40.6.0", "wheel"]
|
||||
|
|
|
|||
15
setup.py
15
setup.py
|
|
@ -7,7 +7,7 @@ from os.path import join, relpath
|
|||
from setuptools import setup
|
||||
|
||||
|
||||
version = "4.1.0"
|
||||
version = "4.1.3"
|
||||
|
||||
requires = ['feedgenerator >= 1.9', 'jinja2 >= 2.7', 'pygments', 'docutils',
|
||||
'pytz >= 0a', 'blinker', 'unidecode', 'six >= 1.4',
|
||||
|
|
@ -33,11 +33,17 @@ setup(
|
|||
name='pelican',
|
||||
version=version,
|
||||
url='https://getpelican.com/',
|
||||
author='Alexis Metaireau',
|
||||
maintainer='Justin Mayer',
|
||||
author='Justin Mayer',
|
||||
author_email='authors@getpelican.com',
|
||||
description="Static site generator supporting reStructuredText and "
|
||||
"Markdown source content.",
|
||||
project_urls={
|
||||
'Documentation': 'https://docs.getpelican.com/',
|
||||
'Funding': 'https://donate.getpelican.com/',
|
||||
'Source': 'https://github.com/getpelican/pelican',
|
||||
'Tracker': 'https://github.com/getpelican/pelican/issues',
|
||||
},
|
||||
keywords='static web site generator SSG reStructuredText Markdown',
|
||||
license='AGPLv3',
|
||||
long_description=description,
|
||||
packages=['pelican', 'pelican.tools'],
|
||||
|
|
@ -55,6 +61,9 @@ setup(
|
|||
for name in names],
|
||||
},
|
||||
install_requires=requires,
|
||||
extras_require={
|
||||
'Markdown': ['markdown~=3.1.1']
|
||||
},
|
||||
entry_points=entry_points,
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue