bake
bake copied to clipboard
RFC [Question / Feature]: non-destructive bake all
So the docs on bake are a bit sketchy. It seems to me that bake is designed to be used once then discarded – generally the approach for scaffolding. I personally don't like that idea. I prefer to use bake as an ongoing tool during development.
Why?
- It facilitates easy schema changes
- I don't want to have to get clever and specific on the command line with bake because it slows me down, so I want to be able to run
bake all --everything -t MyTheme
and have it all just work. - It also avoids errors; you know that you'll never overwrite something with bake that you shouldn't have.
- Makes the separation between boilerplate and custom code crystal clear, which improves maintenance.
- Facilitates maintenance as you can change boilerplate and re-bake without destroying custom code.
- DRY
How? To achieve this I think the way that bake outputs should be configurable through overrides or config rather than (or in addition to) via shell arguments.
The architecture I like has the following changes:
Models
- Baked Tables get written to
Models/Table/Baked
. These are overwritten each bake. - Extensions to these (which is where you put your custom code), go into
Models/Table/Extension
. Any that are missing are added during bake, no overwriting. -
Models/Table
just gets classes that glue the two together. These are overwritten. E.g.
include APP . 'Model/Table/Extension/DocumentsTable.php';
Controllers
- Baked Controllers get written to
Controller/Baked
. These are overwritten each bake. -
Controller/<Route>
can be configured to add any that are missing (e.g. for tables added newly to the schema). Can configure to add for multiple routes. Newly added are just empty classes extending the bake. This is where you put any custom code. Same applies for mainController
folder. Thus the bake method should be generic here, something likebakeFolder
and then in the bake method one iterates over anextensions
array which defines the folder and template to be passed to bakeFolder as arguments.
Entity Unchanged
Templates
- Baked templates get written to the
Templates/Baked
folder. Overwrite on re-bake. - Extensions get written to the
Templates/Extensions
folder. Only write if missing. The extensions would simply include the corresponding bake by default e.g.
<?php
include str_replace('Extension', 'Baked', __FILE__);
?>
Let me know if I'm missing something fundamental about bake's philosophy but in my books this is a far more useful arrangement than bake as it currently stands.
If there's general consensus about this I'll submit a BC PR with these changes.
It seems to me that bake is designed to be used once then discarded – generally the approach for scaffolding.
Yes, it is intended to make getting started quicker and generating starter code for your applications/plugins as they grow.
Having multiple directories with baked and customized code adds complexity to an application as all basic operations now involve inheritance and logic spread across multiple files/classes. I think you'll find that it doesn't actually end up saving you a ton of time/maintenance energy in your controllers as you'll still need to update your customized code if you're dramatically changing your schema.
On the contrary :D I find it saves me a huge amount of time and trouble.
I don't have to update my custom controllers at all for basic fields and associations as that is all handled by bake.
I have a short list of customised controller extensions, which cuts out a lot of noise, as I can quickly find the heavy machinery
, which only need updating if I'm changing something like a non-standard association, which bake wouldn't handle anyway.
I also have custom bake which handles all the inheritance logic for me and creates the necessary files where required. So basic operations are even easier.
I know @GrandFelix has also done something very similar.
Certain defaults through configure are now included: https://github.com/cakephp/bake/pull/365 Maybe a few more can help to remove the need for too much CLI typing for always the same args.
My approach to this is that when I pass some flag to bake I generate additional class which is generated only once. When flag is passed it creates for example UsersPersistentTable and main class is like
class UsersTable extends UsersPersistentTable {}
so basically generated class is still main class which extends persistent class. Also every bake run is aware of already generated persistent class so the main class is every time correctly extended. If there would be need to override initialize code or validationDefault etc. I could change template which would call parent::func() at the end of every mentioned function. But I did not need to do this until now. My only need was when adding custom functions to tables class and when development is in main stage and you add some custom functions then add new filed or rename it in db, everything is overwritten, but it doesn't have to be that way :)
For now I only extend Tables, I don't see any need to extend controllers for now.
If there is any interest I can share this.
@geoidesic @markstory @dereuromark here is my implementation https://github.com/GrandFelix/bake/commit/de7a807b4459a55186c2096be43deb272519bd6c
Can you make a PR against this repo? That would be easier to collaborate or give feedback.
~~https://github.com/cakephp/bake/pull/733~~ https://github.com/cakephp/bake/pull/793
Support for updating table and entity classes will be in bake 2.8.