I've recently inherited a project build on a particular PHP framework, Asgard. The framework itself is less important.
The code is stored on GitHub and contains the framework files, some of them modified, and a few dependencies. Upon installation, one should run composer install, which will bring the rest of the dependencies.
Most of the custom code is in two folders, located in public_html/modules and in framework/Modules, respectively. However, there are some framework files that have been modified.
The code management/installation procedure seems illogical to me, and I would rather all of the framework code (the specified version of it) would be brought by composer and only the few files be applied on top, as a patch.
Is there some development workflow that would allow me to push to GitHub just the changes, not all of the framework files, and then somehow apply a patch over the framework code when composer install runs?
I'm aware that composer is configured via composer.json and composer.lock, I just don't know how to do the patch.
Also, I don't know how to push just the changes to Git, without including the initial framework files, while retaining full functionality in my working folder.
Any idea would be appreciated.
Thanks.
Related
I am reading/learning about Composer, the application-level package manager for PHP.
In this blog post written by lead dev Jordi Boggiano, he writes:
Composer on the other hand forces you to declare your project
dependencies in a one-stop location (composer.json at the root). You
just checkout the code, install dependencies, and they will sit in the
project directory, not disturbing anything else on the machine.
Another related feature is the composer.lock file that is generated
when you install or update dependencies. It stores the exact version
of every dependency that was used. If you commit it, anyone checking
out the project will be able to install exactly the same versions as
you did when you last updated that file, avoiding issues because of
minor incompatibilities or regressions in different versions of a
dependency.
If I understand Composer properly, when we're talking about packages downloaded/installed by Composer, we are talking about PHP code packages, ie, programming code written in PHP, and not system-level packages, eg, extensions to the PHP runtime installed on the server. So once these PHP code packages have been downloaded and added to a PHP project, I would have thought those packages become part of the PHP application source code, eg to be checked in to whichever version control system is being used for the project. If another developer comes along and checks out the code, why would they need to then "install the packages", as is stated in the blog post? Wouldn't they get a copy of all code packages when they check out the code from source control? This line in the blog post is confusing me, and making me think I don't understand Composer.
Any clarity on this would be greatly appreciated. Thanks.
The dependencies themselves should not be commited to source control. The composer.json and composer.lock files, on the other hand, should. There's various reasons for this, amongst them:
Every time you update the dependency you would have to commit the changes. That kind of tightly couples your code to the dependency, when it should be exactly the other way around.
The packages themselves are already in their own repository with their own history. Why repeat that in your project's history?
Those repositories can be huge, just muddling the waters around your project. Why carry around all that weight?
Instead, having each developer just run composer install (very important: not composer update) whenever they check out the project is much more efficient. Composer will install the dependencies from composer.lock, making sure everyone running the same commit is on the exact same page. The same goes for deploying.
You can read more about this here.
On the other hand, there might be situations where you have to commit your packages to get around a problem, like for example when you know you won't be able to run composer install on your production server (shared hosting)
Normally packages installed via composer don't get checked in to source control, only the code you write and the composer.json and composer.lock files.
This way the repository for your project does not get bloated with code you did not write and possibly don't really care that much about.
Yes its normal after cloning down your repository a developer will need to run the "composer install" command. The composer.lock file will ensure they get the same modules and versions of them you used when creating your project.
Not including the composer modules in your source control also allow you to easily update to the modules to get bug fixes and new features in new versions of them.
Let me just say this, I'm very new to composer and laravel.
I'm a long time cli fan, so I feel very comfy with composer. I've used npm, ruby gems etc, I see all the benefits to package managers.
Problem is, I'm saving entire laravel dir to my svn repository. It seems kinda redundant, especially vendor/bootstrap dirs.
I also find it uncomfortable to have vendor packages same in every laravel app directory on the same server, I'm kinda missing global gems thing from ruby.
How do you deal with this? Is it possible to have laravel like a shared library on server and then just have app/public directories in each project?
What files should be saved to repository? can composer handle all the dependency installation on production server? I see laravel files come with .gitignore files, where do I get svn version?
Much confusion atm in my head, hope to clear these up, so I can start actually writing code ^_^
First off, as far as I know, it is not easily possible to install laravel and it's dependencies globally. I wouldn't worry about that too much though since composer will cache them so it won't need to download everything for each project you set up.
Vendor directory
The vendor dir should definitely NOT be in your repository. I'm no SVN expert but according to this answer you can ignore directories by doing:
svn propset svn:ignore "vendor" .
Most SVN client software should have a similar function in a context menu or similar.
Deploy workflow
Ideally you checkout the repo on your production server and then run composer update to install all dependencies. If you don't have terminal access or have other troubles with that I recommend you download a fresh copy of your repo and run composer udpate. Then upload it to your server.
I am going to rewrite this question to be more clear. I have the following application structure:
applications/
api/
public/
composer.json
frontend/
public/
composer.json
backend/
public/
composer.json
common/
vendor/
... composer libraries here
How can I make that every single application's composer install gets installed into common/vendor, so that way I can have the most up to date version of the library in wherever is used with just one composer update; while at the same time only load the libraries that are in the composer.json file of each application. So, when I include vendor/autoload.php, only the needed libraries are loaded.
EDIT: Edited the whole question. Please reread
You have to create one bigger meta project that requires the API package, the frontend and the backend. You can define which directory should be used for placing dependencies for this meta project, and should be able to define for the special packages API, frontend and backend that they should go into their respective directories and not the common folder.
Updating that meta package will have to check more dependencies, but it is guaranteed that you either get the newest possible versions that conform to your version constraints (which may NOT install the newest version available if one of your packages requires a lower version). That way you would avoid installing dependencies that are not allowed for one of the projects, and you would be immediately notified if you attempt to install conflicting versions.
Note that I wouldn't recommend this at all. I would write a script, placing it at applications/updatecomposer.sh and add all the commands necessary to update each project individually. You gain all the flexibility that Composer is about, because essentially you want to have the central library installation of PEAR back. This central installation and the resulting inability to update any of the PEAR packages without risking to break something is one of the reasons that PEAR is considered dead.
Or think about any pre-Composer originating framework like Zend Framework 1. Having this installed in a central point that every application is using will effectively prevent you from ever updating it, if you are not prepared to also deal with incompatibilities in ALL your applications at the same time. Just an example: Updating from any ZF 1.11 to ZF 1.12 (the currently maintained up to date version) is a potentially backwards-incompatible change, because at least one abstract class (dealing with REST interfaces) got new abstract methods that have to be implemented.
I want to customize a module that I installed using composer, and it is now in /vendor. When I copy it in /module directory, it won't be recognized anymore. Here is the file /vendor/composer/autoload_classmap.php, that I added this into it:
return array(
'myModule\\Module' => $vendorDir . '/../module/myModule/Module.php',
);
and after that it was working. But the problem is that whenever I run php comnposer.phar install that file is overwritten and again I have to update that file.
It seems that I am doing it wrong. So, What's the correct way to copy a module from vendor directory to module directory without loosing the functionality?
Regards
Edit: I want to fork the package and edit that fork.
Technically you can change where composer installs things to by specifying a vendor-dir in your app's composer.json, see: https://getcomposer.org/doc/04-schema.md#config But this would affect all composer-installed packages, including (presumably) your installation of Zend Framework itself.
I would recommend you just leave the vendor folder as-is and let Composer do its thing.
Edit: Okay, if you want to fork a project, it's best to make changes outside of your app. Checkout a copy of your fork, make any changes you need and commit them. Then run composer update in your app to bring in the updated version.
If you need to test your changes in the app before committing them, that can be a bit fiddly. Personally I would either symlink to the checkout elsewhere on the file system (temporarily, just to get it working). Or edit the files in vendor just to figure out what changes you need to make, then apply those changes again to your separate forked project. There may be a better way though.
I think you have to ask this question before trying to solve this problem:
Why i need to move this directory to another place?
Editing / modifying / moving any file or directory which located under the vendor folder or incorporating them to your awesome application's module/library/whatever folder by copy & paste is not a good practice. Composer won't like that.
To customize a library code, create your own module (or library) folder and properly extend composer-installed 3rd party library classes which needs to provide more or different functionality.
We created a ZF2 project with skeleton app and it works fine for a simple test application. Now we are working on a real project. My question is what we should store in the repository (SVN), the whole project structure or just the new source code? ZF2 comes with a vendor directory which is almost 31MB in size (which has the ZF libraries). Should we store the whole vendor folder in SVN?
This is the first time we are using PHP and ZF so are not clear in how we will deliver the complete project to production from SVN. Also what is the build process if at all exists. Any clues/links to "ZF2 project packaging" is appreciated.
No, don't include dependencies in your repository! Putting your dependencies under version control doesn't do any good, it just blows up your repo for no reason.
You want to add the skeleton to your repository and your own library but definitely not the framework or any other dependencies.
The way to go is to use composer for dependency installation and some kind of build tool like Phing to automate installation of your project.
See the relevant chapter on phptherightway for more information on how to build your application.
The most simple build process doesn't even need a build tool
checkout your project from SVN/git
run php composer.phar install to install the needed dependencies (defined in your composer.json)
But most probably you want to do some more stuff like setup up the environment, deleting some files, etc.
A word about ZF packages. They're not available from packagist but you can install them with composer anyways. You just have to add the dedicated repository to your composer.json as described here: http://framework.zend.com/downloads/composer