Composer downloads entire .git repo directory - php

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.

Related

How to regenerate autoloader per local changes to package composer.json

I know this is sloppy and unconventional, but I need to test some changes to a package by manually adjusting a composer.json file within a package in the vendor folder. But I can't figure out how to get the new dependencies and "autoloader->file" changes to take hold. I've tried composer install, composer dumpautoload -o, and installing directly from that folder (which merely created a new and useless "vendor" folder within the package directory).
Is this even possible, or just too sloppy for Composer to offer a way to go about it?

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.

Using SVN and composer together - Version control of the vendor directory

This is how I use composer and svn together:
In my development version, I run composer to download required packages to the vendor directory. I then commit the vendor directory to svn together with the rest of the development folder. The production build makes a copy of the vendor folder.
I know, it is recommended not to commit the vendor directory in svn (see SVN Repo in vendor with Composer), but I want to be safe for the case when a composer update may break my application. It allows me to rollback everything in that case to the last stable state.
The problem with how composer works is that the checked out svn repo breaks, if composer deletes whole directories.
I would switch to the recommended practice and only check in composer.lock and composer.json into svn, if I knew how to rollback an eventual breaking composer update. Can somebody explain this to me, please.
When you have composer.lock and run composer install (not update) you are sure that you'll get dependencies which are "locked" by you.
Running composer update ignores entries in composer.lock and tries to download latest dependencies allowed by composer.json.

Where do PHP Composer Packages Come From?

When I run
$ composer.phar install
where do the packages that get installed come from?
I understand that Packagist is the default repository for PHP packages, and that lacking a different package in composer.json, this is where composer will look for packages.
However, what I'm not clear on is how Composer and Packagist interact.
Does Composer download files directly from packagist.org
Or does Composer get a git/svn/hg repository link from packagist and download the files from the repository directly?
Or something else?
It depends on the contents of your composer.json file.
For example, if your composer.json contained simply
{
"require": {
"phpunit/phpunit": "3.8.*#dev"
}
}
then composer searches packagist, and finds phpunit here:
https://packagist.org/packages/phpunit/phpunit
which tells composer to load phpunit from here:
https://github.com/sebastianbergmann/phpunit.git
If instead your composer.json contained
{
"repositories": [
{
"type": "vcs",
"url": "http://github.com/sebastianbergmann/phpunit"
}
],
"require": {
"phpunit/phpunit": "3.8.*#dev"
}
}
then composer will not look to packagist, but go directly to github to download the repo.
The packages registered on Packagist are usually the "authoritative" version of the package (not a fork), but I have found several instances where this is NOT the case, so you should check it to be sure you are pulling the package you expect.
Packagist.org offers users to register their software there by pointing Packagist to read their composer.json file that is published somewhere on the web.
The usual case would be some of the common open source hosters like github, which makes it really easy because composer can deal with such a git repo right away. You could however host your own git or svn or hg repository, or even just publish ready-made ZIP or TGZ files for each software version.
Composer downloads directly from the source, e.g. Packagist only knows those source and tells your composer instance where to go. It does this by downloading a bunch of json files from Packagist.org that have all the infos. This is way easier than to find out where the libraries that you want are hosted and add this info as a repository entry into your local composer.json file. :)

How to clone repository with Composer without --prefer-source? (using Symfony 2)

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.

Categories