How to get Composer to leave a package alone - php

I have two packages that was pulled to my project with composer.
I don't want to have composer pull updates on these packages from anywhere and don't want composer to try and override my files with any repository.
If I remove the packages from my composer.json file it deletes the packages an removes the autoloaders.
How do I get composer to leave the packages alone and allow me to work on the code without losing the files or autoloaders on update.

I figured out how to do this.
What you want to do is create an artifact directory.
Thus in your main composer.json file you need to do something like this:
"repositories": [
{
"type": "artifact",
"url": "custom/artifact/"
},
..........
the url var should be the file path to the zip files relative to composer.json file.
Now you only need to add a composer.json file with a name and version to a zip file.
If the package already contains a composer.json file you only need to add a version.
example:
vendor-package-1.0.zip needs a composer.json file with:
{
"version": "1.0",
"name": "vendor/package",
"type": "library",
........... etc
}
It is important to define the version in the composer.json file or it will not find it.
Now you call this package by version from your projects composer file:
"require": {
"vendor/package": "1.0",
Now you can create and update files in your package without the worry that some online change or offline server will cause any problems.
As long as the version stays the same it should leave your files alone.
The good thing is that files added or removed will still update the autoloaders as specified in the zip package's composer.json file.

Give a specific version for that package, so it will not be updated when new versions come up
If you don't have too many packages, you can use
composer update package1 package2

Related

Why is composer using the unpatched version of a file?

I forked a repository and patched a yml file in my forked repository in order to give it valid yml formatting.
https://github.com/patrickmaynard/SonataMediaTwigExtensionBundle/blob/master/Resources/config/services.yml
... but I now find that when I run composer install the old, unpatched version of the file is being pulled in.
The relevant parts of my composer.yml file look like this:
"repositories": [
{
"type": "vcs",
"url": "git#github.com:patrickmaynard/SonataMediaTwigExtensionBundle.git"
}
],
... and this:
"socialbit/sonatamediatwigextension-bundle": "master#dev"
What can I do to force composer to use my patched version of the file?
Because composer installuses the composer.lock file and therefore installs a predefined set of packages. What you instead want is to composer update so it checks your packages new version.

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 cannot find the package for new require within Yii2 composer.json

Ok, I'm using Yii2 and I am trying to add a new requirement/library to the project. Said library can be found here: https://github.com/cyphix333/SBBCodeParser
It is a forked project with an added composer.json.
I tried adding it as a requirement in the projects main composer file, ie:
"require": {
//..........
"samclarke/sbb-code-parser": "*"
},
Then I ran:
composer update
It just complained that it couldn't find the package or any version of it.
Then I removed that line and tried:
require samclarke/sbb-code-parser
I have the files already in my Yii vendor folder located at: #app/vendor/samclarke/sbb-code-parser
I'm pretty new to composer and am not sure what I'm doing wrong or how composer actually is supposed to know where to get the files from based on the package name.
The package samclarke/sbb-code-parser can be found at Packagist.
https://packagist.org/packages/samclarke/sbb-code-parser
By default Composer tries to resolve a stableset of packages.
But this packages doesn't provide a stable version (version tag), yet - only the dev-master version exists. Composer can not resolve it.
In order to require it, you need to lower your minimum-stability for this package to development.
You might do this for one package explicitly:
"require": {
"samclarke/sbb-code-parser": "dev-master#dev"
},
Or for all packages by setting:
"minimum-stability": "dev"
The package cyphix333/SBBCodeParser is not on Packagist.
It's a private fork. If you want exactly this code. You might add a repositories section to your composer.json and add repo with url and type with vcs there. Then Composer can load the package from the VCS repository over at Github. This is described here: https://getcomposer.org/doc/05-repositories.md#loading-a-package-from-a-vcs-repository
That would work like this:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/cyphix333/SBBCodeParser"
}
],
"require": {
"samclarke/sbb-code-parser": "dev-master"
}
}
But unfortunately, the fork is also not well maintained and doesn't contain a valid composer.json file.
[Composer\Repository\InvalidRepositoryException]
No valid composer.json was found in any branch or tag of https://github.com/cyphix333/SBBCodeParser, could not load a package from it.
This needs to be fixed first....

Composer VCS Different Directory Name

When using Composer to load a package from a VCS repository, is there a way to specify which folder to install the contents in to (similar to git clone <directory>)?
For example the repo is:
https://github.com/organization/plugin_name.git
And thus composer file reads:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/organization/plugin_name.git"
}]
"require": {
"organization/plugin_name": "dev-master",
}
Whereas the directory I want the contents to be is not "plugin_name" but something like "organization_plugin-title".
I have several repos (custom WP plugins) that have one name, but a different folder name within my WordPress MU setup, and I'd really like to not have to enable each one manually within the admin after updating my composer file.
Naturally answered my own question once I posted...
In the repo's composer.json file, the "name" field should be what you want the directory to be called when installed. I erroneously thought it had to be the name of the repo.
Be sure to then edit the local install's composer.json file so under the "required" section it is the same name as seen in the repo's composer.json file

Symfony2.3 - How to add a custom vendor

I have a Symfony 2.3 project and I would like to use a custom vendor. I know that on Symfony versions 2.1 and 2.2, you can declare vendors in the deps file.
But how can I declare a custom vendor in Symfony 2.3 project? There is a composer.json file, but I don't really understand how it works.
EDIT:
The custom vendor's code is located on github.
composer.json manages dependencies through the composer tool (which you should have installed). It behaves similarly to npm if you have used that at all.
You can include a custom vendor in a couple of ways - although for the custom vendor code to be (auto)loaded & picked up by composer it will need to have a composer.json file.
Packagist
If the custom vendor has successfully submitted their to packagist then you life is easy, you can search for it and take note of the name (in the <vendor>/<package> format.
Open up your composer.json file and at the end of the "require": {} statement add your vendor. For example if our package was called peterjmit/awesome-package
// ...
"require": {
// ...
"peterjmit/awesome-package": "*"
},
// ...
You can replace the * with a version number if you wish. Once you have done that, you can run the composer update command to pull in your new package. If you only want to update the new package you can use composer update peterjmit/awesome-package.
Thanks to the composer autoloader, and the PSR-0 standard, classes from the package are auto-loaded so there is no other "plumbing" for you to do.
VCS repository
If the custom vendor is not on packagist, but does have a composer.json file then you can specify a custom repository to composer. You need to have the same require statement as before, but you need to add a new statement to composer.json
// ...
"require": {
// ...
"peterjmit/awesome-package": "*"
},
"repositories": [
{
"type": "vcs",
"url": "git#bitbucket.org:peterjmit/awesome-package.git"
},
// .. etc.
If the package does not have a composer.json then you can always fork it and add your own. But if the code does not conform to PSR-0 then you will have to sort out your own auto-loading strategy for the package.

Categories