bake icon indicating copy to clipboard operation
bake copied to clipboard

RFC [Question / Feature]: non-destructive bake all

Open geoidesic opened this issue 4 years ago • 7 comments

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?

  1. It facilitates easy schema changes
  2. 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.
  3. It also avoids errors; you know that you'll never overwrite something with bake that you shouldn't have.
  4. Makes the separation between boilerplate and custom code crystal clear, which improves maintenance.
  5. Facilitates maintenance as you can change boilerplate and re-bake without destroying custom code.
  6. 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

  1. Baked Tables get written to Models/Table/Baked. These are overwritten each bake.
  2. 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.
  3. Models/Table just gets classes that glue the two together. These are overwritten. E.g.
include APP . 'Model/Table/Extension/DocumentsTable.php';

Controllers

  1. Baked Controllers get written to Controller/Baked. These are overwritten each bake.
  2. 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 main Controller folder. Thus the bake method should be generic here, something like bakeFolder and then in the bake method one iterates over an extensions array which defines the folder and template to be passed to bakeFolder as arguments.

Entity Unchanged

Templates

  1. Baked templates get written to the Templates/Baked folder. Overwrite on re-bake.
  2. 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.

geoidesic avatar Mar 06 '20 12:03 geoidesic

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.

markstory avatar Mar 06 '20 21:03 markstory

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.

geoidesic avatar Jan 13 '21 14:01 geoidesic

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.

dereuromark avatar Jan 13 '21 14:01 dereuromark

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.

GrandFelix avatar Jan 15 '21 09:01 GrandFelix

@geoidesic @markstory @dereuromark here is my implementation https://github.com/GrandFelix/bake/commit/de7a807b4459a55186c2096be43deb272519bd6c

GrandFelix avatar Jan 21 '21 16:01 GrandFelix

Can you make a PR against this repo? That would be easier to collaborate or give feedback.

dereuromark avatar Jan 21 '21 16:01 dereuromark

~~https://github.com/cakephp/bake/pull/733~~ https://github.com/cakephp/bake/pull/793

GrandFelix avatar Jan 21 '21 17:01 GrandFelix

Support for updating table and entity classes will be in bake 2.8.

othercorey avatar Sep 09 '22 01:09 othercorey