I am working on a php project and relying on composer for installing dependencies which is working fine in my case but when I try to commit the files things get tricky.
A simplified view of my composer.json is as follows.
"require": {
"apache/log4php": "2.3.0",
"asojon/mysql-pdo-wrapper": "dev-master"
},
"autoload":{
"psr-0":{
"": ""
}
}
When I ran composer install it created 3 folders namely composer,apache and asojon and autoload.php file under vendor folder.Then I went ahead and comited the vendor folder and now when I clone my project repo all the files under vendor/apache and vendor/asojon are empty. Am i missing something here ?
You should not commit you vendor folder but only your composer json, it is why composer exist.
Every time you git clone your repo, you should run composer install.
Related
I want to add repositories in my composer.json where the source depends on the application environment. For example, if I am in local environment, I want to include repositories from a local file path and if it is in production, then I want to include from GIT.
In local:
"repositories": [
{
"type": "path",
"url": "../local-path"
},
]
In production:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/...."
},
]
In my .env file is an APP_ENV variable. Are there any possibilities to achive this?
I think this isn't a great idea because you have a risk of potentially committing your composer.lock file from the wrong environment and deploying it. Hopefully you have stricter deployment checks in place though!
I don't have an exact solution, but some options instead:
Use a Composer config file locally
No need for separate composer file
Might get finicky about versions (I've had trouble getting composer to symlink before)
Should allow you to only maintain one composer.json and only touch the config file when you add new local repos
Documentation
In this example I created a project with a simple composer.json.
{
"name": "mickadoo/test",
"type": "project",
"require": {
"mickadoo/basedata": "dev-master"
}
}
I added a single requirement which is a package I put on packagist myself years ago.
I then created a dummy library to test it locally with the same name. It was in a library directory which contained only a composer.json file. The goal is to check if composer will install this empty library (no requirements) instead of the online one.
{
"name": "mickadoo/basedata",
"type": "library",
"require": {}
}
I then added a config.json file to the project root with configuration telling composer to add a local repo one directory up:
{
"repositories": [
{
"type": "path",
"url": "../library"
}
]
}
After all that I tried first running composer update and setting the COMPOSER_HOME env variable to my current directory. This ensures that composer will pick up the config.json and merge it into the configuration it's using.
$ COMPOSER_HOME=$PWD composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing mickadoo/basedata (dev-master): Symlinking from ../library
Writing lock file
Generating autoload files
I then deleted everything I did because I've messed around with local paths in composer before and know it can be frustrating to get working:
$ rm -rf vendor/ && rm composer.lock
Finally I tried just running composer update as normal, hoping it would skip the config.json and just pull the package from Github.
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 14 installs, 0 updates, 0 removals
- Installing symfony/polyfill-apcu (v1.13.1): Downloading (100%)
- Installing psr/log (1.1.2): Downloading (100%)
... more package installs from Github here....
Writing lock file
Generating autoload files
Which it did!
Use a separate composer.json
Keeps things pretty visible
Separate composer.lock file
Documentation
This would mean maintaining two separate files, like composer.local.json and composer.json. It might be tedious, but at least it's clear what's going on. Based on your COMPOSER env variable you can change which filename it's using
I see here a couple of options.
Use a local path to a repository. Then on the dev env checkout different one than on the production. But this would require to keep the local repository in sync with the remote.
Define dist and source for the repository and then differentiate it running composer commands (--prefer-dist on prod, --prefer-source on dev).
Build your own plugin https://getcomposer.org/doc/articles/plugins.md which would jump into action before certain events https://getcomposer.org/doc/articles/scripts.md#event-names
Another option would be to have composer.json file for production and composer-dev.json for development and run the second with setting system ENV variable first:
COMPOSER=composer-dev.json php composer install
But this can produce some incompatibility issues (when you forgot to move a package from composer-dev.json to production composer.json.
While refactoring legacy code, I try to work on a composer package while at the same time work on a project which uses this package.
Composer allows me to add local path repositories for retrieving the package in-development, and symlinking this package into my project.
<composer.json excerpt>
"repositories": [
{
"type": "path",
"url": "../my-package/",
"options": {
"symlink": true
}
}
],
...
"require": {
"my/package": "#dev"
}
I then do
composer update my/package --prefer-source
Which symlinks just fine. However, when building my project on a CI server, I want the project to retrieve the package from a remote git repository, this is why I added the vcs section to my composer.json.
{
"type": "vcs",
"url": "git#bitbucket.org:my/package.git"
}
However, during building via composer install it still tries to retrieve the package locally, which is not available on the CI server of course. I guess because my composer.lock explicitly says that the package is retrieved from a path.
How can I make it work smoothly, both locally and on the CI server? I seem to lack a decent workflow.
What I tried so far:
adding my/package again as a dev-package, but apparently the composer.json will remove if from the no-dev packages automatically then. Also, I do not know how to tell composer to use the path repository for the dev requirement, and the vcs repository for the no-dev requirement.
After tons of hours searching for a suitable workflow, I found out one. Hope it can help you.
Since repository-dev (like require-dev for repository) doesn't exist and will not exist soon (see this), we need to make two composer.json files. Let's say we call the second one composer-dev.json. I think you should commit both and having both up-to-date. To tell composer to use composer-dev.json, you need to put COMPOSER=composer-dev.json in front of every composer command. To illustrate, see this :
composer.json
{
"repositories":[
{
"type": "vcs",
"url": "{repo}"
}
],
"require": {
"vendor/package": "{version}",
}
}
composer-dev.json
{
"repositories":[
{
"type": "path",
"url": "path/to/your/package",
"options": {
"symlink": true
}
}
],
"require": {
"vendor/package" : "{version}",
}
}
As you can see, the composer.json contains the 'vcs' repository and the composer-dev.json contains the 'path' repository.
To initialise your application and start developing :
COMPOSER=composer-dev.json composer update
Composer created the vendor directory and symlink your package folder to vendor/package. It also created a composer-dev.lock file which you should commit for deployment.
To install new package :
COMPOSER=composer-dev.json composer require vendor/package
Remember that composer.json have to be up-to-date, so you have to put all new lines in it.
To build your application :
COMPOSER=composer-dev.json composer install
Which should throw you :
[RuntimeException]
Source path "path/to/your/package" is not found for package vendor/package
Now you can run :
composer update --no-dev vendor/package
or if you need specific version :
composer update --no-dev vendor/package:{version}
Notice that there is no COMPOSER=composer-dev.json in front of the last command since we are using composer.json in order to use our vcs repository. This last command will also install all missing packages.
I hope it was usefull !
TL;DR
I need a way to make composer download my package as an archive so it excludes files and directories I don't want to be included that are on my .gitattributes as export-ignore
Background info
I have files in my composer package repository that I don't want to be included in projects that use this package (DataFixtures, Tests, CI configuration). I have setup a .gitattributes file which excludes those folders and files with export-ignore.
This works fine when downloading the package as a zip manually but it, of course, doesn't when you checkout the code with git.
This is where my problem starts, I have added the repository manually to the composer.json since it is a private gitlab instance. Whenever I run composer update it uses GIT to download the code. I probably need a way to either make composer remove the files that are on the .gitattributes or force it to download my repository as an archive.
composer.json example
"repositories": [
{
"url": "git#<my-gitlab-server>:composer-libraries/testproject.git",
"type": "git"
}
],
......
"require": {
"myownvendor/testproject": "^1.0",
}
Is there a way to solve this?
Try setting the preferred-install method for this repository to dist in your composer.json:
{
"config": {
"preferred-install": {
"myownvendor/testproject": "dist"
}
}
}
Alternatively, install dependencies by running
$ composer install --prefer-dist
For reference, see:
https://getcomposer.org/doc/06-config.md#preferred-install
https://getcomposer.org/doc/03-cli.md#install
I'm trying to install the Intervention Image package for Laravel but it's not working.
In my composer.json file I have this:
"require": {
"laravel/framework": "4.1.*",
"intervention/image": "1.*"
},
Then from the command line in my project directory I have:
php composer.phar install
I get this:
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Warning: The lock file is not up to date with the latest changes in composer.jso
n. You may be getting outdated dependencies. Run update to update them.
Nothing to install or update
Generating autoload files
Generating optimized class loader
I've try running update and then tried installing it again but nothing seem to work.
Any help would be much appreciated,
Thanks in advance, Scott
You might have broken a composer lock file. Remove your vendor folder and composer.lock file:
rm -rf vendor
rm composer.lock
If you are on Windows, use windows explorer to delete the vendor folder and the composer.lock file.
And then install it all again:
composer install
Scenario: I am working with Symfony 2.2. In my list of required packages is also one of my github repositories, let's call it "TestLib".
I know that I can define the github url as additional repository in Symfony's composer.json to download "TestLib" via Composer from Github.
Problem: I cannot commit to "TestLib" repository as there is no local .git directory in the "TestLib" directory. I guess composer is fetching a zip from Github and not cloning it.
So my question is: is there a way to specifiy in Symfony's composer.json that Composer should clone TestLib?
Question 2: Maybe my workflow is wrong - so if you also have this scenario - how do you handle this?
Adding #dev to the package version clones the repository too.
{
"require": {
'package': '*#dev'
}
}
Also is possible setup source as preference in the composer.json
{
"config": {
"preferred-install": "source"
}
}
What I typically do if I notice that a vendor has an issue is rm -rf vendor/foo/bar to remove it and then I run composer install --prefer-source to get it back as a git repo.
What I did was add my github repo to packagist.org then I did this:
composer require malhal/createdby dev-master --prefer-source
This appears to add the require line to composer.json and also get it as a git repo, unfortunately this only works once so if you wouldn't be able to reuse the composer.json for a new install and would need to delete the require line and then remember to do this same command again. This command also downloads the git repo you don't have to do another composer update.