yohang / Finite

A Simple PHP Finite State Machine
http://yohan.giarel.li/Finite
MIT License
1.31k stars 187 forks source link

Split standalone component and Symfony bundle #43

Closed jjsaunier closed 10 years ago

jjsaunier commented 10 years ago

First, really nice project, i love it !

Is it possible to split Finite as standalone component without the symfony stack inside ? and add the symfony bundle on top ?

Currently on non symfony project (like silex or cilex) it's a bit frustrating to see a bundle folder appear :D

Is it plan ?

yohang commented 10 years ago

Hi,

Sorry, but it's not planned at all.

The best solution I can propose you, is to right-click on the Bundle folder in your editor, and click something like "exclude this directory".

More seriously, having the bundle inside the library simplify a lot the development process of Finite, so we'll keep the it inside.

However, a solution could be to create read-only subtree splits.

jjsaunier commented 10 years ago

However, a solution could be to create read-only subtree splits.

No, subtree splits is only good when you have project where there are a lot of components and you would extract it because they can be used in other project (because they are isolated blabla) like symfony component, sylius component, and beside this, they create a glue bundle who joined all components. In your case you only have one.

Your component must be abstract of dependency injection system, that will be built on top. You can't support N dependency injection modules (currently symfony-deps, and pimple), that means other projects who do not use these system, will have to add there own dependency system beside these. In this way you can leave the choice to create different library among version of your component and the dependency injection, and let people create their own bridge.

I don't know why you say it's more harder to develop the stand alone component and the symfony version, it's the same. The other problematic, how you will manage symfony version and pimple version when a BC will come ? You will create N branch to support symfony compatibility and backport all modification of above branches (and for the entire component, no only symfony2 parts) ? Just make a symfony 2 Bundle who is synced with symfony, When symfony up to the next version, your version also and each branch can only support once version of symfony2.

I have fork the project to adapt it in this way, think about it because it's very important if you want that your project is reused, some developper will reject to use your project because all layers are mixed and the sustain will be more harder each version.

If you want more explaination or help or any quesition, send a me email (given on my profile) and i will send you my skype to discuss about that and i'm also French (that can be more easy to communicate). If you prefer IRC, i can also.

Taluu commented 10 years ago

I agree with @ProPheT777 here ; the bundle (and also pimple integration) and Finite lib are in themselves different projets... So you should not mix them up.

What if someone using Zend needs the lib ? He has to download the bundle for nothing.

Even if it can be bothersome to develop a bundle, a provider, and a lib in parallel, it is still the best way to clear potential messes. Look at Imagine for example, as there is two projects (a bundle and the lib)

matteosister commented 10 years ago

I tend to prefer the bundle inside the lib...especially when the bundle (as it should be) is a small layer over the library. I use symfony, but if there was a zend module, I would have simply ignored it.

jjsaunier commented 10 years ago

Well, i have made one part, symfony2 stand alone is now available https://github.com/ProPheT777/FiniteBundle.

I have clear the composer, and the Finite composer must be rework he is really bad. I have also remove some elements in .gitignore, you must ignore in the global config of git not inside the .gitignore of your project.

Avoid ">=2.3,<3.0" use ~2.3 is more readable and avoid fail typo :)

You required "php": ">=5.3.0" but your unit test run from 5.3.3, add build matrix 5.3.0 or update your php require to >=5.3.3

You dont need to config bin-dir

    "config": {
        "bin-dir":"bin"
    }

I have also change the structure (BC BREAK ? I dont think) like :

capture du 2014-05-09 20 08 05

and test are OK (Test provided by @winzou)

capture du 2014-05-09 20 10 34

If you are interested by this bundle, take and clone it to your account (dont fork) i will not register him anywhere and delete him after you move it to your account. Otherwise, i would keep.

@winzou i know you contribute for the symfony part, if you can review the bundle (and other interested also), I would appreciate.

jjsaunier commented 10 years ago

@matteosister

I would have simply ignored it.

Ignoring dead / zombie code on big project is not acceptable.

is a small layer over the library

Today he is small, because Finite is young, and as i know Sylius is interested by this component and need lot PR to increase it. I'm agree today the symfony part is small, but he will grow, and cut cleanly causes of big BC breaks.

The most problem is to test the component, you must checkout symfony to pass the test, really annoying for CI

matteosister commented 10 years ago

@ProPheT777 I work daily on a giant project, and the vendor folder is full of code I don't use at all. For example in symfony I've got the translation files for every language in the world...but it's not a problem at all.

the bundle should stay small, all the business logic should be in the library...especially for a library like this one that expose a functionality, and it's not bound to anything which is not symfony/zend/whatever related.

decoupling for the sake of decoupling just add a useless layer of complexity.

jjsaunier commented 10 years ago

TL;DR Should not either applied the principles of KISS in the extreme. IMHO a separate logic for bundle is needed, and pimple should present only in the documentation with a use case and an example with the implementation code.

@matteosister The fact is translation component code is not dead, he is unused, at any time, you just have to config the config.yml and update the FrameworkBundle configuration to activate it and you can use the translation component. On the other hand this is not because symfony provides a standard-edition full stack that you must use as they have designed. Symfony is super flexible, it would be annoying not to enjoy ... Just make your own symfony-edition with custom FrameworkBundle and synced the version of your fork with symfony (And with git + contribution policy of symfony it's easy to maintain). But I can understand that it is much easier to do it by the way, but sometimes easy way are not the optimal solution, but it's not the discussion.

The difference here, the Bundle or pimple (and so both DI) will be never used according to the attached project. And like i said, support many DI in the same logic of component is not a good way, a dedicated package must be build on top of component to make the adaptation.

all the business logic should be in the library...especially for a library.

The business logic must be the library. Take a look at Atlantic18/DoctrineExtensions for example, they have 0 line of code for symfony, and a very little bundle is on top stof/StofDoctrineExtensionsBundle

decoupling for the sake of decoupling add a useless layer of complexity.

Where is the complexity ? Complexity is reduced instead. Test are easy and no need all dependencies (Which may have no relation to the current project) from N component to support N framework or DI or take the way to skip some test ... And the API is exactly the same, in developper POV no difference.

The component code is clean and business are isolated. A component dedicated for the kernel business and a Bundle for Symfony. The day when a Zend developer will want this lib, he just had to build his lib on top of Finite like the symfony bundle and it's all.

For pimple just a doc with integration example is adequate (no need to create a dedicated repo) IMO.

jjsaunier commented 10 years ago

@matteosister, starting your principle, that we keep all this logic inside the library how you versioned the library ? Knowing composer is based on version to resolve dependencies and keep compatible from now and all next of Symfony and Pimple, and may be other like Zend

I think with this, you will find the real complexity.

aaronmu commented 10 years ago

I'm all for separating bundle from library. I can image that Integrating this library into a framework that is not Symfony2 feels a bit "meh" right now.

yohang commented 10 years ago

Hi,

Even if I can understand that having a "Bundle" namespace in your ZF/Silex/Laravel/whatever project feels weird, the bundle is built on top of Finite, and is just an integration layer for Finite. No logic, just some glue between the framework and the library.

There is no particular dependencies problems, as symfony is just a dev dependency, so installing Finite in your ZF project won't install any useless Sf component.

About library versioning related to frameworks versioning, splitting the bundle isn't a solution. How will you manage a bundle that have to support Finite 1.x and an eventual 2.x (wich will exists someday, as i don't want any BC break in 1.x), and various versions of Symfony ? This will result in an even more complicated versioning issue.

An other, less important, point, is that keeping the bundle inside simplify bug and BC break tracking, as the Bundle test suite is runned on Travis on each Finite change. Splitting the bundle implies to manually update the Bundle an run the test suite on each change.

Moreover, it simplifies the development process by grouping library and bundle changes in the same pull request.

The Bundle is nothing more than an adapter, as there is the case in many other libraries. When you are using Imagine, there is support for GD, Imagick and GMagick, you have 2 unused adapters. Is it dead code ? Same thing goes for all web frameworks, how many various adapters did they includes ?

yohang commented 10 years ago

@ProPheT777 You're right about version constraints in compser.json , i'll update to ~x.y.

jjsaunier commented 10 years ago

About library versioning related to frameworks versioning, splitting the bundle isn't a solution. How will you manage a bundle that have to support Finite 1.x and an eventual 2.x (wich will exists someday, as i don't want any BC break in 1.x), and various versions of Symfony ? This will result in an even more complicated versioning issue.

How will you version to support many version of framework ??

yohang commented 10 years ago

It will depend of the context.

For Symfony, it won't be a problem until 3.0 release. If 3.0 requires lot of changes, then we'll maybe introduce a new bundle. Inside or outside Finite code, I don't know.

For Silex, as it the code is usually a single class, there will be 2 services providers inside Finite.

One more time, I really understand why you want to split the bundle, but then, must we split all library/framework integration layers ? Must we extract twig extension ? Sf DI factory ? Pimple Factory ? It will introduce unwanted complexity for end user.

jjsaunier commented 10 years ago

I dont know if we must split all part in one time. Pimple is not big, and new version come slower so ...

Twig extension can stay, even if we should not impose as rendering system and simply let the API to connect any renderer, cutting is simple and I think for the moment it is not annoying.

I'm just scared if you support many framework inside your library because each new version release of framework can may forced you to make a release and up version to support it, and at this time, the versionning of your library will have no meaning, and be really harder for end user to retrieve the compatible version.

yohang commented 10 years ago

In, at any time, we'll be forced to create a specific versionning to support frameworks, then we'll split.

But I think we won't have to, as BC support in common frameworks becomes really good.

jjsaunier commented 10 years ago

Ok, can i maintain the current FiniteBundle i did ? Even if nobody use it i really need to use a seperate bundle to prevent issue in some project for the long term support. So i will backport all modification on.

yohang commented 10 years ago

You can, but I won't break compatibility with currently supported frameworks. Or if I do, that's a bug, and it'll be fixed.