Symfony2 - creating own vendor bundle - project and git strategy

34,046

Solution 1

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" : "[email protected]"
    }],
    "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.

Solution 2

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.

Solution 3

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.

Share:
34,046

Related videos on Youtube

ex3v
Author by

ex3v

SOreadytohelp #SOreadytohelp

Updated on July 05, 2022

Comments

  • ex3v
    ex3v almost 2 years

    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.

  • Boris Guéry
    Boris Guéry about 10 years
    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: getcomposer.org/doc/articles/…
  • Vincent Barrault
    Vincent Barrault about 10 years
    sure, but maybe he has a private repository in github.
  • Jovan Perovic
    Jovan Perovic about 10 years
    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).
  • ex3v
    ex3v about 10 years
    @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! :)
  • Stéphan Champagne
    Stéphan Champagne about 10 years
    Just a typo composer.phat should be composer.phar
  • tftd
    tftd almost 10 years
    For anybody who's researching this topic, you could have a look at the boilerplate LilaConceptsBestPracticeBundle (github.com/LilaConcepts/LilaConceptsBestPracticeBundle). It'll give you a great starting point.
  • Dimitry K
    Dimitry K over 9 years
    Mind that parameter "target-dir" : "Company/DemoBundle" uses forward-slash / when specifying target dir, and "psr-0" :"Company\\DemoBundle" : ""} uses escaped ` \\ ` backslash.
  • Serge Velikan
    Serge Velikan over 9 years
    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
  • Sergey Kolodyazhnyy
    Sergey Kolodyazhnyy over 8 years
    Now you can use path repository type, composer will create symlinks by itself getcomposer.org/doc/05-repositories.md#path
  • k0pernikus
    k0pernikus over 8 years
    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.
  • Exit196
    Exit196 over 8 years
    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?
  • flouflou2000
    flouflou2000 over 8 years
    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.
  • Sandor Farkas
    Sandor Farkas over 7 years
    This should be part of the symfony documentation. Good job, thx
  • Emiliano Sangoi
    Emiliano Sangoi about 7 years
    You can create composer.json file with composer init command ( getcomposer.org/doc/03-cli.md#init )
  • ReaperSoon
    ReaperSoon about 6 years
    You cannot use symlink as git does not accept files beyond symlinks
  • Manolo
    Manolo almost 4 years
    BTW, I also created a project for developing reusable bundles: github.com/msalsas/symfony-bundle-skeleton