Conditions | 9 |
Total Lines | 167 |
Code Lines | 129 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
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:
If many parameters/temporary variables are present:
Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.
There are several approaches to avoid long parameter lists:
1 | """Main `cookiecutter` CLI.""" |
||
70 | @click.command(context_settings=dict(help_option_names=['-h', '--help'])) |
||
71 | @click.version_option(__version__, '-V', '--version', message=version_msg()) |
||
72 | @click.argument('template', required=False) |
||
73 | @click.argument('extra_context', nargs=-1, callback=validate_extra_context) |
||
74 | @click.option( |
||
75 | '--no-input', |
||
76 | is_flag=True, |
||
77 | help='Do not prompt for parameters and only use cookiecutter.json file content. ' |
||
78 | 'Defaults to deleting any cached resources and redownloading them. ' |
||
79 | 'Cannot be combined with the --replay flag.', |
||
80 | ) |
||
81 | @click.option( |
||
82 | '-c', |
||
83 | '--checkout', |
||
84 | help='branch, tag or commit to checkout after git clone', |
||
85 | ) |
||
86 | @click.option( |
||
87 | '--directory', |
||
88 | help='Directory within repo that holds cookiecutter.json file ' |
||
89 | 'for advanced repositories with multi templates in it', |
||
90 | ) |
||
91 | @click.option( |
||
92 | '-v', '--verbose', is_flag=True, help='Print debug information', default=False |
||
93 | ) |
||
94 | @click.option( |
||
95 | '--replay', |
||
96 | is_flag=True, |
||
97 | help='Do not prompt for parameters and only use information entered previously. ' |
||
98 | 'Cannot be combined with the --no-input flag or with extra configuration passed.', |
||
99 | ) |
||
100 | @click.option( |
||
101 | '--replay-file', |
||
102 | type=click.Path(), |
||
103 | default=None, |
||
104 | help='Use this file for replay instead of the default.', |
||
105 | ) |
||
106 | @click.option( |
||
107 | '-f', |
||
108 | '--overwrite-if-exists', |
||
109 | is_flag=True, |
||
110 | help='Overwrite the contents of the output directory if it already exists', |
||
111 | ) |
||
112 | @click.option( |
||
113 | '-s', |
||
114 | '--skip-if-file-exists', |
||
115 | is_flag=True, |
||
116 | help='Skip the files in the corresponding directories if they already exist', |
||
117 | default=False, |
||
118 | ) |
||
119 | @click.option( |
||
120 | '-o', |
||
121 | '--output-dir', |
||
122 | default='.', |
||
123 | type=click.Path(), |
||
124 | help='Where to output the generated project dir into', |
||
125 | ) |
||
126 | @click.option( |
||
127 | '--config-file', type=click.Path(), default=None, help='User configuration file' |
||
128 | ) |
||
129 | @click.option( |
||
130 | '--default-config', |
||
131 | is_flag=True, |
||
132 | help='Do not load a config file. Use the defaults instead', |
||
133 | ) |
||
134 | @click.option( |
||
135 | '--debug-file', |
||
136 | type=click.Path(), |
||
137 | default=None, |
||
138 | help='File to be used as a stream for DEBUG logging', |
||
139 | ) |
||
140 | @click.option( |
||
141 | '--accept-hooks', |
||
142 | type=click.Choice(['yes', 'ask', 'no']), |
||
143 | default='yes', |
||
144 | help='Accept pre/post hooks', |
||
145 | ) |
||
146 | @click.option( |
||
147 | '-l', '--list-installed', is_flag=True, help='List currently installed templates.' |
||
148 | ) |
||
149 | @click.option( |
||
150 | '--keep-project-on-failure', |
||
151 | is_flag=True, |
||
152 | help='Do not delete project folder on failure', |
||
153 | ) |
||
154 | def main( |
||
155 | template, |
||
156 | extra_context, |
||
157 | no_input, |
||
158 | checkout, |
||
159 | verbose, |
||
160 | replay, |
||
161 | overwrite_if_exists, |
||
162 | output_dir, |
||
163 | config_file, |
||
164 | default_config, |
||
165 | debug_file, |
||
166 | directory, |
||
167 | skip_if_file_exists, |
||
168 | accept_hooks, |
||
169 | replay_file, |
||
170 | list_installed, |
||
171 | keep_project_on_failure, |
||
172 | ): |
||
173 | """Create a project from a Cookiecutter project template (TEMPLATE). |
||
174 | |||
175 | Cookiecutter is free and open source software, developed and managed by |
||
176 | volunteers. If you would like to help out or fund the project, please get |
||
177 | in touch at https://github.com/cookiecutter/cookiecutter. |
||
178 | """ |
||
179 | # Commands that should work without arguments |
||
180 | if list_installed: |
||
181 | list_installed_templates(default_config, config_file) |
||
182 | sys.exit(0) |
||
183 | |||
184 | # Raising usage, after all commands that should work without args. |
||
185 | if not template or template.lower() == 'help': |
||
186 | click.echo(click.get_current_context().get_help()) |
||
187 | sys.exit(0) |
||
188 | |||
189 | configure_logger(stream_level='DEBUG' if verbose else 'INFO', debug_file=debug_file) |
||
190 | |||
191 | # If needed, prompt the user to ask whether or not they want to execute |
||
192 | # the pre/post hooks. |
||
193 | if accept_hooks == "ask": |
||
194 | _accept_hooks = click.confirm("Do you want to execute hooks?") |
||
195 | else: |
||
196 | _accept_hooks = accept_hooks == "yes" |
||
197 | |||
198 | if replay_file: |
||
199 | replay = replay_file |
||
200 | |||
201 | try: |
||
202 | cookiecutter( |
||
203 | template, |
||
204 | checkout, |
||
205 | no_input, |
||
206 | extra_context=extra_context, |
||
207 | replay=replay, |
||
208 | overwrite_if_exists=overwrite_if_exists, |
||
209 | output_dir=output_dir, |
||
210 | config_file=config_file, |
||
211 | default_config=default_config, |
||
212 | password=os.environ.get('COOKIECUTTER_REPO_PASSWORD'), |
||
213 | directory=directory, |
||
214 | skip_if_file_exists=skip_if_file_exists, |
||
215 | accept_hooks=_accept_hooks, |
||
216 | keep_project_on_failure=keep_project_on_failure, |
||
217 | ) |
||
218 | except ( |
||
219 | ContextDecodingException, |
||
220 | OutputDirExistsException, |
||
221 | InvalidModeException, |
||
222 | FailedHookException, |
||
223 | UnknownExtension, |
||
224 | InvalidZipRepository, |
||
225 | RepositoryNotFound, |
||
226 | RepositoryCloneFailed, |
||
227 | ) as e: |
||
228 | click.echo(e) |
||
229 | sys.exit(1) |
||
230 | except UndefinedVariableInTemplate as undefined_err: |
||
231 | click.echo(f'{undefined_err.message}') |
||
232 | click.echo(f'Error message: {undefined_err.error.message}') |
||
233 | |||
234 | context_str = json.dumps(undefined_err.context, indent=4, sort_keys=True) |
||
235 | click.echo(f'Context: {context_str}') |
||
236 | sys.exit(1) |
||
237 | |||
241 |