Completed
Pull Request — master (#916)
by
unknown
01:18
created

main()   C

Complexity

Conditions 7

Size

Total Lines 96

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
c 2
b 0
f 0
dl 0
loc 96
rs 5.3181

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
# -*- coding: utf-8 -*-
2
3
"""
4
cookiecutter.cli
5
-----------------
6
7
Main `cookiecutter` CLI.
8
"""
9
10
import os
11
import sys
12
import json
13
14
import click
15
16
from cookiecutter import __version__
17
from cookiecutter.log import configure_logger
18
from cookiecutter.config import get_user_config, get_config, DEFAULT_CONFIG
19
from cookiecutter.main import cookiecutter
20
from cookiecutter.exceptions import (
21
    OutputDirExistsException,
22
    InvalidModeException,
23
    FailedHookException,
24
    UndefinedVariableInTemplate,
25
    UnknownExtension,
26
    RepositoryNotFound,
27
    RepositoryCloneFailed
28
)
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
def list_installed_templates(default_config, passed_config_file):
53
    """
54
    Lists installed (locally cloned) templates. Use cookiecutter installed
55
    """
56
57
    config = get_user_config(passed_config_file, default_config)
58
    cookiecutter_folder = config.get('cookiecutters_dir')
59
60
    if not os.path.exists(cookiecutter_folder):
61
        click.echo('Error: Cannot list installed templates. ' + \
62
                   'Folder does not exist: {}'.format(cookiecutter_folder))
63
        sys.exit(-27)
64
65
    template_names = [
66
        folder
67
        for folder in os.listdir(cookiecutter_folder)
68
        if os.path.exists(os.path.join(
69
            cookiecutter_folder,
70
            folder,
71
            'cookiecutter.json'))
72
    ]
73
74
    click.echo('{} installed templates: '.format(len(template_names)))
75
    for name in template_names:
76
        click.echo(' * {}'.format(name))
77
78
79
@click.command(context_settings=dict(help_option_names=[u'-h', u'--help']))
80
@click.version_option(__version__, u'-V', u'--version', message=version_msg())
81
@click.argument(u'template')
82
@click.argument(u'extra_context', nargs=-1, callback=validate_extra_context)
83
@click.option(
84
    u'--no-input', is_flag=True,
85
    help=u'Do not prompt for parameters and only use cookiecutter.json '
86
         u'file content',
87
)
88
@click.option(
89
    u'-c', u'--checkout',
90
    help=u'branch, tag or commit to checkout after git clone',
91
)
92
@click.option(
93
    '-v', '--verbose',
94
    is_flag=True, help='Print debug information', default=False
95
)
96
@click.option(
97
    u'--replay', is_flag=True,
98
    help=u'Do not prompt for parameters and only use information entered '
99
         u'previously',
100
)
101
@click.option(
102
    u'-f', u'--overwrite-if-exists', is_flag=True,
103
    help=u'Overwrite the contents of the output directory if it already exists'
104
)
105
@click.option(
106
    u'-o', u'--output-dir', default='.', type=click.Path(),
107
    help=u'Where to output the generated project dir into'
108
)
109
@click.option(
110
    u'--config-file', type=click.Path(), default=None,
111
    help=u'User configuration file'
112
)
113
@click.option(
114
    u'--default-config', is_flag=True,
115
    help=u'Do not load a config file. Use the defaults instead'
116
)
117
@click.option(
118
    u'--debug-file', type=click.Path(), default=None,
119
    help=u'File to be used as a stream for DEBUG logging',
120
)
121
def main(
122
        template, extra_context, no_input, checkout, verbose,
123
        replay, overwrite_if_exists, output_dir, config_file,
124
        default_config, debug_file):
125
    """Create a project from a Cookiecutter project template (TEMPLATE).
126
127
    Cookiecutter is free and open source software, developed and managed by
128
    volunteers. If you would like to help out or fund the project, please get
129
    in touch at https://github.com/audreyr/cookiecutter.
130
    """
131
132
    # If you _need_ to support a local template in a directory
133
    # called 'help', use a qualified path to the directory.
134
    if template == u'help':
135
        click.echo(click.get_current_context().get_help())
136
        sys.exit(0)
137
    if template == u'installed' or template == u'i':
138
        list_installed_templates(default_config, config_file)
139
        sys.exit(0)
140
141
    configure_logger(
142
        stream_level='DEBUG' if verbose else 'INFO',
143
        debug_file=debug_file,
144
    )
145
146
    try:
147
        cookiecutter(
148
            template, checkout, no_input,
149
            extra_context=extra_context,
150
            replay=replay,
151
            overwrite_if_exists=overwrite_if_exists,
152
            output_dir=output_dir,
153
            config_file=config_file,
154
            default_config=default_config,
155
        )
156
    except (OutputDirExistsException,
157
            InvalidModeException,
158
            FailedHookException,
159
            UnknownExtension,
160
            RepositoryNotFound,
161
            RepositoryCloneFailed) as e:
162
        click.echo(e)
163
        sys.exit(1)
164
    except UndefinedVariableInTemplate as undefined_err:
165
        click.echo('{}'.format(undefined_err.message))
166
        click.echo('Error message: {}'.format(undefined_err.error.message))
167
168
        context_str = json.dumps(
169
            undefined_err.context,
170
            indent=4,
171
            sort_keys=True
172
        )
173
        click.echo('Context: {}'.format(context_str))
174
        sys.exit(1)
175
176
177
if __name__ == "__main__":
178
    main()
179