Closed GenevieveBuckley closed 1 month ago
Thanks for reopening @GenevieveBuckley! š
Tests are failing currently š¤ Also when I pull this down to try it out, I got an error:
$ copier copy --trust cookiecutter-napari-plugin algospatial
No git tags found in template; using HEAD as ref
š¤ The name of your plugin
algospatial
š¤ Display name for your plugin
AlgoSpatial
š¤ Plugin module name
algospatial
š¤ Short description of what your plugin does
Spatial algorithms in napari
š¤ Developer name
Juan Nunez-Iglesias
š¤ Email address
juan.nunez-iglesias@monash.edu
š¤ Github user or organisation name
jni
š¤ Github repository URL
provide later
š¤ Include reader plugin?
Yes
š¤ Include writer plugin?
No
š¤ Include sample data plugin?
No
š¤ Include widget plugin?
Yes
š¤ Use git tags for versioning?
Yes
š¤ Install pre-commit? (Code formatting checks)
No
š¤ Install dependabot? (Automatic security updates of dependency versions)
No
š¤ Which licence do you want your plugin code to have?
Mozilla Public License 2.0
Copying from template version 0.0.0.post109.dev0+134ce29
create .
create .napari-hub
create .napari-hub/DESCRIPTION.md
create .napari-hub/config-yml
create .gitignore
create .github
create .github/workflows
create .github/workflows/test_and_deploy
create src
create src/algospatial
create src/algospatial/_tests
create src/algospatial/_tests/__init__.py
followed by this crash:
Traceback (most recent call last):
File "/Users/jni/micromamba/envs/copier/bin/copier", line 10, in <module>
sys.exit(CopierApp.run())
^^^^^^^^^^^^^^^
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/plumbum/cli/application.py", line 638, in run
inst, retcode = subapp.run(argv, exit=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/plumbum/cli/application.py", line 633, in run
retcode = inst.main(*tailargs)
^^^^^^^^^^^^^^^^^^^^
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/copier/cli.py", line 280, in main
return _handle_exceptions(inner)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/copier/cli.py", line 70, in _handle_exceptions
method()
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/copier/cli.py", line 271, in inner
with self._worker(
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/copier/main.py", line 217, in __exit__
raise value
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/copier/cli.py", line 278, in inner
worker.run_copy()
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/copier/main.py", line 769, in run_copy
self._render_folder(src_abspath)
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/copier/main.py", line 659, in _render_folder
self._render_folder(file)
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/copier/main.py", line 659, in _render_folder
self._render_folder(file)
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/copier/main.py", line 659, in _render_folder
self._render_folder(file)
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/copier/main.py", line 661, in _render_folder
self._render_file(file)
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/copier/main.py", line 582, in _render_file
new_content = tpl.render(**self._render_context()).encode()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/jinja2/environment.py", line 1304, in render
self.environment.handle_exception()
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/jinja2/environment.py", line 939, in handle_exception
raise rewrite_traceback_stack(source=source)
File "/private/var/folders/z7/mv1jznhx59q5vc3bp09gj69m0000gn/T/copier.vcs.clone.y8mvpar1/template/src/{{module_name}}/_tests/{% if include_widget_plugin %}test_widget.py{% endif %}.jinja", line 3, in top-level template code
File "/Users/jni/micromamba/envs/copier/lib/python3.12/site-packages/jinja2/sandbox.py", line 327, in getattr
value = getattr(obj, attribute)
^^^^^^^^^^^^^^^^^^^^^^^
jinja2.exceptions.UndefinedError: 'cookiecutter' is undefined
maybe something missing from carrying the PR over? (Since there shouldn't be any reference to cookiecutter left...?)
Also, the plugin name is a default rather than a placeholder ā I think it should also be a placeholder?
Also, the plugin name is a default rather than a placeholder ā I think it should also be a placeholder?
I'm starting to feel like placeholders are most suitable for optional variables. Otherwise, if someone just hits enter the whole way through the prompts, that will give us empty prompt values and can crash the operation. Opinions?
You must have a non-empty value for three questions: plugin_name
, display_name
, and module_name
. If any of those are left blank, because of how we've set the template repository up, you can't create a new repo from it. There's a returned non-zero exit status 1
error message.
I'm fine with an error. I personally find it jarring to have to erase text to type what I want. It would be better if copier would give you the option of setting something as not-empty so that the error could be caught early, but I think that's a thing for copier to worry about, not us. (Maybe the feature exists, or maybe we can make an issue in the repo.)
https://copier.readthedocs.io/en/stable/reference/user_data/#copier.user_data.Question
Looks like you can put in a "validator":
Jinja template with which to validate the user input. This template will be rendered with the combined answers as variables; it should render nothing if the value is valid, and an error message to show to the user otherwise.
I'm not familiar enough with template language here but I presume we can implement exactly the check above...
Oh good. There's one more check that needs to happen - a valid email address also appears to be required (you can generate a new repo from the template without it, but then tox will fail on that new repo)
Here's an example of using validators:
https://copier.readthedocs.io/en/stable/configuring/#advanced-prompt-formatting
project_name:
type: str # Any value will be treated raw as a string
help: An awesome project needs an awesome name. Tell me yours.
default: paradox-specifier
validator: >-
{% if not (project_name | regex_search('^[a-z][a-z0-9\-]+$')) %}
project_name must start with a letter, followed one or more letters, digits or dashes all lowercase.
{% endif %}
Ooh, maybe we can also use the validators to check module_name first the PEP specs. If we can get rid of _tasks.py
, then we don't need to use the copier --trust
command anymore, which would be nice.
The above validator seems to do just that, so I think that's a yes! And indeed it would be amazing!
Two points:
_tasks.py
and --trust
. It does more than just plugin and module name validation (also git init, optional pre-commit install, and validating the manifest with npe2). I'd forgotten about those extra tasks in my excitement.Closing in favour of napari/napari-plugin-template#7
This PR switches the plugin template repo to using copier instead of cookiecutter
The biggest advantage of using copier is that users can run
copier update
to check for any changes in the template.This will be very useful for ongoing code maintenance (eg: updating versions of dependencies, any changes required to keep the
test_and_deploy
github action working smoothly, etc.)But it also has some smaller advantages, like being able to conditionally generate files, depending on the user's answers to the prompt questions (cookiecutter does not do this, were were previously using a hack in the
hooks/post_gen.py
file to delete the unnecessary files)Steps required (ideally all steps should be close to simultaneous):
napari-plugin-template
instead ofcookiecutter-napari-plugin
(and remove the other testnapari-plugin-template
repo)Previously: