0

Most of the time I'm developing Joomla extensions. It happens often that one needs to reuse helper classes, installation classes etc. Up until now I've just copy pasted code around. I know, I know... but this is always the fastest solution, that in the long term turns out to be the slowest. I've been thinking now some time how to manage the dependency management in my projects. I've tested out composer and I like it, but it doesn't seem to be a good fit for me. Let me elaborate. Let us say we have the following folder structure

projects
- library A
- library B
- project A
- project B
- project C

Project A and B both use the library A and B, where project C uses only library A. If I were to use composer then the structure of the folder would look like this:

projects 
- library A
- library B
- project A
-- vendor
--- library A
--- library B
- project B
-- vendor
--- library A
--- library B
- project C
-- vendor
--- library A

I don't know - this would be maybe fine if I was using 3rd party libraries that I'm not developing myself, but if I already have the code of library A and library B on my hard drive - why the * will I copy them to the vendor folder? Not only that, but whenever I update my library, I need to do composer update in each project to get the latest library version. This seems kinda contra productive to me?

So what I came up with is -> symlinks. I can place a symlink to my library A and B and then whenever I make a change -> the change will be auto-applied to all of my projects.

Whenever I zip the extension my phing scripts will get the libraries and include them in the zip. So this seems to be good for my development workflow, but there is another issue. Some of my projects are available on github and other developers fork them, do whatever they like with them etc. Now I need to explain to them, that they should create the same directory structure as I have in order for the build scripts to function. They will download project A, but they will have to go and download library A and B.

This is where composer is great. But if I want to have it easy on my, I need to use symlinks... How do you manage such situation? What is your workflow and how do you structure your projects and libraries in order not to have to copy code all over the place and at the same time make it easy for other developers to get going in seconds? Any tips are welcome!

Daniel Dimitrov
  • 1,848
  • 21
  • 35
  • Dependency management or composer is based on per project basis. Every single project should contain it's own `composer.json` file and it manages it's own dependency, it makes sense, (AFAIK). – The Alpha Oct 31 '13 at 09:10
  • Each project will have it's own dependencies, some shared (i.e "Project A and B both use the library A and B"). Composer will determine the whole project's dependencies and create **one** vendor folder with them all in - Not duplicate them. – AlexP Oct 31 '13 at 09:10
  • composer will create a vendor folder with my dependencies. As I explained - in my case the issue is that I'm not relying on 3rd party libraries, but I'm relying on libraries that I develop and they are available on my PC. If I was somehow able to point composer to the original location of the libraries on my pc then this could be another story. – Daniel Dimitrov Oct 31 '13 at 09:25

3 Answers3

0

Seeing you've already set your mind on symlinks, and assuming all of these projects live on the same server, I'd propose the following;

A shared vendor dir

  • vendor A
    • current -> 0.3 ( symlink to your "stable" version that (all) projects share" )
    • 0.1
    • 0.2
    • 0.3
  • vendor B
    • current -> 0.0.2
    • 0.0.1
    • 0.0.2
    • 0.0.3-beta

So when you post a new update of one of your dependencies you can test these properly by switiching a projects version, if your satisfied applying it to all projects is a mere symlink switch

Vendor dir in Project A

  • vendorA -> /shared/vendorA/current
  • vendorB -> /shared/vendorB/current

Vendor dir in project B with different requirements

  • vendorA -> /shared/vendorA/0.1
  • vendorB -> /shared/vendorB/current

However I really love composer...

Depending on wether you will also want to be able to use external dependencies with composer, you might want to try something in this direction.

"autoload": { "psr-0": {"vendorA": "/shared/vendorA/current"} }
wtfzdotnet
  • 1,022
  • 8
  • 11
  • Hey could you elaborate a little more on your reply? You are suggesting I go for composer. Create my composer.json, do the composer install etc - which will create the vendors folder and will place the libraries in there. After that I'll go inside the vendor folder and symlink the libraries to my original location? Is this what you are suggesting? – Daniel Dimitrov Oct 31 '13 at 11:34
0

If you use Composer, and you develop "library A" and "library B" - do not think about the applications that might use them. When you change something in these libraries, it must work on it's own.

When you develop your "application A", do not think about "this feature is useful for application B as well". Think about "this feature belongs into library B". Put it there, and then update application A to make use of it.

You need not update application B at the same time, just because you released a newer version of a library.

Sven
  • 69,403
  • 10
  • 107
  • 109
0

Indeed, there is an open issue for this request https://github.com/composer/composer/issues/1299. Unfortunately there wasn't any progress during the last months.

mellors
  • 31
  • 3