Is it possible to get /dist only in Composer? - php

I'd like to use composer for managing my front-end dependencies as well.
Unfortunately, using "bower-asset/bootstrap": "dev-master" or "twbs/bootstrap": "dev-master" brings more than 80 MB of code, while I need only /dist/ from the whole bootstrap folder.
Is it possible to add only /dist/ of bootstrap to my application using dependency manager?

You can ignore files with the composer fxp-asset plugin.
For instance, if want only the dist folder of bootstrap, add these lines in your composer.json :
"config": {
"process-timeout": 1800,
"fxp-asset":{
"ignore-files": {
"bower-asset/bootstrap": [
"!dist",
"*"
]
}
}
}

Composer cannot influence what is in the packages you download. Especially if you depend on branches (hint: don't do it), basically the only thing Composer does is clone that repository. This adds up to probably the amount of data you see.
You may try to influence what Composer downloads by adding --prefer-dist to the update command (you may need to delete the vendor folder before you update), but if Composer is unable to locate a source for a ZIP download, it will still clone the repo.

Related

Composer download repository in Gitlab as archive

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

Ignore tests folder when send to packagist

I have a project with the following structure:
- src
----/ /* Relevant files */
- tests
----/ /* Irrelevant files */
- composer.json
- phpunit.xml
The project is sent to packagist on every commit already. But, it is sending the test files.
I'd like to ignore tests folder, so composer wont download unecessary files when someone calls composer require my/package
Here is whats the content of my composer.json looks like:
{
"name": "my/package",
"description": "...",
"type": "library",
"license": "MIT",
"require": {
"php": ">=7"
},
"require-dev": {
"phpunit/phpunit": ">=5.4"
},
"autoload": {
"psr-4": {
"MyProject\\": "./src"
}
}
}
Ignore tests folder when send to packagist
Let's first clear up some confusion.
When you enable Packagist for your repository, Packagist will load the composer.json to get metadata about your project and fetch the version informations from the tags/branches.
But you are not sending your PHP code or any tests to Packagist.
I'd like to ignore tests folder, so composer wont download unecessary files when someone calls composer require my/package
This question pops up quite often. I'm referencing a detailed answer, which i've written some time ago, which explains a lot of the background: https://stackoverflow.com/a/32476500/1163786
Usage of a .gitattributes file with export-ignore directive
Technically, you could add a .gitattributes file to your repository, which declares a export-ignore rule for the test folder.
This means that any git export will no longer have the tests folder, including the Github zip file.
Ok, exclude done..
But, when someone composer require's your project, it will now depend on the --prefer-dist setting to install the package from the dist (zip). (You would get the tests with --prefer-source).
If it is a small library, stop to worry. Be happy.. :)
If it is a bigger application, then a better solution is to package your application properly, instead of relying on the git exported zip distribution.
Most developers don't use a build.xml or any build script anymore, but that's the correct way to do it in my opinion.
That means once you are ready to tag a new release.
You trigger your build script, which fetches all the dependencies, runs the tests once more and when everything is ok, drop all the tests and packages the files for deployment.
Small hint: don't forget to add a autoload-dev section for your tests to composer.json.
If your Packagist package is linked to a GitHub repo, just create a "Release" in GitHub that does not contain the development files.
This works out-of-the-box for your end users, because Composer install/update uses --prefer-dist by default, which serves the package zip that is in the "Release".
The easiest way to do this (And it's how some Symfony packages does it, for instance), is to create a .gitattributes (as Jens suggested) with the following content:
/tests export-ignore
Now, when you create a tag/release in GitHub, the release zip won't contain the tests folder.
The only scenario where tests folder would be included in this case is if the user installed your package with --prefer-source, but if they do that, they should know what they're doing.

Composer install package from private GIT repository without the .git directory

I have a project X which relies on module Y. They are both my private projects. Each have their own git repository on bitbucket. And each of them has a composer.json.
When I run composer install on project X, it gets Y from its repository and shoves it into X's vendor directory.
The problem is it also shoves a .git directory in vendor/jodes/Y/.
This is a problem because something keeps opening files in that .git directory, meaning my [continuous integration] scripts cannot then delete the .git directory when it repeats the process. I presume it's my IDE.
How can I make composer get Y from the repository, without making a `.git` directory?
X's composer.json is:
{
"name": "jodes/X",
"require": {
"jodes/Y": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "https://Jodes#bitbucket.org/Jodes/Y.git"
}
]
}
It seems that composer basically runs git clone to fetch from the repository? Instead, is there a way to make it do something similar to git archive into the vendor directory? (rather than a zip file).
as a workaround I have tried configuring my IDE (Netbeans) to ignore the .git directory but my scripts still get the "Permission denied" error when trying to delete it.
As a bonus, I would also like to make use of other advantages of using git archive, such as being able to specify files or directories or other patterns which will be excluded from the archive.
composer [install|update] --prefer-dist
should do the trick.
By default, especially when you refer to branches, instead of tags ("versions"), composer prefers to fetch the dependencies as source. If you specify --prefer-dist you explicitely tell composer to use the archive instead.

