80

We're considering creating our own common bundle for entity mapping and services for use within few separate apps. A bundle should be easy to modify, run, include and test. I know about Best Practices for Structuring Bundles, but I don't know what git strategy to use when it comes to development.

Should we create common bundle as a whole project and commit whole repository to our git server, or is it better to start source control only for root of common bundle and push only its contents? I see this approach in bundles available on github, but I don't know easy and comfortable way to develop bundles that way.

Darryl Hein
  • 142,451
  • 95
  • 218
  • 261
ex3v
  • 3,518
  • 4
  • 33
  • 55

3 Answers3

177

Create a new empty symfony project

php composer.phar create-project symfony/framework-standard-edition demo/ 2.4.1
cd demo

Generate a new bundle

(for example src/Company/DemoBundle)

php app/console generate:bundle
cd src/Company/DemoBundle/

Init your github repository in src/Company/DemoBundle

git init
touch README.md
git add .
git commit -m "initial commit"
git remote add origin https://github.com/YourAccount/DemoBundle.git
git push -u origin master

Add a composer.json file

src/Company/DemoBundle/composer.json:

{
    "name" : "company/demobundle",
    "description" : "A demo bundle",
    "type" : "symfony-bundle",
    "authors" : [{
        "name" : "demo",
        "email" : "demo@company.com"
    }],
    "keywords" : [
        "demo bundle"
    ],
    "license" : [
        "MIT"
    ],
    "require" : {
    },
    "autoload" : {
        "psr-0" : {
            "Company\\DemoBundle" : ""
        }
    },
    "target-dir" : "Company/DemoBundle",
    "repositories" : [{
    }],
    "extra" : {
    "branch-alias" : {
            "dev-master" : "some_version-dev"
        }
    }
}

Now you have the base structure of your bundle

Use it in another project

composer.json:

    [...]
    "require" : {
        [...]
        "company/demobundle" : "dev-master"
    },
    "repositories" : [{
        "type" : "vcs",
        "url" : "https://github.com/Company/DemoBundle.git"
    }],
    [...]

Do:

curl -sS https://getcomposer.org/installer | php
php composer.phar update company/demobundle

app/AppKernel:

new Company\DemoBundle\CompanyDemoBundle(),

Work on it

  • You can clone your DemoBundle in the src/Company folder, then manually install it
  • You can use symlink

Conclusion

You can develop and test your bundle in your first project and use it with github and composer in your second project.

Darryl Hein
  • 142,451
  • 95
  • 218
  • 261
