Completed
Push — dry-undefined-variable-excepti... ( d183c8...3df04f )
by Michael
01:19
created

validate_extra_context()   A

Complexity

Conditions 4

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 4
c 2
b 0
f 0
dl 0
loc 11
rs 9.2
1
# -*- coding: utf-8 -*-
2
3
"""
4
cookiecutter.cli
5
-----------------
6
7
Main `cookiecutter` CLI.
8
"""
9
10
import os
11
import sys
12
import logging
13
14
import click
15
16
from cookiecutter import __version__
17
from cookiecutter.config import USER_CONFIG_PATH
18
from cookiecutter.main import cookiecutter
19
from cookiecutter.exceptions import (
20
    OutputDirExistsException,
21
    InvalidModeException,
22
    FailedHookException,
23
    UndefinedVariableInTemplate,
24
    UnknownExtension,
25
    RepositoryNotFound
26
)
27
28
logger = logging.getLogger(__name__)
29
30
31
def version_msg():
32
    """Returns the Cookiecutter version, location and Python powering it."""
33
    python_version = sys.version[:3]
34
    location = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
35
    message = u'Cookiecutter %(version)s from {} (Python {})'
36
    return message.format(location, python_version)
37
38
39
def validate_extra_context(ctx, param, value):
40
    for s in value:
41
        if '=' not in s:
42
            raise click.BadParameter(
43
                'EXTRA_CONTEXT should contain items of the form key=value; '
44
                "'{}' doesn't match that form".format(s)
45
            )
46
47
    # Convert tuple -- e.g.: (u'program_name=foobar', u'startsecs=66')
48
    # to dict -- e.g.: {'program_name': 'foobar', 'startsecs': '66'}
49
    return dict(s.split('=', 1) for s in value) or None
50
51
52
@click.command(context_settings=dict(help_option_names=[u'-h', u'--help']))
53
@click.version_option(__version__, u'-V', u'--version', message=version_msg())
54
@click.argument(u'template')
55
@click.argument(u'extra_context', nargs=-1, callback=validate_extra_context)
56
@click.option(
57
    u'--no-input', is_flag=True,
58
    help=u'Do not prompt for parameters and only use cookiecutter.json '
59
         u'file content',
60
)
61
@click.option(
62
    u'-c', u'--checkout',
63
    help=u'branch, tag or commit to checkout after git clone',
64
)
65
@click.option(
66
    '-v', '--verbose',
67
    is_flag=True, help='Print debug information', default=False
68
)
69
@click.option(
70
    u'--replay', is_flag=True,
71
    help=u'Do not prompt for parameters and only use information entered '
72
         u'previously',
73
)
74
@click.option(
75
    u'-f', u'--overwrite-if-exists', is_flag=True,
76
    help=u'Overwrite the contents of the output directory if it already exists'
77
)
78
@click.option(
79
    u'-o', u'--output-dir', default='.', type=click.Path(),
80
    help=u'Where to output the generated project dir into'
81
)
82
@click.option(
83
    u'--config-file', type=click.Path(), default=USER_CONFIG_PATH,
84
    help=u'User configuration file'
85
)
86
@click.option(
87
    u'--default-config', is_flag=True,
88
    help=u'Do not load a config file. Use the defaults instead'
89
)
90
def main(template, extra_context, no_input, checkout, verbose, replay,
91
         overwrite_if_exists, output_dir, config_file, default_config):
92
    """Create a project from a Cookiecutter project template (TEMPLATE)."""
93
    if verbose:
94
        logging.basicConfig(
95
            format=u'%(levelname)s %(filename)s: %(message)s',
96
            level=logging.DEBUG
97
        )
98
    else:
99
        # Log info and above to console
100
        logging.basicConfig(
101
            format=u'%(levelname)s: %(message)s',
102
            level=logging.INFO
103
        )
104
105
    try:
106
        # If you _need_ to support a local template in a directory
107
        # called 'help', use a qualified path to the directory.
108
        if template == u'help':
109
            click.echo(click.get_current_context().get_help())
110
            sys.exit(0)
111
112
        user_config = None if default_config else config_file
113
114
        cookiecutter(
115
            template, checkout, no_input,
116
            extra_context=extra_context,
117
            replay=replay,
118
            overwrite_if_exists=overwrite_if_exists,
119
            output_dir=output_dir,
120
            config_file=user_config
121
        )
122
    except (OutputDirExistsException,
123
            InvalidModeException,
124
            FailedHookException,
125
            UnknownExtension,
126
            RepositoryNotFound,
127
            UndefinedVariableInTemplate) as e:
128
        click.echo(e)
129
        sys.exit(1)
130
131
132
if __name__ == "__main__":
133
    main()
134