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
Related
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 !
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.
I've set up two projects, an 'init' and a library, which is required by the init. They both have PSR-0 autoloads set, but the autoload values from the library are not added to the vendor/composer/autoload_namespaces.php in the init project.
Sample composer.json from the Library:
{
"name": "lxp/library",
"description": "A test library",
"autoload": {
"psr-0": {
"LXP\\Library": "src/"
}
}
}
Sample composer.json from the project that requires that library:
{
"name": "lxp/init",
"name": "A test init",
"autoload": {
"psr-0": {
"LXP\\Init": "src/"
}
},
"repositories": [
{
"type": "composer",
"url": "http://satis.repo.redacted/"
}
],
"require": {
"lxp/library": "dev-master"
}
}
The library contains the class LXP\Library\Something in the file src/LXP/Library/Something.php.
The project that requires the library contains the class LXP\Init\Now in the file src/LXP/Init/Now.php.
When running composer install in the 'init' project, it downloads the library project and puts it in vendor correctly, but vendor/composer/autoload_namespaces.php doesn't contain the library's autoload information, only that of the current project.
What am I doing wrong? If I run dump-autoload in the library project then the autoload_namespaces.php file is correct, and a quick bootstrap script confirms that it does indeed pick up the class.
EDIT - This is a problem with the satis-generated packages.json. To fix it, I had to add the autoload information from the library's composer.json into the json file I supply to satis, which seems like an unnecessary duplication and so I'm probably doing it wrong. Is there a single place that autoload information can be stored for satis libraries? For example, can satis read the composer.json files that exist in the libraries it scans?
EDIT #2 - Satis does not read the composer.jsons from repositories specified as 'package' type. This is obvious in hindsight, because 'package' is used for libraries that do not have a composer.json, and is a way to wrap composer-like dependency management around them.
Changing the satis.json's repository to 'vcs' type meant that the composer.json was read, and the information (including the autoload specification) was parsed and stored in the packages.json.
#Seldaek - thank you for suggesting that my satis config was the problem, and I hope that this clarifies satis / composer behaviour for anyone else in my position.
I see two possible mistakes you may have done that would cause this:
You forgot to update your satis repo so the autoload config for lxp/init is not up to date in there
You are running composer install from a lock file, and that means composer just reads the info from the composer.lock file and does not update package metadata to the latest version available in satis. To solve this you should run composer update instead.
Try composer dump-autoload command.
It depends how you installing your library via Composer. For example, when downloading it as package type (same I believe with composer type), Composer never reads the composer.json file, so instead you should use vcs or git type. See: GH-6846.
Here is composer.json which should work:
{
"require": {
"lxp/library": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "http://satis.repo.redacted/"
}
]
}
Then run: composer install.
For troubleshooting, try running:
composer dump-autoload -o -vvv.
composer diagnose -vvv
I pull in a package using Composer with this composer.json:
{
"require": {
"torophp/torophp": "dev-master",
},
}
When I run composer install it seems to pull this package from GitHub directly.
I have created a fork of that repo on github with some small changes. Is there a way I can get composer to pull my version on GitHub instead of the original?
If this is your composer.json
"require": {
"torophp/torophp": "dev-master"
}
and you want to change it and use your fork instead, just add your repository into composer.json as follows:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/your-github-username/torophp"
}
]
Important: Do not change the "require" part, it must continue using torophp/torophp!
After adding the "repositories" part, run a composer update (or composer.phar update) and composer will then download your fork (even though it echoes "installing torophp/torophp" during the operation).
Update (18.09.2014): As mentioned by #efesaid in the comments:
If your package is published on packagist, you need to add
--prefer-source option to force installation from VCS.
Note: For those having issues with pulling from the HTTP(S) source (ie you get [RuntimeException] Failed to clone https://github.com/your-github-username/torophp, could not read packages from it when trying to update), you can change the composer.json to use the git protocol instead. To do so, change the composer.json as follows and run composer update again.
"repositories": [
{
"type": "git",
"url": "git://github.com/your-github-username/torophp.git"
}
]
Now go into vendor/torophp/torophp and run git remote -v for a double check that you use the desired source for the repository.
From there you can commit the changes to your fork and update it from origin (git pull origin master).
Update: To work with private repositories at GitHub, you must use git protocol and also must have installed SSH keys for a git client.
Composer reference: Loading a package from a VCS repository
I'm trying to publish composer package. I saved composer.json in my package directory:
{
"name": "vendor_name/my_bundle",
"type": "symfony-bundle",
"autoload": {
"psr-0": {
"VendorName\\MyBundle": ""
}
},
"target-dir": "VendorName/MyBundle"
}
But when I install it (composer update), with package files will added .hg directory.
Similar behaviour can be seen in this package: https://packagist.org/packages/tom32i/file-bundle (with package files will added .git directory: http://joxi.ru/uploads/prod/20130201/560/53a/136c5290b3c0f4c6f6318445f358d1d8cf30fe13.png)
Quote from the documentation:
There are two ways of downloading a package: source and dist. For stable versions composer will use the dist by default. The source is a version control repository.
The package you mentioned has no stable version, so composer downloads the source from git. Use --prefer-dist if you'd like composer to download package files (only happens if possible).
Jakub's answer is great, and totally nails the solution...
In order to more permanently specify the dist version, simply add a preferred-install to your composer.json file:
{
"config": {
"preferred-install": "dist"
}
}