Skip to content

Instantly share code, notes, and snippets.

@ivanvenosdel
Last active June 15, 2017 20:49
Show Gist options
  • Save ivanvenosdel/fa410ecf417d2b1b8a17d23ffd58839d to your computer and use it in GitHub Desktop.
Save ivanvenosdel/fa410ecf417d2b1b8a17d23ffd58839d to your computer and use it in GitHub Desktop.
An example of a pelican project's Fabric-based fabfile.py converted to a pynt-based build.py, including in-project virtualenv support
import os
import shutil
from pynt import task
from pyntcontrib import safe_cd, execute
MODULE_PATH = os.path.abspath(__file__)
PROJECT_ROOT = os.path.dirname(MODULE_PATH)
REQUIREMENTS_PATH = os.path.join(PROJECT_ROOT, 'requirements.txt')
VENV_PATH = os.path.join(PROJECT_ROOT, 'venv')
PYTHON_PATH = os.path.join(VENV_PATH, 'bin/python')
SHELL_PATH = os.path.join(VENV_PATH, 'bin/bpython')
PIP_PATH = os.path.join(VENV_PATH, 'bin/pip')
PELICAN_PATH = os.path.join(VENV_PATH, 'bin/pelican')
DEPLOY_PATH = os.path.join(PROJECT_ROOT, 'output')
SERVE_PORT = 8000
@task()
def delete_venv():
shutil.rmtree(VENV_PATH)
@task()
def create_venv():
"""Create virtualenv w/local_requirements"""
if not os.path.isdir(VENV_PATH):
execute('virtualenv', '--distribute', '--no-site-packages', '--python=python3.6', VENV_PATH)
execute(PYTHON_PATH, '-m', 'easy_install', 'pip')
execute(PIP_PATH, 'install', '--upgrade', '-r', REQUIREMENTS_PATH)
@task()
def recreate_venv():
"""Deletes and re creates virtualenv"""
delete_venv()
create_venv()
@task()
def clean():
"""Wipes any compiled python files"""
execute('find', PROJECT_ROOT, '-name', '*.pyc', '-delete')
execute('find', PROJECT_ROOT, '-name', '*.pyo', '-delete')
execute('find', PROJECT_ROOT, '-name', '*~', '-delete')
execute('find', PROJECT_ROOT, '-name', '__pycache__', '-exec', '"rm -r"', '{}', ';')
if os.path.isdir(DEPLOY_PATH):
shutil.rmtree(DEPLOY_PATH)
os.makedirs(DEPLOY_PATH)
@task()
def build():
"""Build local version of site"""
execute(PELICAN_PATH, '-s', 'pelicanconf.py')
@task()
def rebuild():
"""`build` with the delete switch"""
execute(PELICAN_PATH, '-d', '-s', 'pelicanconf.py')
@task()
def regenerate():
"""Automatically regenerate site upon file modification"""
execute(PELICAN_PATH, '-r', '-s', 'pelicanconf.py')
@task()
def serve():
"""Serve site at http://localhost:8000/"""
with safe_cd(DEPLOY_PATH):
execute(PYTHON_PATH, '-m', 'pelican.server', str(SERVE_PORT))
@task()
def reserve():
"""`build`, then `serve`"""
build()
serve()
@task()
def preview():
"""Build production version of site"""
execute(PELICAN_PATH, '-s', 'publishconf.py')
@task()
def shell():
execute(SHELL_PATH)
@ivanvenosdel
Copy link
Author

ivanvenosdel commented Jun 15, 2017

NOTE: Rename file to build.py to work with pynt command.

Advantages to using pynt over fabric

  • Easy install on all platforms (it's pure python)
  • Supports both python2 and python3

Advantages of this style of build.py

  • Easier to get going (pip install pynt, pynt -l, pynt create). No need to even activate a venv in most cases.
  • No need to install dependencies into your system's default python

Limitations (by design)

  • Manages an in-project venv (it is expected that 'venv' will be in your .gitignore)
  • Does not have local development build tasks alongside remote deploy/publish tasks. The advantage to this is that the build.py is simpler and pynt will allows mean "this will not affect anyone but me". The disadvantage is that you have to know two tools, one for your local environment and something else for working with a remote environment. That said, nothing prevents you from adding your own remote build tasks (e.g. publish) to your version of this example.

Enjoy!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment