72 Commits

Author SHA1 Message Date
Sigurd Spieckermann
2491c0681b refactor: re-expose API with deprecation warnings on non-public API imports 2025-04-22 13:52:51 +02:00
Sigurd Spieckermann
ef5ea4b212 refactor: rename internal modules with a _ prefix 2025-04-22 13:52:51 +02:00
Sigurd Spieckermann
3daa5bc89c fix: expose only answers in question rendering context 2025-02-28 16:41:40 +01:00
danieleades
1c2f8d8b08
style: use pathlib 2025-02-26 17:42:21 +01:00
Jairo Llopis
25bc06d01d feat(external_data): load data from other YAML files
When composing templates, it's often needed to be able to load answers from other templates that you know are usually combined with yours. Or any other kind of external data.

@moduon MT-8282
2025-02-16 08:00:21 +00:00
Axel H.
0a9644d249 feat(settings): add user settings support with defaults values (fix #235) 2025-01-29 19:46:06 +01:00
Adrian Freund
d6f226f2b3
feat: add simpler migrations configuration syntax (#1510) 2024-05-15 11:19:11 +02:00
Sigurd Spieckermann
0e5350e966 test: reuse git_init() helper 2024-04-16 19:38:22 +02:00
danieleades
0c6b0b96fe
build(typing): enable 'strict' mypy linting (#1527)
---------

Co-authored-by: Timothée Mazzucotelli <dev@pawamoy.fr>
2024-03-23 12:58:20 +01:00
Sigurd Spieckermann
037d7f04a3 refactor: drop pyyaml-include dependency and reimplement relevant features 2024-02-28 17:18:23 +01:00
Sigurd Spieckermann
14865bfe8e fix: ignore empty YAML documents in copier.yml 2024-02-28 13:06:20 +01:00
danieleades
878c4d4f40
style: add 'flake-future-annotations' lint group (#1506)
* add ruff 'flake8-future-annotations' (FA) lint group
2024-02-22 06:19:17 +00:00
Jairo Llopis
19be0a1a74 build(lint): switch over to ruff; add taplo
Ruff is faster, better integrated, easier to configure... Cool!

Taplo also helps with toml maintenance.
2024-01-15 18:26:48 +00:00
Sigurd Spieckermann
9218e22807 fix: require default value for secret question 2023-07-19 05:53:26 +01:00
Timothée Mazzucotelli
a42a3a702c
build: support Pydantic v2 (#1229)
Co-authored-by: Sigurd Spieckermann <sigurd.spieckermann@gmail.com>
Co-authored-by: Jairo Llopis <yajo.sk8@gmail.com>
2023-07-14 11:44:02 +02:00
Sigurd Spieckermann
7fbf287d5f
build: clean up secret questions management 2023-07-10 18:34:02 +00:00
Jairo Llopis
6996b9cc7a feat: add recopy command and function
This new command allows to reapply a template, keeping old answers but discarding subproject evolution.

It is useful when there are bugs replaying an old version of the template, or when the subproject has drifted too much from the template and you need to reset it.

BREAKING CHANGE: All CLI calls to Copier must now include the subcommand as the 1st argument. For example, `copier` must become now `copier update`; also `copier ./tpl ./dst` must become `copier copy ./tpl ./dst`.

BREAKING CHANGE: All flags must go after the subcommand now. For example, `copier -r HEAD update ./dst` must now become `copier update -r HEAD ./dst` or `copier update ./dst -r HEAD`.

BREAKING CHANGE: Automatic mode removed. Since now subcommands are required, the automatic mode is removed.

BREAKING CHANGE: Deprecated `copier.copy` function is removed. Use `copier.run_copy`, `copier.run_update` or `copier.run_recopy` explicitly as needed.

Fix https://github.com/copier-org/copier/issues/1081
Close https://github.com/copier-org/copier/issues/1082
2023-05-17 11:56:13 +01:00
Sigurd Spieckermann
5029b6e7a9
test: add type hints and clean up (#985)
* refactor(tests): add type hints and clean up

* fix: import `Protocol` from `typing-extensions` when using Python 3.7

* fix: import `Literal` from `typing-extensions` when using Python 3.7

* refactor(tests): create template and subproject directory using `tmp_path_factory` fixture

* refactor(tests): use OS-agnostic file path separator

* refactor(tests): use `/` separator for `skip_if_exists` paths

* style: fix formatting error

* refactor(tests): expect POSIX path for local repo URL
2023-03-21 16:31:11 +00:00
Sascha Desch
f643d846cd test: add test case for merging settings
The test case checks that merging entries for the the settings
`skip_if_exists`, `exclude`, `jinja_extensions` and
`secret_questions` work as expected and entries are concatenated.
2022-10-27 08:37:39 +01:00
Sigurd Spieckermann
34a4feea85 refactor: model a task to execute using a dataclass 2022-09-24 09:28:17 +01:00
Jacob Straszynski
126a7460b5
feat: allow overriden defaults in questionnaire (#477)
* allow overriden defaults in questionnaire

This works in conjunction with https://github.com/copier-org/copier/pull/476.
If partial answers are written out to a file, they can be re-loaded as
default overrides to whatever is specified in the template allowing one
to resume progress.

* fix failing test
2021-11-20 17:36:16 +00:00
Yajo
c390685f05 test: fix other cases of force removal 2021-07-02 15:34:51 +01:00
Dennis Roche
a1fcccf906 test: Replace force=True with defaults=True, overwrite=True 2021-07-02 15:34:51 +01:00
Jairo Llopis
1482de4972
wip 2021-03-05 17:33:11 +00:00
Jairo Llopis
d86c88d051 Refactor a bit how version warnings are issued
- Move template methods to template module.
- Remove load_config_data.
- Verification on lazy property.
- Add Template.min_copier_version.
- Add tools.copier_version.
2021-02-17 07:53:15 +00:00
Jairo Llopis
0441b86f0c
Refactor (#314)
* Refactor
* Fix #110.
* Rewrite test_config_exclude, test_config_exclude_overridden and test_config_include. These tests were badly designed, using a monkeypatch that would never happen in the real world, and actually producing false positives. I moved them to test_exclude.py and rewritten to test the what and not the how.
* Fix #214 by removing skip option. Relevant tests use the better skip_if_exists=["**"].
* Remove subdirectory flag from API/CLI. It was confusing and could lead to bad maintenance situations. Fixes #315.
* Remove extra_paths and fix #321
* Remember that you cannot use _copier_conf.src_path as a path now
* use dataclasses
* Create errors module, simplify some tests, fix many others
* Fix some tests, complete EnvOps removal
* Fix #214 and some tests related to it
* Reorder code
* Update docs and imports
* Modularize test_complex_questions
* Interlink worker and questionary a bit better
* Removal of Questionary class, which only had 1 meaningful method that is now merged into Worker to avoid circular dependencies.
* Fix #280 in a simple way: only user answers are type-casted inside API, and CLI transforms all `--data` using YAML always. Predictable.
* Use prereleases correctly.
* Reorder AnswersMap to have a more significative repr.
* Simpler cache for old `Question.get_choices()` method (renamed now).
* fix wrong test
* Fix test_subdirectory
* Fix test_tasks (and remove tests/demo_tasks)
* Fix path filter tests, and move it to test_exclude, where it belongs
* Make test_config pass
* Fix more wrongly designed tests
* Use cached_property backport if needed
* xfail test known to fail on mac
* force posix paths on windows
* Add typing_extensions for python < 3.8
* Sort dependencies in pyproject.toml
* Support python 3.6 str-to-datetime conversion
* Workaround https://bugs.python.org/issue43095
* xfail test_path_filter on windows
* Upgrade mkdocs and other dependencies to fix https://github.com/pawamoy/mkdocstrings/issues/222
* Add missing reference docs.
* Add workaround for https://github.com/pawamoy/mkdocstrings/pull/209
* Docs.
* Remove validators module
* Add workaround for https://github.com/pawamoy/mkdocstrings/issues/225
* Restore docs autorefs as explained in https://github.com/pawamoy/mkdocstrings/issues/226#issuecomment-775413562.
* Workaround https://github.com/pawamoy/pytkdocs/issues/86
2021-02-09 18:22:47 +00:00
Jairo Llopis
b479cb9804 Make exclude extend if called from CLI/API
When adding the `exclude` option from CLI/API, it extends the definitions found in `copier.yml`.

When adding it in `copier.yml`, it replaces the defaults.

Fixes #215, which explains that it was very unexpected that excluding some extra things included a lot of other things by accident.
2020-09-18 10:55:09 +00:00
Jairo Llopis
6e7cff8b37 Allow multidoc copier.yml with glob include
Before this patch, using `!include` was a bit absurd because it would fail under any useful scenario:

- Including with a glob.
- Trying to include more than 1 file.

Now all those are supported, and they can coexist. Besides, the patch is quite simple, which makes it more attractive.

Fix #237.
2020-09-05 11:22:42 +00:00
Jairo Llopis
2cf5be072a Print all logs to sys.stderr 2020-08-17 07:59:25 +01:00
Jairo Llopis
9bd9400580 Windows fixes
- Ignore errors when executing `shutil.rmtree()`, because it seems like it's common to fail when deleting git repos on Windows, and since these are temp files, we don't really care that much there's garbage left. Any good OS should clean the temp folders automatically.
- Always find Jinja templates in `PosixPath` mode.
- Ignore `OSError` when trying to enter a possibly git root directory. This is yielded by Windows when the path is a URL and we don't really care about it.
- Fix some tests with non-windows hardcoded stuff.
- Fix a test that was using a Bash script. Modified to be Python, which should work fine cross-system.
- Remove external python dependencies (yaml, plumbum) from test task/migration files. These are available on Linux because it gets the python env from the venv, but on Windows, it uses the main python interpreter and breaks. After all, that's not very important here.
- Do not modify EOL in CI.
- Use python executable in tests instead of python3.
- Update pre-commit versions to include https://github.com/pre-commit/pre-commit-hooks/pull/509.
- Disable autorebasing.
- Disable pre-commit on CI on Windows.
- Require python 3.8 on Windows, where `tempfile` supports autoremoving directories with read-only files.
2020-08-08 15:27:56 +00:00
Jairo Llopis
823f3a1935 Remove dst fixture
This is redundant with pytest's native `tmp_path` fixture, so we use that one instead now.
2020-06-23 07:58:03 +00:00
Jairo Llopis
f7aee2857d Remember answer procedence
- `ConfigData` objects now know where do answers come from.
- Their `.data` attribute is now a computed property that merges all those answer sources in priority order.
- To merge dicts, `ChainMap` is used extensively.
- `query_user_data` gets both `last_answer_data` and `forced_answers_data` instead of the single `answers_data` argument it got before.
- By knowing where does an answer come from, now Copier avoids asking something if the user already answered that from other source. For example, if you use `copier -d some_question=some_answer copy $src $dst`, then Copier will not ask you about `some_question` again, because you already answered that. 🎉
- All answer sources are deep-copied to avoid modifying mutable dicts and affecting further copier executions.
- A minimal amount of tests got updated as they were now supposed to fail with new behavior.
- Ignore flake8 `E501 line too long` errors. We use black, that's just unnecessarily annoying.

@Tecnativa TT23705
2020-06-18 09:24:58 +01:00
Timothée Mazzucotelli
c4b38a1ec6 Add subdirectory option
Co-authored-by: Jairo Llopis <Yajo@users.noreply.github.com>
2020-05-20 19:41:10 +02:00
Jairo Llopis
55a49c2386
Fix default answers_file location
After #163, a `copier.yml` file without a `_answers_file` definition would default to `None` instead of `".copier-answers.yml"` as expected.

I modified some tests to reproduce this failure, and fixed them.

@Tecnativa TT20357
2020-03-16 14:00:55 +00:00
Jairo Llopis
d44ba2fbfb
Allow to choose custom answers file
With this enhacenment, template designers are able to choose a different default path for the `.copier-answers.yml` file, and users are still able to alter it via their API/CLI calls.

The main purpose for this is to let users use several templates to fill the same destination directory, and still be able to autoupdate all of them by just providing the answers file path to use.

@Tecnativa TT20357
2020-03-16 12:50:02 +00:00
Jairo Llopis
293d84f73d
Add secret questions support
Secrets questions are available in the jinja render context, but are not logged into `.copier-answers.yml` by default.

To mark a question as secret, just set `secret: true` into its definition. You can also pass a list of question keys in `_secret_questions` if you prefer.

@Tecnativa TT20357
2020-03-02 11:42:11 +00:00
Ben Felder
6ae7cc5c54
Update transclude tests 2020-02-28 15:12:51 +01:00
Ben Felder
1878854e57
Add test_config_data_multi_transclusion 2020-02-28 13:55:35 +01:00
Ben Felder
eef2374a1f
Add test_config_data_empty 2020-02-27 22:08:28 +01:00
Ben Felder
d5f67ea5d3
Unify similar tests under parameterized test_invalid_config_data 2020-02-27 20:23:01 +01:00
Ben Felder
cd256fa5cc
Add test_invalid_yaml_empty 2020-02-27 20:03:50 +01:00
Ben Felder
1dac0f0d57
Add basic test for yaml transclusion 2020-02-27 12:09:28 +01:00
Ben Felder
c451f4c949
Remove ignore option, adapt tests 2020-02-26 15:50:28 +01:00
Jairo Llopis
6bf0cedd3a
Add migrations support
This commit fixes #119. Summary:

- Depend on packaging to get a good implementation of PEP 440.
- Document new behaviors.
- Add support for migrations.
- Checkout by default the most modern git tag available in the template.
- Reuse `run_tasks` to run migrations too.
- Use `git describe --tags --always` to obtain template commit, to get a version parseable by PEP 440.
- Update `test_updatediff` to with new behaviors.

@Tecnativa TT20357
2020-02-21 13:52:35 +00:00
Jairo Llopis
fc6b364321
Reduce code complexity
As explained in #110, the dangling parameters for methods keep on complicating development.

A full code refactoring is too much work for now, but I did a little refactoring which consists in:

- Merge `Flags` into `ConfigData`, and remove anything related exclusively to flags.
- Any method that uses arguments from `ConfigData` gets instead a `conf: ConfigData` argument.
- `get_jinja_renderer()` removed; it's not useful as its little work can easily be done by `Renderer` itself.

This way, whenever we need a new config, we can just add it to `ConfigData` and use it more widely.

A full refactoring is still needed IMHO, where we have a main `Copier` class which handles its state and everything it needs (or it could be `CopierApp` instead), but that's more a design decision to be taken by the project leader.

@Tecnativa TT20357
2020-02-21 11:11:49 +00:00
Jairo Llopis
e5f96ec1d0
Merge pull request #111 from Tecnativa/update-only-git-diff
Updates respecting evolved git history
2020-01-27 11:24:01 +00:00
Jairo Llopis
1f2ce1ed25
Updates respecting evolved git history
Fix #88 the easiest way possible. Changes summary:

- A new `--vcs-ref` flag that indicates which commit/ref you want to copy, and only applies when the source directory is git-versioned.
- A new `--no-diff` flag to `copier update` skips the smartypants diff behavior.

What it does?

- Checks you are updating a git-versioned destination from a git-versioned source.
- Clones the destination into temp dir.
- Does a `copier copy -f tmp_src tmp_dst` (yes, a temp dir also).
- Gets the git diff between `tmp_dst` and `dst_path`.
- Performs a normal `copier update dst_path`.
- Applies the git diff at the end, to try to respect downstream project evolution.

@Tecnativa TT20357
2020-01-23 12:38:57 +00:00
Jairo Llopis
6dd69a957f
Support custom templates suffix
The `.tmpl` suffix doesn't seem to be a very widely adopted standard on the Jinja world. Others like `.jinja` or `.j2` usually have better IDE integration.

It's not like `.tmpl` is a wrong default, so here I'm leaving it as a default but letting template developers to change it to another one that fits better their environment.

Apart from this, if you really had to produce any `.tmpl` files in your copies, having files that ended with `.tmpl.tmpl` seemed a bit weird, while now you can change that suffix to whatever fits better your project.

@Tecnativa TT20357
2020-01-23 11:30:56 +00:00
Jairo Llopis
0a952b7680 Run pre-commit for the 1st time
OK, now this diff is very big, but it's actually modifying only style, not code functions themselves. From now on, this won't have to happen again.

Basically I just ran `pre-commit run --all-files` and committed that. I hope you like how it looks now!
2019-12-10 11:47:30 +00:00
Jairo Llopis
899f5d6a66
Basic support for automatic copy updates
This is a totally breaking PR. It had to come sooner or later...

Before this patch, copier had some ugly problems:

- If a file was called `--exclude`, you couldn't add it to `--extra-paths` due to using `nargs='*'` in an option. It is a weird thing that `ArgumentParser` allows to do, but can potentially lead to unfixable problems.
- Argument parsing was a little bit handycraft work.

Meet [Plumbum](https://plumbum.readthedocs.io/), the swiss army knife for CLI packages:

- CLI has been refactored as a plumbum application.
- Tests for CLI parsing removed, since they were incompatible and we are using a well-tested CLI parsing library now after all.
- The application now includes 2 subcommands: `copy` and `update`.
- If called without args, or with 1, it will use `update`.
- If called with 2 args, it will use `copy` (this preserves old usage unchanged, unless you are copying from a template called `copy` or `update`; in such corner case, just call it as `copier copy copy destination` instead).
- `copier --help` and `copier --help-all` are more useful now.

And you might be wondering... Adding such a big dependency just for that? Well, actually plumbum supports more than just CLI applications: supports sane execution of local & remote commands, sane output coloring, sane user prompting... Possibly it will make Copier go to the next level as we keep on using it more. Just take a look at its docs! You'll love it 😉

Of course, all that new CLI had to be reflected in API changes:

- `src_path` is now optional (`None` by default). In such case, copier will try to guess the `src_path` from the `.copier-answers.yml` file in the copy, or fail otherwise.
- `dst_path` is also now optional (`.` by default), meaning that without a `src_path`, you'll be trying to copy anything else to current `$PWD`.
- The builtin `_log` variable, which contains all necessary data for copy updates, now has also a `_src_path` key that points to the original source. This only happens when it was copied from a git repo or from an absolute path in the local disk, as relative paths are not easily reproducible in next updates (they depend on the user's CWD when running copier).
- A new `original_src_path` variable goes around, indicating the git repo or abs system path passed to `src_path` on the initial call. This is just to be stored in `_log` as explained.

```bash
copier gh:example/template destination
cd destination
echo my changes >> anywhere
git commit -m changing .
copier # Equals to `copier update .`
git commit -m 'copier update' .
```

🎉 You're updated!

This is an importan step to complete #88.

@Tecnativa TT20357
2019-12-05 13:51:55 +00:00