Completed
Pull Request — master (#400)
by
unknown
01:11
created

cookiecutter.main()   D

Complexity

Conditions 8

Size

Total Lines 93

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 8
dl 0
loc 93
rs 4.2139

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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