Vincent Barrault
  • 2,906
  • 1
  • 19
  • 17
  • That's a good step-by-step, however I would suggest hosting on its own repositories as well as using Satis to service private dependencies: https://getcomposer.org/doc/articles/handling-private-packages-with-satis.md – Boris Guéry Feb 03 '14 at 12:03
  • sure, but maybe he has a private repository in github. – Vincent Barrault Feb 03 '14 at 12:47
  • Great answer @VBee! I did some research few days ago on the same topic but I was more interested in using private Git repos or local repos (preferred). – Jovan Perovic Feb 03 '14 at 13:13
  • @VBee Great tutorial, thanks! Private repo is not a problem - we have our own git server. The problem is that I don't really get how to develop common module in team using your solution. Does every developer has to create new `sf2` project and `clone` this repo into `src/` ? What about `composer.lock` for main project and using it to assure same version of every library across team? If you know good and effective way to do that, please, add it to your answer. Thanks! :) – ex3v Feb 03 '14 at 13:48
  • 3
    Just a typo composer.phat should be composer.phar – Stéphan Champagne Apr 26 '14 at 19:10
  • For anybody who's researching this topic, you could have a look at the boilerplate `LilaConceptsBestPracticeBundle` (https://github.com/LilaConcepts/LilaConceptsBestPracticeBundle). It'll give you a great starting point. – tftd Jul 02 '14 at 23:58
  • Mind that parameter `"target-dir" : "Company/DemoBundle"` uses forward-slash `/` when specifying target dir, and `"psr-0" :"Company\\DemoBundle" : ""}` uses escaped ` \\ ` backslash. – Dimitry K Nov 11 '14 at 12:48
  • how about making bundles like Sylius does? it has many bundles [READ-ONLY] and "replace" in composer.json, but how does this work… I don't understand yet – Serge Velikan Dec 09 '14 at 21:12
  • Now you can use `path` repository type, composer will create symlinks by itself https://getcomposer.org/doc/05-repositories.md#path – Sergey Kolodyazhnyy Nov 17 '15 at 22:14
  • How to add a vendor inside the Bundle? I want my bundle to be glue code to a custom library, hence I want to require a vendor library for it, yet am unsure where to require it. I think it should be inside the Bundle's composer.json. – k0pernikus Nov 25 '15 at 15:15
  • This should be part of the symfony documentation. Good job, thx – Wolf-Tech Nov 08 '16 at 08:37
  • You can create composer.json file with composer init command ( https://getcomposer.org/doc/03-cli.md#init ) – Emiliano Sangoi Apr 18 '17 at 17:26
  • You cannot use symlink as git does not accept files beyond symlinks – ReaperSoon Mar 29 '18 at 09:28
16

An important point to know is that you can commit into your repo from the /vendor. Indeed, composer creates a second remote called "composer" for each bundle (or package) that references the repo of the package, in order you can work on it in a working context. So the good practice is to register your package in your composer.json for all your projects and commit from your /vendor/MyCompany/MyBundle, from any project.

As a proof, just run git remote -v from any bundle in your vendor.

The bad practice would be to consider your bundle as a separate project and have symlinks with it. The main reason why this is the bad practice is that you won't be able to declare dependancies with your bundle. Moreover you'll have some difficulties with the deployment of your projects.

Darryl Hein
  • 142,451
  • 95
  • 218
  • 261
flouflou2000
  • 201
  • 2
  • 5
  • I am creating own vendor Bundle. I want put this bundle for example on GitHub and use it in other projects. I should generate new Bundle in `/src` or in `/vendor` directory at start? When i include this Bundle to other project it will be in `/vendor` but where i should genate them at start? – Exit196 Jan 24 '16 at 17:24
  • 5
    Create a new empty project in GitHub that will store your bundle. Commit a composer.json in it. You can even commit a very simple composer.json, with only the name and the description of your bundle. Back in your project, add a requirement to your new bundle and do a `composer update`. Now you should see your empty bundle in the vendor folder and you can work in it. If you want your bundle to be public, add it to Packagist. – flouflou2000 Jan 25 '16 at 18:50
4

In Symfony4, generate:bundle command is no longer available. Instead, you may follow this tutorial.

First create a project with:

composer create-project symfony/website-skeleton my-project

Then, create a my-project/lib/AcmeFooBundle/src directory. Here will live your bundle. The namespace for this directory will be Acme\AcmeFooBundle, so if you create a service class at lib/AcmeFooBundle/src/Service/Foo.php, its namespace would be Acme\AcmeFooBundle\Service.

Now we need to tell composer autoloader to look for new classes at that new directory, so we need to edit composer.json autoload section:

"autoload": {
    "psr-4": {
        "Acme\\AcmeFooBundle\\": "lib/AcmeFooBundle/src/",
    }
}, 

and run composer dump-autoload.

Now you only need to add your bundle class to config/bundles.php:

return [
    ...
    Acme\AcmeFooBundle\AcmeFooBundle::class => ['all' => true],
];

and dependency injection to load configuration from your bundle.

If you want to check your services before adding dependency injection, you can just autowire them at config/services.yml:

services:
    ...
    Acme\AcmeFooBundle\Services\Foo: ~

That's all. Follow best practices and go on coding.

PS: I've published a post with a few tips for developing Symfony reusable bundles.

Manolo
  • 24,020
  • 20
  • 85
  • 130
  • BTW, I also created a project for developing reusable bundles: https://github.com/msalsas/symfony-bundle-skeleton – Manolo May 12 '20 at 16:57