kivy-ios/tools/external/cookiecutter/hooks.py

107 lines
2.8 KiB
Python
Executable file

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
cookiecutter.hooks
------------------
Functions for discovering and executing various cookiecutter hooks.
"""
import io
import logging
import os
import subprocess
import sys
import tempfile
from jinja2 import Template
from cookiecutter import utils
_HOOKS = [
'pre_gen_project',
'post_gen_project',
# TODO: other hooks should be listed here
]
def find_hooks():
"""
Must be called with the project template as the current working directory.
Returns a dict of all hook scripts provided.
Dict's key will be the hook/script's name, without extension, while
values will be the absolute path to the script.
Missing scripts will not be included in the returned dict.
"""
hooks_dir = 'hooks'
r = {}
logging.debug('hooks_dir is {0}'.format(hooks_dir))
if not os.path.isdir(hooks_dir):
logging.debug('No hooks/ dir in template_dir')
return r
for f in os.listdir(hooks_dir):
basename = os.path.splitext(os.path.basename(f))[0]
if basename in _HOOKS:
r[basename] = os.path.abspath(os.path.join(hooks_dir, f))
return r
def run_script(script_path, cwd='.'):
"""
Executes a script from a working directory.
:param script_path: Absolute path to the script to run.
:param cwd: The directory to run the script from.
"""
run_thru_shell = sys.platform.startswith('win')
if script_path.endswith('.py'):
script_command = [sys.executable, script_path]
else:
script_command = [script_path]
utils.make_executable(script_path)
proc = subprocess.Popen(
script_command,
shell=run_thru_shell,
cwd=cwd
)
proc.wait()
def run_script_with_context(script_path, cwd, context):
"""
Executes a script after rendering with it Jinja.
:param script_path: Absolute path to the script to run.
:param cwd: The directory to run the script from.
:param context: Cookiecutter project template context.
"""
_, extension = os.path.splitext(script_path)
contents = io.open(script_path, 'r', encoding='utf-8').read()
with tempfile.NamedTemporaryFile(
delete=False,
mode='w',
suffix=extension
) as temp:
temp.write(Template(contents).render(**context))
run_script(temp.name, cwd)
def run_hook(hook_name, project_dir, context):
"""
Try to find and execute a hook from the specified project directory.
:param hook_name: The hook to execute.
:param project_dir: The directory to execute the script from.
:param context: Cookiecutter project context.
"""
script = find_hooks().get(hook_name)
if script is None:
logging.debug('No hooks found')
return
return run_script_with_context(script, project_dir, context)