Composer downloads entire .git repo directory

I recently published my library in GitHub and Packagist. When I load it to a project, using the Composer, entire repo is being downloaded, along with the hidden .git directory.
How to prevent Composer from downloading this unnecesary directory?
Composer will clone a repository if you do require a development version. And if you reduce the allowed minimum-stability of your application, ALL possible packages are being cloned.
This is actually a good thing because you seem to be in development mode, and after the initial cloning updating these repositories is usually faster - and you can more easily edit these packages and push your changes back.
I tested your package, and it was correctly downloaded as a ZIP file with this composer.json:
{
"require": {
"mikemix/zend2-auth": ">=1.0"
}
}
And after deleting /vendor and the composer cache, it cloned your repo with this composer.json:
{
"require": {
"mikemix/zend2-auth": ">=1.0#dev"
}
}
Changing back to the above version, but not deleting anything, a run of composer update only checked out that tag, but did not download the ZIP file.
So Composer tries to minimize network activity, and tries to not destroy an existing repository, because that repo might have some valuable code committed in another branch.

Use composer to install bundle in custom directory

I see there is already a question but it did not answer the question
How can I install a composer package into the /src dir?
How can I install a bundle in the /src directory?
Reason I would like to do this is for development and deployment, so
I don't have to check in Symfony's base code into my subversion repo
I could use Composer to deploy
Looking over the Composer docs some more I did come across this:
http://getcomposer.org/doc/04-schema.md#config
vendor-dir: Defaults to vendor. You can install dependencies into a
different directory if you want to.
Could I set this at a Bundle level? or is this for the overall install?
https://github.com/composer/composer/blob/master/res/composer-schema.json
I know this is late, but in case anyone is searching for an answer that I painstakingly (hours and hours) found: vendor-dir
The documentation says:
By setting this var you can make composer install the dependencies into a directory other than vendor
Example:
{
"config": {
"vendor-dir": "website/password/vendor/"
}
}
From this doc and this doc
Again, hope to save anyone else a couple hours.
{
"extra": {
"installer-paths": {
"sites/example.com/modules/{$name}": ["vendor/package"]
}
}
}
Read more.
If you find composer's custom installers too complex or rigid, and you can plan what types of systems you will be deploying to, you might consider using post-install scripts.
Here's an example that creates a symlink from a package installed under vendors to the location where it might be expected:
"scripts": {
"post-install-cmd": [
"test -d vendor/foo/bar && ln -s ../vendor/foo/bar lib/bar"
]
}
This will create a symlink at lib/bar/ pointing to vendor/foo/bar/.
I have implemented this composer plugin to install packages into user (custom) defined folders you can just include it in your composer.json, follow the example and tell me if you have more questions :)
https://github.com/mnsami/composer-custom-directory-installer
composer-custom-directory-installer
A composer plugin, to install differenty types of composer packages in custom directories outside the default composer default installation path which is in the vendor folder.
This is not another composer-installer library for supporting non-composer package types i.e. application .. etc. This is only to add the flexability of installing composer packages outside the vendor folder. This package only supports composer package types,
https://getcomposer.org/doc/04-schema.md#type
The type of the package. It defaults to library.
Package types are used for custom installation logic. If you have a package that needs some special logic, you can define a custom type. This could be a symfony-bundle, a wordpress-plugin or a typo3-module. These types will all be specific to certain projects, and they will need to provide an installer capable of installing packages of that type.
How to use
Include the composer plugin into your composer.json require section::
"require":{
"php": ">=5.3",
"mnsami/composer-custom-directory-installer": "1.1.*",
"monolog/monolog": "*"
}
In the extra section define the custom directory you want to the package to be installed in::
"extra":{
"installer-paths":{
"./monolog/": ["monolog/monolog"]
}
by adding the installer-paths part, you are telling composer to install the monolog package inside the monolog folder in your root directory.
As an added new feature, we have added more flexibility in defining your download directory same like the composer/installers, in other words you can use variables like {$vendor} and {$name} in your installer-path section:
"extra": {
"installer-paths": {
"./customlibs/{$vendor}/db/{$name}": ["doctrine/orm"]
}
}
the above will manage to install the doctrine/orm package in the root folder of your project, under customlibs.
Note
Composer type: project is not supported in this installer, as packages with type project only make sense to be used with application shells like symfony/framework-standard-edition, to be required by another package.

Categories