copier-org / copier

Library and command-line utility for rendering projects templates.
https://readthedocs.org/projects/copier/
MIT License
1.92k stars 173 forks source link

Exclude on update #1725

Open msharp9 opened 1 month ago

msharp9 commented 1 month ago

Actual Situation

I have some files I want generated on copy, but then I want them to be ignored thereafter. I would like the files included on copy but excluded on update. I can do this now, with a regular copier copy then passing in exclude when running update, copier update -x files, but it's an extra hassle to type out all the files to exclude on the command line everytime I update.

Desired Situation

A user runs copier copy. Some template files are deleted, renamed, completely changed based on use case. User runs copier update and those files are ignored.

Proposed solution

If the copier.yml template included an _exclude_on_update option that would be ideal.

pawamoy commented 1 month ago

I suppose it's like _skip_if_exist, but more general (no condition on existence, just ignore on updates).

msharp9 commented 1 month ago

I suppose it's like _skip_if_exist, but more general (no condition on existence, just ignore on updates).

Yes, but also _skip_if_exist has other uses, like ignoring files when migrating a repo that already exists from another template like cookiecutter.

yajo commented 1 month ago

Skip if exists should work for you here. Even if the file exists from a previous cookiecutter template, the point is that you want to do nothing with the file if it exists. In practical terms, you declare that the template doesn't care about that file contents. Where those contents come from, or whether you're copying or updating shouldn't make a difference here.

If you really want that file from the template, then remove it before the first copy.

Please feel free to reopen if you still find a valid use case for the requirement. Thank you!

msharp9 commented 1 month ago

@yajo sorry, migrating from cookiecutter isn't my use case. I was just pointing out that _skip_if_exists does indeed work for that. My request is still the opposite of that use case. So I'm a bit confused, did you read the original request?

the point is that you want to do nothing with the file if it exists.

No, the point is I want to do nothing with the file after it was initially created, regardless if it exists.

git itself actually does this, so it's a good example. When you run git init it creates a hidden subdirectory .git in your repo. If you look under .git/hooks, you'll find a host of sample hooks, the most commonly used is probably pre-commit.sample. To actually use it, it isn't uncommon for a user to just rename it to pre-commit so git commit catches the hook. Some users might delete the samples all together since they "know better" and "it's a waste of space". Regardless, once the file has been generated, we don't ever want to touch it, regenerate it, or what have you. We want to exclude it regardless of if it exists. _skip_if_exists does not work here.

msharp9 commented 1 month ago

@yajo I can't reopen this. Should I submit another request?

yajo commented 1 month ago

Ah sorry, I thought you had that permission.

Quoting a solution from https://github.com/copier-org/copier/issues/1718#issuecomment-2282643624:

we could simply add a _copier_conf.operation variable that contains copy, recopy or update. Then you can use it to template _exclude and effectively "skip if updating".

I'll reopen here and close the other issue because this one is easier to follow IMHO.

msharp9 commented 1 month ago

Yes, that solution would also work. It is more flexible then what I suggested, I'm just not sure when someone would want to exclude on copy and not on update. I've also never personally had to use recopy. A single _exclude_on_update might be more straight forward for a user, and simpler to document.

yajo commented 1 month ago

Hi folks. Now that https://github.com/copier-org/copier/pull/1719 is merged, do you still see a use case for this issue?

lkubb commented 1 month ago

Yes. This feature enables two behaviors:

  1. Files can be deleted once and then never be regenerated again (possible now)
  2. Files can be kept in a modified form without causing merge conflicts on update (still not possible)

Both are required for generate-once dumb boilerplate to work as intended.

msharp9 commented 4 weeks ago

Hi folks. Now that #1719 is merged, do you still see a use case for this issue?

Actually, I only see issues now with that merged. How do I force a file to be regenerated? What if a user accidently deletes a crucial config file?

Here's a common scenario. My template uses tool A. Tool A has a config file to customize feature A. Feature A is optional, so user deletes config file. Tool A upgrades to include feature B. Feature B is critical for future scope of template. I update config file to use feature B. But now because the user deleted the config file, they don't get the updates on update and their repo is now broken and they don't why. They now have to recopy which adds a lot of pain.

Do we now need a feature to ensure we always regenerate all the files when we make an update? This all seems silly. The previous behavior was correct. The files should exist or not based purely on the template, not the actions of the end user.