From 80318cc033c069eb17e5b7f0724a00c227454a02 Mon Sep 17 00:00:00 2001 From: borNfreee Date: Mon, 28 Jan 2019 20:04:13 +0300 Subject: [PATCH 1/3] Add `--ci-friendly` option to differentiate between progress bars output --- .travis.yml | 2 +- src/Command/InfectionCommand.php | 6 ++ src/Process/Builder/SubscriberBuilder.php | 37 +++++++- .../CiInitialTestsConsoleLoggerSubscriber.php | 89 ++++++++++++++++++ ...iMutantCreatingConsoleLoggerSubscriber.php | 71 ++++++++++++++ ...ationGeneratingConsoleLoggerSubscriber.php | 73 +++++++++++++++ .../Process/Builder/SubscriberBuilderTest.php | 9 +- ...nitialTestsConsoleLoggerSubscriberTest.php | 92 +++++++++++++++++++ ...antCreatingConsoleLoggerSubscriberTest.php | 76 +++++++++++++++ ...nGeneratingConsoleLoggerSubscriberTest.php | 78 ++++++++++++++++ 10 files changed, 526 insertions(+), 7 deletions(-) create mode 100644 src/Process/Listener/CiInitialTestsConsoleLoggerSubscriber.php create mode 100644 src/Process/Listener/CiMutantCreatingConsoleLoggerSubscriber.php create mode 100644 src/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriber.php create mode 100644 tests/Process/Listener/CiInitialTestsConsoleLoggerSubscriberTest.php create mode 100644 tests/Process/Listener/CiMutantCreatingConsoleLoggerSubscriberTest.php create mode 100644 tests/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriberTest.php diff --git a/.travis.yml b/.travis.yml index 86ea08c28..2bcf5ac53 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ sudo: false env: global: - - INFECTION_FLAGS='--threads=4 --min-msi=67 --min-covered-msi=75 --coverage=coverage --log-verbosity=none' + - INFECTION_FLAGS='--threads=4 --min-msi=67 --min-covered-msi=75 --coverage=coverage --log-verbosity=none --ci-friendly' - PHPUNIT_BIN='vendor/bin/phpunit --coverage-clover=clover.xml --coverage-xml=coverage/coverage-xml --log-junit=coverage/phpunit.junit.xml' - secure: KPHUzOeWLeCWzcyPrnrDaR6grVUEXj48KlSQhJiubdkyKtGcvEs+TzZNYa2v+mSZsvrBHez9MRu4itcx05fNrb7/6M23uppv+fENH7tgZi8PXktlEXvD+Iqc9DIaDS1hQKpsnOhOZLlDNQ/kyE6TJAvoBMcbG6RfLqwLP1Abdz11t9Z65SIL7l2YpTjLjgmZUctpEVkivnQ3VQojd3soFTKZ8s9jNhdyUL2F+Rab4wu26Dy+q9xEd5y1tj2242nmVU7U/OD/spTkxRivuUPNM7jEnUvUcdEHd5DIBki702OrSkgsjrxlOlqOWcIRzVZA+A54GiE8qpnLSPN1qbc68ifXhd4lw4zKrE9KfvI8gnnFHtwQP0lhQuwG+j/VtbQRYrb0ufX1sAOUpOIDGMxYrh+Hn6j/nZnBiBh3NRF0u6PLfnAuph5TybylY0cuiGfGOWFf8UG7yz/EH+Br/D5M/IkObU8b9e3YJlUQPcjTi0BSa/+lkLpQMOOVOlQZk+LTVVRjXwSO10JcWhpqwWX74dsa5b2N/XbXOEQldVsYuQZz7re8e5Nwm5dx+B/KF/ohv2GDkQdqAA35ogOAABI3rvGlfOESDeZyGYOiJqBWX+KLKNRQ6l/KRkHNflX5J+0xeRlK4L84n0YwesyEAEFnYrYtQ+/VNd9ZP2+xXyTrePI= - secure: gto1Cg/FEurmKP+JNi7G7MBxJx9KX+WzM9VlLnu0x1Hq+2n8dEgNCBc9gvNrdpPPWHdke23uYXxM3XaKh6f/KXNRmYskJwAUP/jWTwkAc9dIz6qo3ObcS3M6WPnohkjhTJjJJH/dbUknR9gbstTvGsan7JysUnast6uyAhuP81ago0BoiCshTGPa7gZkD4dPPvDrUr70kRzgOd2ZJQZcuoCfL00q4Yu0OkjM9VMBxaBKkL8EE7594aYDjFtGbJuvWmZ36qqtUxzc3ly+G3IHfQVMQqN8+H0VB4ULwE1JOzWMsj5gpJtVeyPY5BTcAOE3je5/+1eq14VVnf3iSgMu3DbF1o/KuMxdes5vDadoZaVQmtLtNHvgu/UDCicBKk3BnLtlQe1bFfEsoSDRr+zCVkO5ypcbERxQzVCGdZdHsXLFZSxdLsEqSqD5ItZe1ZXv4K8bsDDY5rJgjyaiQs/FT/G4dlf61MHqzKtErgsNQ99ilV4iWqHGHnbMISyYdiLWTG8z/nhE34M+08J0gpSDfVrs1pvoUIzhD8KvjlU2QC2IXuE38aXTZm4IeTA7P6vZbUoCCcgOxIRqzS0UX9M1ddOUmy6prc3CGgiEgn6ey/eWmfyRQSbuL07aRH7MEzW4ESAJbdjHsuZoIUXGC9okLvk2pKfQxCjV86akPub7BZ8= diff --git a/src/Command/InfectionCommand.php b/src/Command/InfectionCommand.php index 4a8cace01..f79fdb1af 100644 --- a/src/Command/InfectionCommand.php +++ b/src/Command/InfectionCommand.php @@ -120,6 +120,12 @@ protected function configure(): void InputOption::VALUE_NONE, 'Show mutations to the console' ) + ->addOption( + 'ci-friendly', + null, + InputOption::VALUE_NONE, + 'Makes the output CI friendly' + ) ->addOption( 'configuration', 'c', diff --git a/src/Process/Builder/SubscriberBuilder.php b/src/Process/Builder/SubscriberBuilder.php index 371e34f57..7a894fb8f 100644 --- a/src/Process/Builder/SubscriberBuilder.php +++ b/src/Process/Builder/SubscriberBuilder.php @@ -41,11 +41,15 @@ use Infection\Console\OutputFormatter\ProgressFormatter; use Infection\Differ\DiffColorizer; use Infection\EventDispatcher\EventDispatcherInterface; +use Infection\EventDispatcher\EventSubscriberInterface; use Infection\Mutant\MetricsCalculator; use Infection\Performance\Listener\PerformanceLoggerSubscriber; use Infection\Performance\Memory\MemoryFormatter; use Infection\Performance\Time\TimeFormatter; use Infection\Performance\Time\Timer; +use Infection\Process\Listener\CiInitialTestsConsoleLoggerSubscriber; +use Infection\Process\Listener\CiMutantCreatingConsoleLoggerSubscriber; +use Infection\Process\Listener\CiMutationGeneratingConsoleLoggerSubscriber; use Infection\Process\Listener\CleanUpAfterMutationTestingFinishedSubscriber; use Infection\Process\Listener\InitialTestsConsoleLoggerSubscriber; use Infection\Process\Listener\MutantCreatingConsoleLoggerSubscriber; @@ -150,9 +154,9 @@ private function getSubscribers( OutputInterface $output ): array { $subscribers = [ - new InitialTestsConsoleLoggerSubscriber($output, $testFrameworkAdapter), - new MutationGeneratingConsoleLoggerSubscriber($output), - new MutantCreatingConsoleLoggerSubscriber($output), + $this->getInitialTestsConsoleLoggerSubscriber($testFrameworkAdapter, $output), + $this->getMutantGeneratingConsoleLoggerSubscriber($output), + $this->getMutantCreatingConsoleLoggerSubscriber($output), new MutationTestingConsoleLoggerSubscriber( $output, $this->getOutputFormatter($output), @@ -199,4 +203,31 @@ private function getOutputFormatter(OutputInterface $output): OutputFormatter throw new \InvalidArgumentException('Incorrect formatter. Possible values: "dot", "progress"'); } + + private function getMutantCreatingConsoleLoggerSubscriber(OutputInterface $output): EventSubscriberInterface + { + if ((bool) $this->input->getOption('ci-friendly')) { + return new CiMutantCreatingConsoleLoggerSubscriber($output); + } + + return new MutantCreatingConsoleLoggerSubscriber($output); + } + + private function getMutantGeneratingConsoleLoggerSubscriber(OutputInterface $output): EventSubscriberInterface + { + if ((bool) $this->input->getOption('ci-friendly')) { + return new CiMutationGeneratingConsoleLoggerSubscriber($output); + } + + return new MutationGeneratingConsoleLoggerSubscriber($output); + } + + private function getInitialTestsConsoleLoggerSubscriber(AbstractTestFrameworkAdapter $testFrameworkAdapter, OutputInterface $output): EventSubscriberInterface + { + if ((bool) $this->input->getOption('ci-friendly')) { + return new CiInitialTestsConsoleLoggerSubscriber($output, $testFrameworkAdapter); + } + + return new InitialTestsConsoleLoggerSubscriber($output, $testFrameworkAdapter); + } } diff --git a/src/Process/Listener/CiInitialTestsConsoleLoggerSubscriber.php b/src/Process/Listener/CiInitialTestsConsoleLoggerSubscriber.php new file mode 100644 index 000000000..b41a89658 --- /dev/null +++ b/src/Process/Listener/CiInitialTestsConsoleLoggerSubscriber.php @@ -0,0 +1,89 @@ +output = $output; + $this->testFrameworkAdapter = $testFrameworkAdapter; + } + + public function getSubscribedEvents(): array + { + return [ + InitialTestSuiteStarted::class => [$this, 'onInitialTestSuiteStarted'], + ]; + } + + public function onInitialTestSuiteStarted(InitialTestSuiteStarted $event): void + { + try { + $version = $this->testFrameworkAdapter->getVersion(); + } catch (\InvalidArgumentException $e) { + $version = 'unknown'; + } + + $this->output->writeln([ + 'Running initial test suite...', + '', + sprintf( + '%s version: %s', + $this->testFrameworkAdapter->getName(), + $version + ), + ]); + } +} diff --git a/src/Process/Listener/CiMutantCreatingConsoleLoggerSubscriber.php b/src/Process/Listener/CiMutantCreatingConsoleLoggerSubscriber.php new file mode 100644 index 000000000..ca7acb38d --- /dev/null +++ b/src/Process/Listener/CiMutantCreatingConsoleLoggerSubscriber.php @@ -0,0 +1,71 @@ +output = $output; + } + + public function getSubscribedEvents(): array + { + return [ + MutantsCreatingStarted::class => [$this, 'onMutantsCreatingStarted'], + ]; + } + + public function onMutantsCreatingStarted(MutantsCreatingStarted $event): void + { + $this->output->writeln([ + '', + sprintf('Creating mutated files and processes: %s', $event->getMutantCount()), + ]); + } +} diff --git a/src/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriber.php b/src/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriber.php new file mode 100644 index 000000000..7ba06c1ac --- /dev/null +++ b/src/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriber.php @@ -0,0 +1,73 @@ +output = $output; + } + + public function getSubscribedEvents(): array + { + return [ + MutationGeneratingStarted::class => [$this, 'onMutationGeneratingStarted'], + ]; + } + + public function onMutationGeneratingStarted(MutationGeneratingStarted $event): void + { + $this->output->writeln([ + '', + 'Generate mutants...', + '', + sprintf('Processing source code files: %s', $event->getMutableFilesCount()), + ]); + } +} diff --git a/tests/Process/Builder/SubscriberBuilderTest.php b/tests/Process/Builder/SubscriberBuilderTest.php index b2955a786..66a34b6be 100644 --- a/tests/Process/Builder/SubscriberBuilderTest.php +++ b/tests/Process/Builder/SubscriberBuilderTest.php @@ -57,10 +57,11 @@ final class SubscriberBuilderTest extends TestCase public function test_it_registers_the_subscribers_when_debugging(): void { $input = $this->createMock(InputInterface::class); - $input->expects($this->exactly(6)) + $input->expects($this->exactly(9)) ->method('getOption') ->will($this->returnValueMap( [ + ['ci-friendly', false], ['formatter', 'progress'], ['show-mutations', true], ['log-verbosity', 'all'], @@ -94,10 +95,11 @@ public function test_it_registers_the_subscribers_when_debugging(): void public function test_it_registers_the_subscribers_when_not_debugging(): void { $input = $this->createMock(InputInterface::class); - $input->expects($this->exactly(6)) + $input->expects($this->exactly(9)) ->method('getOption') ->will($this->returnValueMap( [ + ['ci-friendly', false], ['formatter', 'progress'], ['show-mutations', true], ['log-verbosity', 'all'], @@ -131,10 +133,11 @@ public function test_it_registers_the_subscribers_when_not_debugging(): void public function test_it_throws_an_exception_when_output_formatter_is_invalid(): void { $input = $this->createMock(InputInterface::class); - $input->expects($this->exactly(2)) + $input->expects($this->exactly(5)) ->method('getOption') ->will($this->returnValueMap( [ + ['ci-friendly', false], ['formatter', 'foo'], ['show-mutations', true], ] diff --git a/tests/Process/Listener/CiInitialTestsConsoleLoggerSubscriberTest.php b/tests/Process/Listener/CiInitialTestsConsoleLoggerSubscriberTest.php new file mode 100644 index 000000000..f7fd13d0b --- /dev/null +++ b/tests/Process/Listener/CiInitialTestsConsoleLoggerSubscriberTest.php @@ -0,0 +1,92 @@ +output = $this->createMock(OutputInterface::class); + $this->testFramework = $this->createMock(AbstractTestFrameworkAdapter::class); + } + + public function test_it_reacts_on_mutants_creating_event(): void + { + $this->output->expects($this->once()) + ->method('writeln') + ->with([ + 'Running initial test suite...', + '', + 'PHPUnit version: 6.5.4', + ]); + + $this->testFramework->expects($this->once()) + ->method('getVersion') + ->willReturn('6.5.4'); + + $this->testFramework->expects($this->once()) + ->method('getName') + ->willReturn('PHPUnit'); + + $dispatcher = new EventDispatcher(); + $dispatcher->addSubscriber(new CiInitialTestsConsoleLoggerSubscriber($this->output, $this->testFramework)); + + $dispatcher->dispatch(new InitialTestSuiteStarted()); + } +} diff --git a/tests/Process/Listener/CiMutantCreatingConsoleLoggerSubscriberTest.php b/tests/Process/Listener/CiMutantCreatingConsoleLoggerSubscriberTest.php new file mode 100644 index 000000000..8e26db5f8 --- /dev/null +++ b/tests/Process/Listener/CiMutantCreatingConsoleLoggerSubscriberTest.php @@ -0,0 +1,76 @@ +output = $this->createMock(OutputInterface::class); + } + + public function test_it_reacts_on_mutants_creating_event(): void + { + $this->output->expects($this->once()) + ->method('writeln') + ->with([ + '', + 'Creating mutated files and processes: 123', + ]); + + $dispatcher = new EventDispatcher(); + $dispatcher->addSubscriber(new CiMutantCreatingConsoleLoggerSubscriber($this->output)); + + $dispatcher->dispatch(new MutantsCreatingStarted(123)); + } +} diff --git a/tests/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriberTest.php b/tests/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriberTest.php new file mode 100644 index 000000000..d1fd2b9a2 --- /dev/null +++ b/tests/Process/Listener/CiMutationGeneratingConsoleLoggerSubscriberTest.php @@ -0,0 +1,78 @@ +output = $this->createMock(OutputInterface::class); + } + + public function test_it_reacts_on_mutation_generating_started_event(): void + { + $this->output->expects($this->once()) + ->method('writeln') + ->with([ + '', + 'Generate mutants...', + '', + 'Processing source code files: 123', + ]); + + $dispatcher = new EventDispatcher(); + $dispatcher->addSubscriber(new CiMutationGeneratingConsoleLoggerSubscriber($this->output)); + + $dispatcher->dispatch(new MutationGeneratingStarted(123)); + } +} From 84c0d67fa3ade4c9e39a4a6583afbb737ba98fa1 Mon Sep 17 00:00:00 2001 From: borNfreee Date: Tue, 29 Jan 2019 20:38:33 +0300 Subject: [PATCH 2/3] Rename to --no-progress. Automatically detect CI and skip progress bars --- .ci/travis-functions.sh | 2 +- .travis.yml | 2 +- src/Command/InfectionCommand.php | 4 ++-- src/Process/Builder/SubscriberBuilder.php | 13 ++++++++++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.ci/travis-functions.sh b/.ci/travis-functions.sh index 98a9a1d8b..3a80314b6 100644 --- a/.ci/travis-functions.sh +++ b/.ci/travis-functions.sh @@ -32,4 +32,4 @@ function get-infection-pr-flags() { fi echo $INFECTION_PR_FLAGS; -} \ No newline at end of file +} diff --git a/.travis.yml b/.travis.yml index 2bcf5ac53..86ea08c28 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ sudo: false env: global: - - INFECTION_FLAGS='--threads=4 --min-msi=67 --min-covered-msi=75 --coverage=coverage --log-verbosity=none --ci-friendly' + - INFECTION_FLAGS='--threads=4 --min-msi=67 --min-covered-msi=75 --coverage=coverage --log-verbosity=none' - PHPUNIT_BIN='vendor/bin/phpunit --coverage-clover=clover.xml --coverage-xml=coverage/coverage-xml --log-junit=coverage/phpunit.junit.xml' - secure: KPHUzOeWLeCWzcyPrnrDaR6grVUEXj48KlSQhJiubdkyKtGcvEs+TzZNYa2v+mSZsvrBHez9MRu4itcx05fNrb7/6M23uppv+fENH7tgZi8PXktlEXvD+Iqc9DIaDS1hQKpsnOhOZLlDNQ/kyE6TJAvoBMcbG6RfLqwLP1Abdz11t9Z65SIL7l2YpTjLjgmZUctpEVkivnQ3VQojd3soFTKZ8s9jNhdyUL2F+Rab4wu26Dy+q9xEd5y1tj2242nmVU7U/OD/spTkxRivuUPNM7jEnUvUcdEHd5DIBki702OrSkgsjrxlOlqOWcIRzVZA+A54GiE8qpnLSPN1qbc68ifXhd4lw4zKrE9KfvI8gnnFHtwQP0lhQuwG+j/VtbQRYrb0ufX1sAOUpOIDGMxYrh+Hn6j/nZnBiBh3NRF0u6PLfnAuph5TybylY0cuiGfGOWFf8UG7yz/EH+Br/D5M/IkObU8b9e3YJlUQPcjTi0BSa/+lkLpQMOOVOlQZk+LTVVRjXwSO10JcWhpqwWX74dsa5b2N/XbXOEQldVsYuQZz7re8e5Nwm5dx+B/KF/ohv2GDkQdqAA35ogOAABI3rvGlfOESDeZyGYOiJqBWX+KLKNRQ6l/KRkHNflX5J+0xeRlK4L84n0YwesyEAEFnYrYtQ+/VNd9ZP2+xXyTrePI= - secure: gto1Cg/FEurmKP+JNi7G7MBxJx9KX+WzM9VlLnu0x1Hq+2n8dEgNCBc9gvNrdpPPWHdke23uYXxM3XaKh6f/KXNRmYskJwAUP/jWTwkAc9dIz6qo3ObcS3M6WPnohkjhTJjJJH/dbUknR9gbstTvGsan7JysUnast6uyAhuP81ago0BoiCshTGPa7gZkD4dPPvDrUr70kRzgOd2ZJQZcuoCfL00q4Yu0OkjM9VMBxaBKkL8EE7594aYDjFtGbJuvWmZ36qqtUxzc3ly+G3IHfQVMQqN8+H0VB4ULwE1JOzWMsj5gpJtVeyPY5BTcAOE3je5/+1eq14VVnf3iSgMu3DbF1o/KuMxdes5vDadoZaVQmtLtNHvgu/UDCicBKk3BnLtlQe1bFfEsoSDRr+zCVkO5ypcbERxQzVCGdZdHsXLFZSxdLsEqSqD5ItZe1ZXv4K8bsDDY5rJgjyaiQs/FT/G4dlf61MHqzKtErgsNQ99ilV4iWqHGHnbMISyYdiLWTG8z/nhE34M+08J0gpSDfVrs1pvoUIzhD8KvjlU2QC2IXuE38aXTZm4IeTA7P6vZbUoCCcgOxIRqzS0UX9M1ddOUmy6prc3CGgiEgn6ey/eWmfyRQSbuL07aRH7MEzW4ESAJbdjHsuZoIUXGC9okLvk2pKfQxCjV86akPub7BZ8= diff --git a/src/Command/InfectionCommand.php b/src/Command/InfectionCommand.php index f79fdb1af..fcc82a668 100644 --- a/src/Command/InfectionCommand.php +++ b/src/Command/InfectionCommand.php @@ -121,10 +121,10 @@ protected function configure(): void 'Show mutations to the console' ) ->addOption( - 'ci-friendly', + 'no-progress', null, InputOption::VALUE_NONE, - 'Makes the output CI friendly' + 'Do not output progress bars' ) ->addOption( 'configuration', diff --git a/src/Process/Builder/SubscriberBuilder.php b/src/Process/Builder/SubscriberBuilder.php index 7a894fb8f..e44197b17 100644 --- a/src/Process/Builder/SubscriberBuilder.php +++ b/src/Process/Builder/SubscriberBuilder.php @@ -206,7 +206,7 @@ private function getOutputFormatter(OutputInterface $output): OutputFormatter private function getMutantCreatingConsoleLoggerSubscriber(OutputInterface $output): EventSubscriberInterface { - if ((bool) $this->input->getOption('ci-friendly')) { + if ($this->shouldSkipProgressBars()) { return new CiMutantCreatingConsoleLoggerSubscriber($output); } @@ -215,7 +215,7 @@ private function getMutantCreatingConsoleLoggerSubscriber(OutputInterface $outpu private function getMutantGeneratingConsoleLoggerSubscriber(OutputInterface $output): EventSubscriberInterface { - if ((bool) $this->input->getOption('ci-friendly')) { + if ($this->shouldSkipProgressBars()) { return new CiMutationGeneratingConsoleLoggerSubscriber($output); } @@ -224,10 +224,17 @@ private function getMutantGeneratingConsoleLoggerSubscriber(OutputInterface $out private function getInitialTestsConsoleLoggerSubscriber(AbstractTestFrameworkAdapter $testFrameworkAdapter, OutputInterface $output): EventSubscriberInterface { - if ((bool) $this->input->getOption('ci-friendly')) { + if ($this->shouldSkipProgressBars()) { return new CiInitialTestsConsoleLoggerSubscriber($output, $testFrameworkAdapter); } return new InitialTestsConsoleLoggerSubscriber($output, $testFrameworkAdapter); } + + private function shouldSkipProgressBars(): bool + { + $isCi = getenv('CI') === 'true' || getenv('CONTINUOUS_INTEGRATION') === 'true'; + + return $isCi || $this->input->getOption('no-progress'); + } } From 7d6d2d2e03e126fe1199af878915aabe0f2d0aeb Mon Sep 17 00:00:00 2001 From: borNfreee Date: Tue, 29 Jan 2019 20:52:13 +0300 Subject: [PATCH 3/3] Simplify condition --- src/Process/Builder/SubscriberBuilder.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Process/Builder/SubscriberBuilder.php b/src/Process/Builder/SubscriberBuilder.php index e44197b17..58e1eeaa4 100644 --- a/src/Process/Builder/SubscriberBuilder.php +++ b/src/Process/Builder/SubscriberBuilder.php @@ -233,8 +233,8 @@ private function getInitialTestsConsoleLoggerSubscriber(AbstractTestFrameworkAda private function shouldSkipProgressBars(): bool { - $isCi = getenv('CI') === 'true' || getenv('CONTINUOUS_INTEGRATION') === 'true'; - - return $isCi || $this->input->getOption('no-progress'); + return $this->input->getOption('no-progress') + || getenv('CI') === 'true' + || getenv('CONTINUOUS_INTEGRATION') === 'true'; } }