Scrutinizer: install custom composer packages? - php

I have a Github project in Scrutinizer, that has an optional recommended package in its composer.json.
I would like to install this optional package during the Scrutinizer build, but could not find any information on how to do so in the Scrutinizer config. While the package is optional, Scrutinizer detects a number of bugs because the dependency is not present, and some of the unit tests will only run if it is present.
Is it possible to run custom composer commands, or to have additional composer packages installed?
The related package is Mistralys/application-utils.

Looking through scrutinizer configurations of other projects, I was able to find out how to run custom composer commands.
To require additional packages, these can be added in the dependencies:
build:
dependencies:
before:
- composer require vendor/package-name:version
It is also possible to override scrutinizer's composer command entirely, for example to run a script:
build:
dependencies:
override:
- composer run-script scriptname
In my case, because the suggested package also requires the source package back (cyclic dependency), I had to set the root version, like this:
build:
dependencies:
override:
- COMPOSER_ROOT_VERSION=dev-master composer require mistralys/application-localization:dev-master

Related

composer remove (uninstall) all installed packages (composer install rollback)

I have a project with the composer.lock file.
I installed packages with the command:
composer install
Now I would like to rollback that composer install command to the state as it was before running it.
How to remove all packages without affecting composer.lock file?
Is there any single composer command to do that?
I tried:
composer remove *
but I got:
[UnexpectedValueException]
"LICENSE" is not a valid alias.
I tried:
composer remove */*
But then I get bunch of print like:
bin/console is not required in your composer.json and has not been removed
Package "bin/console" listed for update is not locked.
Why composer remove * did not work at all? AFAIK the package name as VendorName/PackageName is a common convention for Packagist but not a must (if you use private repos) so how one would be able to remove all packages named IdontHaveAnySlash etc. at once?
I may use someting similar to:
for package in $(composer show | awk '{print $1}'); do composer remove --no-interaction --dev --no-install "$package"; done
But that is not a simple and single composer command.
Also composer often complains about a package being a part (dependency) of another one so composer does not uninstall it.
Removal failed, doctrine/annotations is still present, it may be required by another package. See composer why doctrine/annotations.
As my intention is to rollback to the state that did not have any package installed but only files: composer.lock and potentially composer.json I really don't care about any dependencies, packages versions, downloading repositories' urls etc.
I just want to have a project without any installed dependencies as it was before.
Is there any single composer command to do that?
My:
composer --version
is:
version 2.2.7 2022-02-25 11:12:27
Following yivi answer I created a simple test to verify:
mkdir -p /tmp/composer-install
cd /tmp/composer-install
curl -o composer.json https://raw.githubusercontent.com/composer/composer/18246212db7103d0a2688febcc336f77183275ee/composer.json
curl -o composer.lock https://raw.githubusercontent.com/composer/composer/d955458f271edb4fcc055a394f90a60a8328a2a8/composer.lock
sha1sum composer.json > composer.json.sha1
sha1sum composer.lock > composer.lock.sha1
composer install
sha1sum -c composer.json.sha1
sha1sum -c composer.lock.sha1
that outputs:
composer.json: OK
composer.lock: OK
So both composer.json and composer.lock are not affected by composer install so the only one thing to achieve the rollback (uninstall) of the composer install is to remove the vendor directory
rm -rf vendor
However as yivi mentioned:
If some other plugin (e.g Symfony Flex) makes changes to your existing files during the process, you'd better have the project on top of a version control system, in which case reverting is managed by VCS, not of composer.
I did not test against that case.
rm -rf vendor
In any case, install should not make any changes to a lockfile, so there shouldn't be anything to "revert" from an install but deleting the installed files.
If the lockfile does not originally exist, then it will be created.
If some other plugin (e.g Symfony Flex) makes changes to your existing files during the process, you'd better have the project on top of a version control system, in which case reverting is managed by VCS, not of composer.
As my intention is to rollback to the state that did not have any package installed but only files: composer.lock and potentially composer.json
For you to be able to run composer install at all, you need at the very least composer.json to exist. install reads from the lockfile (composer.lock), but requires the JSON configuration file to exist as well. If the lockfile does not exist, update will be run instead and the lockfile will be created.
I tried composer remove
remove is the opposite from require. It removes packages from composer.json, as require adds them. Not the opposite of install. There is no opposite of install, as it does not make much conceptual sense. If one needs to delete the installed project... one can always do so.

How to use PHPUnit extensions with Symfony's PHPUnit Bridge?

I'm using PHPUnit Bridge in my Symfony project. I'm currently using PHPUnit 7 and I want to upgrade to PHPUnit 8.
In PHPUnit 8 array subset assertions are deprecated and generate warnings. I want to use dms/phpunit-arraysubset-asserts package to provide them. With regular PHPUnit I'd just composer require it and call it a day.
Now, the Bridge doesn't have original PHPUnit as its dependency, instead it installs it to a temporary folder, patches it and runs from there. phpunit-arraysubset-asserts has PHPUnit dependency though and generates a warning:
Adding phpunit/phpunit as a dependency is discouraged in favor of Symfony's PHPUnit Bridge.
* Instead:
1. Remove it now: composer remove --dev phpunit/phpunit
2. Use Symfony's bridge: composer require --dev phpunit
I don't want to install phpunit/phpunit to avoid confusion.
I've tried to ignore it by adding a * replacement, but just adding the replacement to composer.json produces a Composer error:
Your requirements could not be resolved to an installable set of packages.
Problem 1
- __root__ No version set (parsed as 1.0.0) conflicts with symfony/phpunit-bridge[v5.0.5].
- symfony/phpunit-bridge v5.0.5 conflicts with __root__[No version set (parsed as 1.0.0)].
- Installation request for __root__ No version set (parsed as 1.0.0) -> satisfiable by __root__[No version set (parsed as 1.0.0)].
- Installation request for symfony/phpunit-bridge v5.0.5 -> satisfiable by symfony/phpunit-bridge[v5.0.5].
What's the correct way to add a PHPUnit extension when using PHPUnit Bridge?
WARNING I do not know phpunit-bridge well (in fact today was my first day with it), but I can see the way to achieve what you want. It's not that convenient, but possible. I think it's better to either check with symfony team (maybe there is a supported way for this) or just use plain phpunit (it seems easier and it should be possible to integrate it with symfony's phpunit-bridge without relaying on bridge to install phpunit itself)
# create new symfony project
symfony new gronostaj-phpunit
# cd in it
cd gronostaj-phpunit
# install phpunit-bridge
symfony composer req phpunit-bridge
# to change phpunit version to 9.5
vim phpunit.xml.dist
# install phpunit in symfony bridge way
bin/phpunit
# to update phpunit config
bin/phpunit --migrate-configuration
# black magic begins here
cd bin/.phpunit/phpunit-9.5-0
# to bypass `autoload-dev` in later dump-autoload
mkdir -p tests/_files ; touch tests/_files/CoverageNamespacedFunctionTest.php tests/_files/CoveredFunction.php tests/_files/NamespaceCoveredFunction.php
# install phpunit plugin
composer require --no-plugins dms/phpunit-arraysubset-asserts
# cd back to the root of project
cd -
# create test
--- phpunit/gronostaj-phpunit ‹master* M?› » cat tests/SubsetTest.php
<?php
declare(strict_types=1);
namespace App\Tests;
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
use DMS\PHPUnitExtensions\ArraySubset\Assert;
use PHPUnit\Framework\TestCase;
class SubsetTest extends TestCase
{
use ArraySubsetAsserts;
public function testWithTrait(): void
{
$expectedSubset = ['bar' => 0];
$content = ['bar' => 0];
self::assertArraySubset($expectedSubset, $content, true);
}
public function testWithDirectCall(): void
{
$expectedSubset = ['bar' => 0];
$content = ['bar' => 0];
Assert::assertArraySubset($expectedSubset, $content, true);
}
}
# run test
--- phpunit/gronostaj-phpunit ‹master* M?› » bin/phpunit
PHPUnit 9.5.0 by Sebastian Bergmann and contributors.
Testing
.. 2 / 2 (100%)
Time: 00:00.006, Memory: 8.00 MB
OK (2 tests, 2 assertions)
# done
For phpunit 8, use phpunit verion 8.0 in phpunit.xml.dist and install your plugin like this composer require --no-plugins 'dms/phpunit-arraysubset-asserts:*', that will work.
To make it reproducible for others in your team you will need to provide composer scripts (to create dummy files and install plugin, but it should do the trick) and hook them into something like post-install and post-update events.
I have been struggling with this issue as well in the past, and found this tip in the PHPUnit Bridge documentation:
It is also possible to require additional packages that will be
installed along the rest of the needed PHPUnit packages using the
SYMFONY_PHPUNIT_REQUIRE env variable. This is specially useful for
installing PHPUnit plugins without having to add them to your main
composer.json file.
So basically, edit phpunit.xml.dist and declare the env variable under the existing <php> tag:
<php>
<server name="SYMFONY_PHPUNIT_REQUIRE" value="dms/phpunit-arraysubset-asserts" />
</php>
To add multiple packages, use a space delimiter:
<php>
<server name="SYMFONY_PHPUNIT_REQUIRE" value="dms/phpunit-arraysubset-asserts spatie/phpunit-snapshot-assertions" />
</php>

Missing composer/zend command: development-enable

When I install Zend via composer create-project -n -sdev zendframework/skeleton-application as specified by Zend's main tutorial, I get a skeleton application that seems to work nicely.
However, when I follow this tutorial's advice to use composer development-enable, I get the following message:
[Symfony\Component\Console\Exception\CommandNotFoundException]
Command "development-enable" is not defined.
Is anyone able to duplicate/fix this problem?
I would normally assume it's an issue with the bash $PATH value, but the composer command by itself runs just fine, so I'm thinking it may be some other problem specific to this subcommand -- a missing dependency somewhere, for example.
Here is the relevant piece of the tutorial I am trying to follow:
https://docs.zendframework.com/tutorials/getting-started/skeleton-application/
(In case it helps for purposes of duplication: The CLI PHP version on my development server is 5.4.43. For reasons I won't bore you with, I can't update this CLI PHP to a newer version; the major release that Apache is using on my machine is 5.6.)
EDIT 1: Rerunning my installation using composer create-project -s dev zendframework/skeleton-application (as specified in the linked tutorial) still results in the same problem.
EDIT 2: Here is my shell input/output.
patrick [~/www/berlin-data]# composer create-project -n -sdev zendframework/skeleton-application
Installing zendframework/skeleton-application (2.3.3)
- Installing zendframework/skeleton-application (2.3.3)
Loading from cache
Created project in /home1/patrick/public_html/berlin-data/skeleton-application
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing zendframework/zendxml (1.0.2)
Loading from cache
- Installing zendframework/zendframework (2.3.3)
Loading from cache
zendframework/zendframework suggests installing doctrine/annotations (Doctrine Annotations >=1.0 for annotation features)
zendframework/zendframework suggests installing ircmaxell/random-lib (Fallback random byte generator for Zend\Math\Rand if OpenSSL/Mcrypt extensions are unavailable)
zendframework/zendframework suggests installing ocramius/proxy-manager (ProxyManager 0.5.* to handle lazy initialization of services)
zendframework/zendframework suggests installing zendframework/zendpdf (ZendPdf for creating PDF representations of barcodes)
zendframework/zendframework suggests installing zendframework/zendservice-recaptcha (ZendService\ReCaptcha for rendering ReCaptchas in Zend\Captcha and/or Zend\Form)
Writing lock file
Generating autoload files
patrick [~/www/berlin-data]# cd skeleton-application/
patrick [~/www/berlin-data/skeleton-application]# composer development-enable
[Symfony\Component\Console\Exception\CommandNotFoundException]
Command "development-enable" is not defined.
When you run the command
composer create-project -n -sdev zendframework/skeleton-application
This will create a directory in your current dir called skeleton-application inside of this directory is where you need to run the command:
composer development-enable
If this still doesnt work then something went wrong with install process.
The first command should give out put something like:
$ composer create-project -n -sdev zendframework/skeleton-application
Installing zendframework/skeleton-application (dev-master 941da45b407e4f09e264f0 00fb537928badb96ed)
- Installing zendframework/skeleton-application (dev-master master)
Cloning master from cache
Created project in C:\Users\<UserName>\Documents\skeleton-application
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
- Installing zendframework/zend-component-installer (0.3.0)
Downloading: 100%
- Installing zendframework/zend-stdlib (3.0.1)
Downloading: 100%
...
Notice this line Created project in C:\Users\<UserName>\Documents\skeleton-application
Thats the directory you need to be in to run the command:
cd C:\Users\<UserName>\Documents\skeleton-application
composer development-enable
If that still didnt work, try specifying the version for downloading:
composer create-project -n "zendframework/skeleton-application":"dev-master"
PS
As of writing this the skeleton application requires PHP "^5.6 || ^7.0". So if you are running a lower version composer wont install that copy. And the tutorials based on it may not work as expected.
Two things I've noticed: when you first initialize a skeleton application, depending on your settings, development mode is enabled by default.
If you want to run
composer development-enable
or any other similar commands, you must be in your path/to/install or path/to/yourapp directory for it to work! This is the folder that contains your local composer install. If you are in any of the parent directories, the command will not work.
I was also having this similar problem when trying to enable development mode with the command composer development-enable on my apigility app. I was getting error:
zf-development-mode is not recognised as an internal or external command.
There is a page on the apigility website regarding the development mode module:
https://apigility.org/documentation/modules/zf-development-mode
I found by following the instruction to install the module from composer:
$ composer require zfcampus/zf-development-mode
Then making a copy of the development config file:
$ cp vendor/zfcampus/zf-development-mode/development.config.php.dist config/
Now using the composer development-enable seems to work fine, which in my case returned the message 'Already in development mode'.

My own composer package: automatic dev-master download

I'm making my own Composer package for educational purposes. It's just a Laravel extended package with some libraries already installed.
I uploaded to GitHub: jorgeanzola/laravel
I posted it at Packagist
When I try to run:
$ composer create-package jorgeanzola/laravel <path>
It gave me this error:
Could not find package jorgeanzola/laravel with stability stable
In order to make it work, I have to add =dev-master, like this:
$ composer create-package jorgeanzola/laravel=dev-master
It downloads correctly but at the end it gave me this warning:
Do you want to remove the existing VCS (.git, .svn..) history? [Y,n]?
My question is: How can I set the download process to be more neat? Like, ie: Laravel itself:
$ composer create-project laravel/laravel <path>
Release versions of your package, by creating git tags (git tag). Then, the latest stable version will be installed when using composer create-project.
If you don't want that, then set the stability to dev by doing composer create-project --stability=dev xxx/yyy

What's the difference between require and require-dev? [duplicate]

This question already has answers here:
What is the difference between require and require-dev sections in composer.json?
(6 answers)
Closed 4 years ago.
I would like to know the difference between require and require-dev.
The composer website doesn't offer a good explanation the difference between these two.
The part that I don't get is Lists packages required for developing this package, or running tests, etc. from Composer Official Docs.
The require-dev packages are packages that aren't necessary for your project to work and shouldn't be included in the production version of your project.
Typically, these are packages such as phpunit/phpunit that you would only use during development.
The key distinction is that Composer will only install require-dev dependencies for the "root package" – the directory where you run composer install. The documentation describes this as:
The root package is the package defined by the composer.json at the
root of your project. It is the main composer.json that defines your
project requirements.
…and the require-dev documentation specifies that it is "root-only".
In practice, this means that a package's require-dev dependencies aren't used if the package is being installed as a dependency for something else (ie it's installed to another project's vendor folder).
So if you have phpunit in the require-dev list for YourProject, and I clone down YourProject and run composer install in the yourproject/ directory, Composer will install phpunit to yourproject/vendor/, because it's likely I'm doing some development on YourProject. As part of doing development I'll probably want to run YourProject's test suite, and to do that I'll need phpunit.
But, if I add YourProject as a dependency of MyProject, installing the myproject package will install the yourproject package as well, but it will not install phpunit.
You can override this behaviour with the --dev and --no-dev options, but the default behaviour is based on whether the package concerned is the root package.
seems clear to me:
require
Lists packages required by this package. The package will not be
installed unless those requirements can be met.
require-dev (root-only)
Lists packages required for developing this package (1), or running tests,
etc. The dev requirements of the root package only will be installed
if install is run with --dev or if update is run without --no-dev.
http://getcomposer.org/doc/04-schema.md
1. the packages used to develop a package

Categories