New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to update a project with changes from its cookiecutter? #784
Comments
Hi @aroig! 👋 Thank you for opening this issue. Sorry for the late response, we are currently very short on time. 😢 Can you please provide a link to such this |
There is something you may want to have a look at. Cookiecutter already dumps the used context as a JSON file. It's overwritten though if you use the same template again. You could have a See dump context. |
@hackebrot Thanks for the feedback! I submitted a PR with what I meant in #791. It didn't occur to me to use a |
I'd like to chime in with a solution I came up with:
|
@gnestor I'm doing quiet the same excepted that (such as @aroig ) I'm using Git to applu the upgrade in a separate branch and then a merge. Furthermore I implemented the following option: "strip directory" #894. When option is given it apply the template directly on |
@gnestor I know you can re-render your project on top of the working directory. The problem with this approach is that this is useless once your project modifies any of the rendered files, as they will be overwritten by cookiecutter, and would need manual intervention. The point of my original post was using git to handle this situation via merges from the template branch. I can add a lot of content to a rendered file, and as long as the lines touched in the project, do not overlap with the lines touched in a cookiecutter update, the merges are clean (no manual intervention). That was quite an improvement! Oh, by the way, a quick update of the situation to anyone interested:
I'm not sure what would be the best way to integrate this git boilerplate with cookiecutter though, and I haven't had time to think about it. If anyone is interested in the scripts I use for that, can take a look at aroig/cookiecutter-latex-paper for instance. Look at the end of the Makefile and cookiecutter-update.py |
@aroig I'm building a HTTP API which is using Git to manage directory content and Cookiecutter to template it. I'm doing quiet the same than your ContextMy HTTP API is managing a bunch of "projects" which contains various content. Each project is a Git repository. Each time you're doing an API call, it will do some magic and commit all changes made. Projects are really similar. Thus I'm using Cookiecutter to make some project templating. TemplatingAll changes made by the API are done in Template install
Template upgradeFor an upgrade of the template, the API will do the following:
Template detectionAs you understood, I'm using Git features (branch and note) to detect if a template is already installed (branch) or to know which one and from where (note). Illustration
If you have any advice, idea or whatever about Git/Cookiecutter workflow be my guest ! |
@rmedaer That sounds cool! and the git boilerplate, quite similar to what I do. A couple of comments: I'm even more convinced now that having this git boilerplate in cookiecutter as a low level thing, might be a good idea. Maybe something like a Doing an update without a template branch is not useful, because cookiecutter has no way to know whether the files have been modified in the project or not. Then maybe a I do not have time right now to do it, but if cookiecutter devs would consider something like it, I may put it in my mid-term TODO list. Oh, and that git note thing is interesting, it had not ocurred to me. But I imagine you cannot do that entirely in cookiecutter, your API that knows the cookiecutter repo url may do that, isn't it? It would be nice if it could be done, for instance from a cookiecutter hook, but then I think we are back to injecting the url into the context... |
@aroig I agree with you ! And btw, now I'm reading myself xor your comments, here some additional idea/comment... Assuming we are implementing update feature exclusively with Git, why should we dump the context in Then the upgrade procedure would be:
|
I would suggest the following arguments:
Otherwise we could also implement a wrapper around cookiecutter like I'm doing in my API. It's effortless for Cookiecutter developers and maybe more "flexible"... |
After thinking a bit more about it, I'm not sure I like sticking stuff in git notes. I think I prefer having it in files within the repo. But that might just be a personal bias. Anyway, there are pros and cons: sticking it in the repo, implies that other people cloning it may be able to use cookiecutter with it (assuming the template url is public). On the othe hand, the git notes thing may enable you to use a private cookiecutter template without letting everyone know. I think I would like to find a minimal set of changes to cookiecutter that enable those workflows, are as generic as possible, and leave the specifics of the workflow to cookiecutter hooks. For example, I think that the following
would be enough to let us implement our particular workflow via hooks. It has the advantage it does not commit cookiecutter to a particular way of doing things, plus those two features may be of independent interest to other people. But I'm not really sure... |
The goal of this commit is to define in code what has been discussed in cookiecutter/cookiecutter#784.
Well as you an see in Github references, I made a small POC. I don't want to start developing a lot of crappy stuff in Cookiecutter, so I created the following project: milhoja. I saw you're coming from Spain and I like cooking with cookiecutter, so I called that Milhoja. ;-) In the CLI module you'll find the options I identified. In "main" module I already wrote procedures I described. |
@aroig To answer your comment, even we are dumping context in a Git Note, you still be able to dump it in |
So is there a way to update a cookiecutter project then? |
fwiw, i recall doing similar things (though not as complex) without using a So it's basically:
This has worked fine for me. It's non-destructive, and walking through patchsets seem to be as easy as resolving merge conflicts from an actual branch. The one downside would be file deletions, which need to be done manually. |
If you want your private cookiecutter, just add |
Would have a need for this also. What's needed for this to move forward? Any opposition from the cookiecutter maintainers for integrating a solution to this into cookiecutter itself? Because at the moment, many people seem to be reinventing that wheel. Assuming there's no opposition to the idea of adding this feature, do we still need to discuss the approach to take here, or would we be at the stage where a pull request would be the best way to move this forward? Thanks! (One implementation of this feature is here: https://github.com/senseyeio/cupper) |
Hello, PR: #1173 |
Hey, just wanted to leave two links which might be interesting in this context: Both projects are used in the Puppet universe to repeatedly update standardized files in all lot of Puppet module repositories while still allowing some customization of those files. If think this come close to what we're looking for in cookiecutter. |
Does anyone have a suggested workflow to handle git delete/ git mv events for merging template updates into previously applied templates using git merges as suggested by this issue? |
Just use copier. |
https://github.com/timothycrosley/cruft/ has recently been updated to provide more robust cookiecutter updates. It is a 100% compatible with existing cookiecutters and is a thin layer over the cookiecutter api to provide support for updating. Out of all the options I have tried, I have found it to work the best. Disclaimer - I maintain this project so I am biased towards it. |
While risking to upset quite a few people, I think is better to close this ticket because is likely that will never happen, mostly because code generators will never be able to fully update code that was likely modified. It is more likely to have AI writing production that seeing it done. |
Err, nobody's asking for a magic, do-what-I-mean solution. This is a three-way merge. You do the merges you can, and then flag the conflicts for human review. This general concept is already implemented in multiple other places, including Debian for config files in /etc, and more specifically here, other projects built on top of cookiecutter (like cruft: https://github.com/timothycrosley/cruft/). It's fine for the project to decide this is out of scope. But it's clearly possible, because this problem is being solved elsewhere. |
This is my workaround.
You now can also track conflicts. |
Alternatively just use cruft https://cruft.github.io/cruft/ |
Applies a cookiecutter template to an existing repo. Thanks to [1] for the solution. [1] cookiecutter/cookiecutter#784 (comment)
hi, For this, i would propose, that
|
Hi,
I maintain several personal cookiecutters, and I found that I spend a lot of time keeping projects in sync with updates on the cookiecutter.
I started trying a workflow to deal with this, as follows:
template
, that contains the result of cookiecutter rendering, without any other changes..cookiecutter.json
at the root of the project containing the original context used to render that project, in json format.Makefile
containing at least anupdate-template
target. This make target does the following:git worktree
) of thetemplate
branch..cookiecutter.json
to regenerate the project on top of the temporary checkout, overriding previous content.This way, the
template
branch tracks the changes from the cookiecutter, and I can use git-merges into master to update the current project.The key thing is that by using git merges, I can update template files that got havily modified in the project. Most of the time the merge is clean, but from time to time a conflict will arise, which is easily resolved.
I've used it for a while and works pretty well. There are at least a couple of pain points though, that could benefit from changes in cookiecutter upstream, which may be of independent interest.
The template I use to generate a
.cookiecutter.json
is a bit hacky. I'd like to do something like this:Would you accept distributing this
jsonify
as a default extension? I can provide the code in an other PR.In order to get updates from the cookiecutter, the project stores its url in a
_template
field on its context. Right now, I hard-code this url in the cookiecutter itself. I would love to free my cookiecutters from hard-coding their url, That could be achieved if cookiecutter itself would inject a_template
field into the context with the url used at the time of rendering. I submitted Include template directory or url in the context dictionary #774 to that effect.Additionally, maybe a functionality like the update-template I described above could be moved into cookiecutter upstream. That would require some thinking, I guess...
Of course, any suggestions, or other ways in which a workflow like this could be better supported by cookiecutter would be very welcome!
The text was updated successfully, but these errors were encountered: