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