Source code for cookiecutter.main

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
cookiecutter.main
-----------------

Main entry point for the `cookiecutter` command.

The code in this module is also a good example of how to use Cookiecutter as a
library rather than a script.
"""

from __future__ import unicode_literals
import logging
import os
import re

from .config import get_user_config, USER_CONFIG_PATH, NOT_PROVIDED
from .exceptions import InvalidModeException, RepositoryNotFound
from .prompt import prompt_for_config
from .generate import generate_context, generate_files
from .vcs import clone
from .replay import dump, load

logger = logging.getLogger(__name__)

builtin_abbreviations = {
    'gh': 'https://github.com/{0}.git',
    'bb': 'https://bitbucket.org/{0}',
}

REPO_REGEX = re.compile(r"""
(?x)
((((git|hg)\+)?(git|ssh|https?):(//)?)  # something like git:// ssh:// etc.
 |                                      # or
 (\w+@[\w\.]+)                          # something like user@...
)
""")


[docs]def is_repo_url(value): """Return True if value is a repository URL.""" return bool(REPO_REGEX.match(value))
[docs]def expand_abbreviations(template, config_dict): """ Expand abbreviations in a template name. :param template: The project template name. :param config_dict: The user config, which will contain abbreviation definitions. """ abbreviations = builtin_abbreviations.copy() abbreviations.update(config_dict.get('abbreviations', {})) if template in abbreviations: return abbreviations[template] # Split on colon. If there is no colon, rest will be empty # and prefix will be the whole template prefix, sep, rest = template.partition(':') if prefix in abbreviations: return abbreviations[prefix].format(rest) return template
[docs]def cookiecutter( template, checkout=None, no_input=False, extra_context=None, replay=False, overwrite_if_exists=False, output_dir='.', config_file=NOT_PROVIDED): """ API equivalent to using Cookiecutter at the command line. :param template: A directory containing a project template directory, or a URL to a git repository. :param checkout: The branch, tag or commit ID to checkout after clone. :param no_input: Prompt the user at command line for manual configuration? :param extra_context: A dictionary of context that overrides default and user configuration. :param: overwrite_if_exists: Overwrite the contents of output directory if it exists :param output_dir: Where to output the generated project dir into. :param config_file: User configuration file path. """ if replay and ((no_input is not False) or (extra_context is not None)): err_msg = ( "You can not use both replay and no_input or extra_context " "at the same time." ) raise InvalidModeException(err_msg) # Get user config from ~/.cookiecutterrc or equivalent # If no config file, sensible defaults from config.DEFAULT_CONFIG are used config_dict = get_user_config(config_file=config_file) template = expand_abbreviations(template, config_dict) if is_repo_url(template): repo_dir = clone( repo_url=template, checkout=checkout, clone_to_dir=config_dict['cookiecutters_dir'], no_input=no_input ) else: # If it's a local repo, no need to clone or copy to your # cookiecutters_dir repo_dir = template if not os.path.isdir(repo_dir): raise RepositoryNotFound( 'The repository {0} could not be located.'.format(template) ) template_name = os.path.basename(template) if replay: context = load(config_dict['replay_dir'], template_name) else: context_file = os.path.join(repo_dir, 'cookiecutter.json') logging.debug('context_file is {0}'.format(context_file)) context = generate_context( context_file=context_file, default_context=config_dict['default_context'], extra_context=extra_context, ) # prompt the user to manually configure at the command line. # except when 'no-input' flag is set context['cookiecutter'] = prompt_for_config(context, no_input) dump(config_dict['replay_dir'], template_name, context) # Create project from local context and project template. return generate_files( repo_dir=repo_dir, context=context, overwrite_if_exists=overwrite_if_exists, output_dir=output_dir )