4min.

Contributing to Symfony MakerBundle

Let’s be honest, I love Symfony MakerBundle, I know it may not be a popular tool among experienced developers that may prefer to build code from scratch but this brick of Symfony is a gem 💎.

One of the good things about the MakerBundle, is that it can show you the best practice, so if you always make your controllers a certain way (copy/pasting for example) maybe you should try a make:controller next time and start from a fresh template instead?

Let’s get back to my problem. Fact is, I’m not so good at remembering Doctrine ORM relations (OneToMany ; ManyToOne ; OneToOne and ManyToMany). In this case MakerBundle makes it extra easy with the make:entity command.

It will ask you about your relation and give you a text to help on that precise case.

Something like:

$ bin/console m:entity User

Will give you:

 Your entity already exists! So let's add some new fields!

 New property name (press <return> to stop adding fields):
 > ecommerce

 Field type (enter ? to see all types) [string]:
 > relation

 What class should this entity be related to?:
 > Order

What type of relationship is this?
 ------------ ------------------------------------------------------------------
  Type     	Description
 ------------ ------------------------------------------------------------------
  ManyToOne	Each User relates to (has) one Order.
           	Each Order can relate to (can have) many User objects.

  OneToMany	Each User can relate to (can have) many Order objects.
           	Each Order relates to (has) one User.

  ManyToMany   Each User can relate to (can have) many Order objects.
           	Each Order can also relate to (can also have) many User objects.

  OneToOne 	Each User relates to (has) exactly one Order.
           	Each Order also relates to (has) exactly one User.
 ------------ ------------------------------------------------------------------

 Relation type? [ManyToOne, OneToMany, ManyToMany, OneToOne]:
 >

I’m sold 💛

It only has a small problem when you use classes with similar names then the helper message does not help.

Let’s say you have an Order class in the App\Entity namespace and another type of Order in App\Entity\Logistic namespace.

Then the helper message will be something like:

...
  ManyToOne	Each Order relates to (has) one Order.
           	Each Order can relate to (can have) many Order objects.
...

Which is which?

Fortunately, JoliCode has an open source policy where you can ask to get time to work on open source package (in any way, be it code or anything else). And I wanted to give back to that tool that helped me so much!

Section intitulée contribution-processContribution Process

Contributing to MakerBundle is quite easy:

  • First, I checkout the MakerBundle code, read a bit how the package is made.
  • I see that MakerBundle is fully tested, so my best shot is to work on a test scenario and start from here.
  • I look for the testing part for the entity maker command and I added the updated output I wanted to have to the test.
  • Then, I browse the code until I find where the message asking for a relation is built, I add some conditionals and a bit of helper functions to get to a satisfying result.

It is fun to see how the MakerBundle is tested, because the MakerBundle generates code, then the test executes that generated code and even tests against it, that’s the beauty of it.

After a bit, I succeeded in implementing the new feature, I ran the test suite and checked that everything passes, including of course, code style and PHPStan. And in the end tests are green! 🎉

Section intitulée real-life-testingReal life testing

Let’s be extra careful and make a new Symfony project to test the MakerBundle in real conditions. Functional tests are great, but real life is full of surprises.

Symfony tooling is always a pleasure to work with: I can make a new Symfony project with symfony new maker-bundle-example, then I configure composer for this project to point to my own maker-bundle package:

"require": {
	"symfony/maker-bundle": "dev-main"
},
"repositories": [{
	"type": "vcs",
	"url": "/Users/jerome/tmp/maker-bundle"
}],

I make a new entity App\Entity\Order and App\Entity\Logical\Order then I add a relation between the two.

$ ./bin/console m:entity Order

Let’s see what the make:entity command outputs:

 Your entity already exists! So let's add some new fields!

 New property name (press <return> to stop adding fields):
 > orderLogistic

 Field type (enter ? to see all types) [string]:
 > relation

 What class should this entity be related to?:
 > Logistic\Order

What type of relationship is this?
 ------------ ----------------------------------------------------------------------------
  Type     	Description
 ------------ ----------------------------------------------------------------------------
  ManyToOne	Each Order relates to (has) one Logistic\Order.
           	Each Logistic\Order can relate to (can have) many Order objects.

  OneToMany	Each Order can relate to (can have) many Logistic\Order objects.
           	Each Logistic\Order relates to (has) one Order.

  ManyToMany   Each Order can relate to (can have) many Logistic\Order objects.
           	Each Logistic\Order can also relate to (can also have) many Order objects.

  OneToOne 	Each Order relates to (has) exactly one Logistic\Order.
           	Each Logistic\Order also relates to (has) exactly one Order.
 ------------ ----------------------------------------------------------------------------

 Relation type? [ManyToOne, OneToMany, ManyToMany, OneToOne]:
 >

It works, and it helps the developer to understand which entity is on each side of the relation.

In this blog post we saw that the MakerBundle is a tool that can help everybody, and also that contributing, even for details like this, is simple and important for the community.

Ryan, one of the main authors of MakerBundle, is facing a very big challenge and needs all of our help.
You can read more and help him.

Commentaires et discussions

Ces clients ont profité de notre expertise