diff --git a/docker-compose.yml b/docker-compose.yml index 71991376..4951614b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,8 +3,7 @@ version: '3' services: php56: build: - context: . - dockerfile: ./docker/php56/Dockerfile + context: ./docker/php56 working_dir: /var/www/html command: > sh -c " @@ -17,3 +16,19 @@ services: volumes: - .:/var/www/html - ./docker/php56/php.ini:/usr/local/etc/php/php.ini:ro + + dev_tools: + build: + context: ./docker/dev-tools + working_dir: /var/www/html + command: > + sh -c " + chown -R www-data:www-data /var/www/.composer \ + && su-exec www-data composer bin all install -o \ + && echo 'Logs from /var/log/php/error.log:' \ + && touch /var/log/php/error.log \ + && tail -f /var/log/php/error.log + " + volumes: + - .:/var/www/html + - ./docker/php56/php.ini:/usr/local/etc/php/php.ini:ro diff --git a/docker/dev-tools/Dockerfile b/docker/dev-tools/Dockerfile new file mode 100644 index 00000000..452aa5c3 --- /dev/null +++ b/docker/dev-tools/Dockerfile @@ -0,0 +1,18 @@ +FROM php:7.2-cli-alpine + +RUN apk add --no-cache \ + su-exec && \ + docker-php-ext-install -j$(nproc) \ + opcache + +RUN mkdir -p \ + /var/log/php \ + /var/www/.composer \ + && touch /var/log/php/error.log \ + && chown www-data:www-data \ + /var/log/php/error.log \ + /var/www/.composer + +COPY --from=composer:1.8 /usr/bin/composer /usr/bin/composer +ENV COMPOSER_HOME /var/www/.composer +RUN su-exec www-data composer global require hirak/prestissimo -a && rm -rf /var/www/.composer/cache diff --git a/docker/php56/Dockerfile b/docker/php56/Dockerfile index 5bc926d6..4fc7c54a 100644 --- a/docker/php56/Dockerfile +++ b/docker/php56/Dockerfile @@ -3,7 +3,8 @@ FROM php:5.6-cli-alpine RUN apk add --no-cache \ su-exec && \ docker-php-ext-install -j$(nproc) \ - opcache + opcache \ + sysvsem RUN mkdir -p \ /var/log/php \ diff --git a/src/Event.php b/src/Event.php index a701b77c..cd01819d 100644 --- a/src/Event.php +++ b/src/Event.php @@ -12,8 +12,10 @@ use Crunz\Pinger\PingableInterface; use Crunz\Pinger\PingableTrait; use SuperClosure\Serializer; +use Symfony\Component\Lock\Exception\InvalidArgumentException; use Symfony\Component\Lock\Factory; use Symfony\Component\Lock\Lock; +use Symfony\Component\Lock\Store\FlockStore; use Symfony\Component\Lock\StoreInterface; use Symfony\Component\Process\Process; @@ -27,13 +29,6 @@ class Event implements PingableInterface { use PingableTrait; - /** - * Indicates if the command should not overlap itself. - * - * @var bool - */ - public $preventOverlapping = false; - /** * The location that output should be sent to. * @@ -158,6 +153,13 @@ class Event implements PingableInterface 'month' => 4, 'week' => 5, ]; + + /** + * Indicates if the command should not overlap itself. + * + * @var bool + */ + private $preventOverlapping = false; /** @var ClockInterface */ private static $clock; @@ -168,15 +170,10 @@ class Event implements PingableInterface * @var Factory|null */ private $lockFactory; - - /** - * Contains the timestamp of the last lock refresh. - * - * @var int - */ - private $lastLockRefresh = 0; - + /** @var string[] */ private $wholeOutput = []; + /** @var Lock */ + private $lock; /** * Create a new event instance. @@ -754,14 +751,16 @@ public function user($user) */ public function preventOverlapping(StoreInterface $store = null) { + $lockStore = $store ?: $this->createDefaultLockStore(); $this->preventOverlapping = true; - if (null !== $store) { - $this->lockFactory = new Factory($store); - } + $this->lockFactory = new Factory($lockStore); // Skip the event if it's locked (processing) $this->skip(function () { - return $this->isLocked(); + $lock = $this->createLockObject(); + $lock->acquire(); + + return !$lock->isAcquired(); }); // Delete the lock file when the event is completed @@ -1047,57 +1046,6 @@ public function afterCallbacks() return $this->afterCallbacks; } - /** - * Check if another instance of the event is still running. - * - * @return bool - */ - public function isLocked() - { - if (null !== $this->lockFactory) { - $lock = $this->createLockObject(); - - return $lock->isAcquired(); - } - - // If no symfony lock object is given, fall back to file system locks. - $pid = $this->lastPid(); - $hasPid = (null !== $pid); - - // No POSIX on Windows - if ($this->isWindows()) { - return $hasPid; - } - - return ($hasPid && posix_getsid($pid)) ? true : false; - } - - /** - * Get the last process Id of the event. - * - * @return int - */ - public function lastPid() - { - $lock_file = $this->lockFile(); - - return file_exists($lock_file) ? (int) trim(file_get_contents($lock_file)) : null; - } - - /** - * Get the lock file path for the task. - * - * @return string - */ - public function lockFile() - { - if (null !== $this->lockFactory) { - throw new \BadMethodCallException('We are not using file based locking, but instead symfony/lock'); - } - - return rtrim(sys_get_temp_dir(), '/') . '/crunz-' . md5($this->buildCommand()); - } - /** * If this event is prevented from overlapping, this method should be called regularly to refresh the lock. */ @@ -1107,14 +1055,18 @@ public function refreshLock() return; } - if (null === $this->lockFactory) { - // In case of file based locking there is nothing to do. + $lock = $this->createLockObject(); + $remainingLifetime = $lock->getRemainingLifetime(); + + // Lock will never expire + if (null === $remainingLifetime) { + return; } - // Refresh lock every 10s - $lockRefreshNeeded = $this->lastLockRefresh < (time() - 10); + // Refresh 15s before lock expiration + $lockRefreshNeeded = $remainingLifetime < 15; if ($lockRefreshNeeded) { - $this->createLockObject()->refresh(); + $lock->refresh(); } } @@ -1125,15 +1077,16 @@ public function refreshLock() */ protected function createLockObject() { - if (null === $this->lockFactory) { - throw new \BadMethodCallException( - 'No lock factory. Please call preventOverlapping() with lock storage first.' - ); - } + $this->checkLockFactory(); + + if (null === $this->lock) { + $ttl = 30; - $ttl = 30; + $this->lock = $this->lockFactory + ->createLock($this->lockKey(), $ttl); + } - return $this->lockFactory->createLock('crunz-' . md5($this->buildCommand()), $ttl); + return $this->lock; } /** @@ -1141,17 +1094,10 @@ protected function createLockObject() */ protected function releaseLock() { - if (null !== $this->lockFactory) { - $lock = $this->createLockObject(); - $lock->release(); + $this->checkLockFactory(); - return; - } - - $lockfile = $this->lockFile(); - if (file_exists($lockfile)) { - unlink($lockfile); - } + $lock = $this->createLockObject(); + $lock->release(); } /** @@ -1271,14 +1217,53 @@ protected function applyMask($unit) /** * Lock the event. + */ + protected function lock() + { + $lock = $this->createLockObject(); + $lock->acquire(); + } + + /** + * @return FlockStore * - * @param \Crunz\Event $event - * + * @throws Exception\CrunzException + */ + private function createDefaultLockStore() + { + try { + $lockPath = Path::create( + [ + \sys_get_temp_dir(), + '.crunz', + ] + ); + + $store = new FlockStore($lockPath->toString()); + } catch (InvalidArgumentException $exception) { + // Fallback to system temp dir + $lockPath = Path::create([\sys_get_temp_dir()]); + $store = new FlockStore($lockPath->toString()); + } + + return $store; + } + + /** * @return string */ - protected function lock() + private function lockKey() { - file_put_contents($this->lockFile(), $this->process->getPid()); + return 'crunz-' . \md5($this->buildCommand()); + } + + private function checkLockFactory() + { + if (null === $this->lockFactory) { + throw new \BadMethodCallException( + 'No lock factory. Please call preventOverlapping() first.' + ); + } } /** @return ClockInterface */ diff --git a/src/EventRunner.php b/src/EventRunner.php index 35dc7743..107e8ce2 100644 --- a/src/EventRunner.php +++ b/src/EventRunner.php @@ -147,10 +147,14 @@ protected function manageStartedEvents() while ($this->schedules) { foreach ($this->schedules as $scheduleKey => $schedule) { $events = $schedule->events(); + // 10% chance that refresh will be called + $refreshLocks = (\rand(1, 100) <= 10); /** @var Event $event */ foreach ($events as $eventKey => $event) { - $event->refreshLock(); + if ($refreshLocks) { + $event->refreshLock(); + } $proc = $event->getProcess(); if ($proc->isRunning()) { diff --git a/tests/Unit/EventTest.php b/tests/Unit/EventTest.php index c7df1eaa..b6802a66 100644 --- a/tests/Unit/EventTest.php +++ b/tests/Unit/EventTest.php @@ -7,6 +7,8 @@ use Crunz\Tests\TestCase\TestClock; use PHPUnit\Framework\TestCase; use SuperClosure\Serializer; +use Symfony\Component\Lock\Store\SemaphoreStore; +use Symfony\Component\Lock\StoreInterface; class EventTest extends TestCase { @@ -371,6 +373,43 @@ public function wholeOutputCatchesStdoutAndStderr() ); } + /** @test */ + public function taskWillPreventOverlappingWithDefaultStore() + { + $this->assertPreventOverlapping(); + } + + /** @test */ + public function taskWillPreventOverlappingWithSemaphoreStore() + { + if (!\extension_loaded('sysvsem')) { + $this->markTestSkipped('Semaphore extension not installed.'); + } + + $this->assertPreventOverlapping(new SemaphoreStore()); + } + + private function assertPreventOverlapping(StoreInterface $store = null) + { + $event = $this->createPreventOverlappingEvent($store); + $event2 = $this->createPreventOverlappingEvent($store); + + $event->start(); + + $this->assertFalse($event2->isDue(new \DateTimeZone('UTC'))); + } + + private function createPreventOverlappingEvent(StoreInterface $store = null) + { + $command = "php -r 'sleep(2);'"; + + $event = new Event(\uniqid('c', true), $command); + $event->preventOverlapping($store); + $event->everyMinute(); + + return $event; + } + private function setClockNow(\DateTimeImmutable $dateTime) { $testClock = new TestClock($dateTime); diff --git a/tests/Unit/PreventOverlappingTest.php b/tests/Unit/PreventOverlappingTest.php deleted file mode 100644 index 6e90b7b3..00000000 --- a/tests/Unit/PreventOverlappingTest.php +++ /dev/null @@ -1,143 +0,0 @@ -run($command) - ->description('Show PHP version') - ->preventOverlapping() - ->everyMinute(); - - // Exact same event, might come from another schedule:run - $schedule2 = new Schedule(); - $event2 = $schedule2->run($command) - ->description('Show PHP version') - ->preventOverlapping() - ->everyMinute(); - - $eventRunner = new MyEventRunner( - new Invoker(), - $this->createMock(Configuration::class), - $this->createMock(Mailer::class), - $this->createMock(LoggerFactory::class), - $this->createMock(HttpClientInterface::class), - $this->createMock(ConsoleLoggerInterface::class) - ); - - // Both events are due, none is locked yet - $this->assertEquals([$event1], $schedule1->dueEvents(new \DateTimeZone(date_default_timezone_get()))); - $this->assertEquals([$event2], $schedule2->dueEvents(new \DateTimeZone(date_default_timezone_get()))); - - // Start schedule1, so that event1 will be locked - $eventRunner->handle(new NullOutput(), [$schedule1]); - - // Event is locked and therefore not due (even over the boundaries of multiple independent events and schedules) - $this->assertEquals([], $schedule1->dueEvents(new \DateTimeZone(date_default_timezone_get()))); - $this->assertEquals([], $schedule2->dueEvents(new \DateTimeZone(date_default_timezone_get()))); - - // Assert only one process is running - $this->assertTrue($event1->getProcess()->isRunning()); - $this->assertNull($event2->getProcess(), 'Event 2 should not be running'); - - // Assert lock on both events - $this->assertTrue($event1->isLocked()); - $this->assertTrue($event2->isLocked()); - - // Wait until the process finished - $start = time(); - while ($event1->isLocked()) { - // Verify the events are still locked while the process is running - $this->assertEquals([], $schedule1->dueEvents(new \DateTimeZone(date_default_timezone_get()))); - $this->assertEquals([], $schedule2->dueEvents(new \DateTimeZone(date_default_timezone_get()))); - $this->assertTrue($event1->isLocked()); - $this->assertTrue($event2->isLocked()); - - $eventRunner->manageStartedEvents(); - usleep(50000); - - if (time() - $start > 5) { - $this->fail('Lock was not released after 5 seconds, something is wrong here.'); - } - } - - // Assert both locks were removed - $this->assertFalse($event1->isLocked()); - $this->assertFalse($event2->isLocked()); - } - - public function lockDataProvider() - { - // File based lock storage in sys_get_temp_dir() - yield [null]; - - // Symfony lock with file based lock store - yield [new FlockStore()]; - - if (extension_loaded('sysvsem')) { - // Symfony lock with semaphore store - yield [new SemaphoreStore()]; - } - } -} - -class MyEventRunner extends EventRunner -{ - /** - * Manage the running processes. - * - * This is a simplified version that checks whether the processes are still running and returns afterwards. - * - * This adoption is non-blocking / does not wait for all processes to finish, because otherwise we could not test - * the locking in a single threaded manner. - */ - public function manageStartedEvents() - { - foreach ($this->schedules as $scheduleKey => $schedule) { - $events = $schedule->events(); - - /** @var Event $event */ - foreach ($events as $eventKey => $event) { - $proc = $event->getProcess(); - if ($proc->isRunning()) { - continue; - } - - // Dismiss the event after it's finished - $this->invoke($event->afterCallbacks()); - $schedule->dismissEvent($eventKey); - } - - if (!\count($schedule->events())) { - $this->invoke($schedule->afterCallbacks()); - unset($this->schedules[$scheduleKey]); - } - } - } -} diff --git a/vendor-bin/changelog-linker/composer.lock b/vendor-bin/changelog-linker/composer.lock index 5fd87d63..a5481161 100644 --- a/vendor-bin/changelog-linker/composer.lock +++ b/vendor-bin/changelog-linker/composer.lock @@ -124,32 +124,33 @@ }, { "name": "guzzlehttp/psr7", - "version": "1.4.2", + "version": "1.5.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" + "reference": "9f83dded91781a01c63574e387eaa769be769115" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", - "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115", + "reference": "9f83dded91781a01c63574e387eaa769be769115", "shasum": "" }, "require": { "php": ">=5.4.0", - "psr/http-message": "~1.0" + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5" }, "provide": { "psr/http-message-implementation": "1.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.5-dev" } }, "autoload": { @@ -179,13 +180,14 @@ "keywords": [ "http", "message", + "psr-7", "request", "response", "stream", "uri", "url" ], - "time": "2017-03-20T17:10:46+00:00" + "time": "2018-12-04T20:46:45+00:00" }, { "name": "nette/finder", @@ -432,16 +434,16 @@ }, { "name": "psr/log", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", "shasum": "" }, "require": { @@ -475,20 +477,60 @@ "psr", "psr-3" ], - "time": "2016-10-10T12:19:37+00:00" + "time": "2018-11-20T15:27:04+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~3.7.0", + "satooshi/php-coveralls": ">=1.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2016-02-11T07:05:27+00:00" }, { "name": "symfony/config", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238" + "reference": "005d9a083d03f588677d15391a716b1ac9b887c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", - "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238", + "url": "https://api.github.com/repos/symfony/config/zipball/005d9a083d03f588677d15391a716b1ac9b887c0", + "reference": "005d9a083d03f588677d15391a716b1ac9b887c0", "shasum": "" }, "require": { @@ -511,7 +553,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -538,24 +580,25 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:09:42+00:00" + "time": "2018-11-30T22:21:14+00:00" }, { "name": "symfony/console", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "432122af37d8cd52fba1b294b11976e0d20df595" + "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/432122af37d8cd52fba1b294b11976e0d20df595", - "reference": "432122af37d8cd52fba1b294b11976e0d20df595", + "url": "https://api.github.com/repos/symfony/console/zipball/4dff24e5d01e713818805c1862d2e3f901ee7dd0", + "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0", "shasum": "" }, "require": { "php": "^7.1.3", + "symfony/contracts": "^1.0", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -579,7 +622,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -606,20 +649,88 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:30:44+00:00" + "time": "2018-11-27T07:40:44+00:00" + }, + { + "name": "symfony/contracts", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/contracts.git", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\": "" + }, + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A set of abstractions extracted out of the Symfony components", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2018-12-05T08:06:11+00:00" }, { "name": "symfony/debug", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "19090917b848a799cbae4800abf740fe4eb71c1d" + "reference": "e0a2b92ee0b5b934f973d90c2f58e18af109d276" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/19090917b848a799cbae4800abf740fe4eb71c1d", - "reference": "19090917b848a799cbae4800abf740fe4eb71c1d", + "url": "https://api.github.com/repos/symfony/debug/zipball/e0a2b92ee0b5b934f973d90c2f58e18af109d276", + "reference": "e0a2b92ee0b5b934f973d90c2f58e18af109d276", "shasum": "" }, "require": { @@ -635,7 +746,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -662,37 +773,39 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:09:42+00:00" + "time": "2018-11-28T18:24:18+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483" + "reference": "e4adc57a48d3fa7f394edfffa9e954086d7740e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e72ee2c23d952e4c368ee98610fa22b79b89b483", - "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e4adc57a48d3fa7f394edfffa9e954086d7740e5", + "reference": "e4adc57a48d3fa7f394edfffa9e954086d7740e5", "shasum": "" }, "require": { "php": "^7.1.3", - "psr/container": "^1.0" + "psr/container": "^1.0", + "symfony/contracts": "^1.0" }, "conflict": { - "symfony/config": "<4.1.1", + "symfony/config": "<4.2", "symfony/finder": "<3.4", "symfony/proxy-manager-bridge": "<3.4", "symfony/yaml": "<3.4" }, "provide": { - "psr/container-implementation": "1.0" + "psr/container-implementation": "1.0", + "symfony/service-contracts-implementation": "1.0" }, "require-dev": { - "symfony/config": "~4.1", + "symfony/config": "~4.2", "symfony/expression-language": "~3.4|~4.0", "symfony/yaml": "~3.4|~4.0" }, @@ -706,7 +819,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -733,24 +846,25 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-10-31T10:54:16+00:00" + "time": "2018-12-02T15:59:36+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "552541dad078c85d9414b09c041ede488b456cd5" + "reference": "921f49c3158a276d27c0d770a5a347a3b718b328" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/552541dad078c85d9414b09c041ede488b456cd5", - "reference": "552541dad078c85d9414b09c041ede488b456cd5", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/921f49c3158a276d27c0d770a5a347a3b718b328", + "reference": "921f49c3158a276d27c0d770a5a347a3b718b328", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/contracts": "^1.0" }, "conflict": { "symfony/dependency-injection": "<3.4" @@ -769,7 +883,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -796,20 +910,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-10-10T13:52:42+00:00" + "time": "2018-12-01T08:52:38+00:00" }, { "name": "symfony/filesystem", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981" + "reference": "2f4c8b999b3b7cadb2a69390b01af70886753710" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/fd7bd6535beb1f0a0a9e3ee960666d0598546981", - "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/2f4c8b999b3b7cadb2a69390b01af70886753710", + "reference": "2f4c8b999b3b7cadb2a69390b01af70886753710", "shasum": "" }, "require": { @@ -819,7 +933,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -846,20 +960,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-10-30T13:18:25+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/finder", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "1f17195b44543017a9c9b2d437c670627e96ad06" + "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/1f17195b44543017a9c9b2d437c670627e96ad06", - "reference": "1f17195b44543017a9c9b2d437c670627e96ad06", + "url": "https://api.github.com/repos/symfony/finder/zipball/e53d477d7b5c4982d0e1bfd2298dbee63d01441d", + "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d", "shasum": "" }, "require": { @@ -868,7 +982,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -895,20 +1009,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-10-03T08:47:56+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af" + "reference": "1b31f3017fadd8cb05cf2c8aebdbf3b12a943851" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/82d494c1492b0dd24bbc5c2d963fb02eb44491af", - "reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/1b31f3017fadd8cb05cf2c8aebdbf3b12a943851", + "reference": "1b31f3017fadd8cb05cf2c8aebdbf3b12a943851", "shasum": "" }, "require": { @@ -922,7 +1036,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -949,25 +1063,26 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2018-10-31T09:09:42+00:00" + "time": "2018-11-26T10:55:26+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "958be64ab13b65172ad646ef5ae20364c2305fae" + "reference": "b39ceffc0388232c309cbde3a7c3685f2ec0a624" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/958be64ab13b65172ad646ef5ae20364c2305fae", - "reference": "958be64ab13b65172ad646ef5ae20364c2305fae", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/b39ceffc0388232c309cbde3a7c3685f2ec0a624", + "reference": "b39ceffc0388232c309cbde3a7c3685f2ec0a624", "shasum": "" }, "require": { "php": "^7.1.3", "psr/log": "~1.0", + "symfony/contracts": "^1.0.2", "symfony/debug": "~3.4|~4.0", "symfony/event-dispatcher": "~4.1", "symfony/http-foundation": "^4.1.1", @@ -975,7 +1090,8 @@ }, "conflict": { "symfony/config": "<3.4", - "symfony/dependency-injection": "<4.1", + "symfony/dependency-injection": "<4.2", + "symfony/translation": "<4.2", "symfony/var-dumper": "<4.1.1", "twig/twig": "<1.34|<2.4,>=2" }, @@ -988,7 +1104,7 @@ "symfony/config": "~3.4|~4.0", "symfony/console": "~3.4|~4.0", "symfony/css-selector": "~3.4|~4.0", - "symfony/dependency-injection": "^4.1", + "symfony/dependency-injection": "^4.2", "symfony/dom-crawler": "~3.4|~4.0", "symfony/expression-language": "~3.4|~4.0", "symfony/finder": "~3.4|~4.0", @@ -996,7 +1112,7 @@ "symfony/routing": "~3.4|~4.0", "symfony/stopwatch": "~3.4|~4.0", "symfony/templating": "~3.4|~4.0", - "symfony/translation": "~3.4|~4.0", + "symfony/translation": "~4.2", "symfony/var-dumper": "^4.1.1" }, "suggest": { @@ -1009,7 +1125,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1036,7 +1152,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2018-11-03T11:11:23+00:00" + "time": "2018-12-06T17:39:52+00:00" }, { "name": "symfony/polyfill-ctype", @@ -1157,16 +1273,16 @@ }, { "name": "symfony/process", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9" + "reference": "2b341009ccec76837a7f46f59641b431e4d4c2b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/3e83acef94d979b1de946599ef86b3a352abcdc9", - "reference": "3e83acef94d979b1de946599ef86b3a352abcdc9", + "url": "https://api.github.com/repos/symfony/process/zipball/2b341009ccec76837a7f46f59641b431e4d4c2b0", + "reference": "2b341009ccec76837a7f46f59641b431e4d4c2b0", "shasum": "" }, "require": { @@ -1175,7 +1291,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1202,20 +1318,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-10-14T20:48:13+00:00" + "time": "2018-11-20T16:22:05+00:00" }, { "name": "symfony/yaml", - "version": "v4.1.7", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "367e689b2fdc19965be435337b50bc8adf2746c9" + "reference": "c41175c801e3edfda90f32e292619d10c27103d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/367e689b2fdc19965be435337b50bc8adf2746c9", - "reference": "367e689b2fdc19965be435337b50bc8adf2746c9", + "url": "https://api.github.com/repos/symfony/yaml/zipball/c41175c801e3edfda90f32e292619d10c27103d7", + "reference": "c41175c801e3edfda90f32e292619d10c27103d7", "shasum": "" }, "require": { @@ -1234,7 +1350,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1261,20 +1377,20 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2018-10-02T16:36:10+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symplify/changelog-linker", - "version": "v5.2.1", + "version": "v5.2.17", "source": { "type": "git", "url": "https://github.com/Symplify/ChangelogLinker.git", - "reference": "312b5a40918ea87436a2f154533a09ed15382aa6" + "reference": "14724f5d65bddf295bd4a24307990f4dbaab8355" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Symplify/ChangelogLinker/zipball/312b5a40918ea87436a2f154533a09ed15382aa6", - "reference": "312b5a40918ea87436a2f154533a09ed15382aa6", + "url": "https://api.github.com/repos/Symplify/ChangelogLinker/zipball/14724f5d65bddf295bd4a24307990f4dbaab8355", + "reference": "14724f5d65bddf295bd4a24307990f4dbaab8355", "shasum": "" }, "require": { @@ -1284,7 +1400,7 @@ "symfony/console": "^3.4|^4.1", "symfony/http-kernel": "^3.4|^4.1", "symfony/process": "^3.4|^4.1", - "symplify/package-builder": "^5.2", + "symplify/package-builder": "^5.2.17", "thecodingmachine/safe": "^0.1.6" }, "require-dev": { @@ -1309,20 +1425,20 @@ "MIT" ], "description": "Generates beautiful CHANGELOG.md with links to PRs, versions and users grouped in Added/Changed/Fixed/Removed categories.", - "time": "2018-11-12T16:48:23+00:00" + "time": "2018-12-12T11:50:57+00:00" }, { "name": "symplify/package-builder", - "version": "v5.2.1", + "version": "v5.2.17", "source": { "type": "git", "url": "https://github.com/Symplify/PackageBuilder.git", - "reference": "cb07932d8bd05966802201bfceffbdf8b4abc79d" + "reference": "4a5a771e719aeecedea2d1e631a8f6be976c7130" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Symplify/PackageBuilder/zipball/cb07932d8bd05966802201bfceffbdf8b4abc79d", - "reference": "cb07932d8bd05966802201bfceffbdf8b4abc79d", + "url": "https://api.github.com/repos/Symplify/PackageBuilder/zipball/4a5a771e719aeecedea2d1e631a8f6be976c7130", + "reference": "4a5a771e719aeecedea2d1e631a8f6be976c7130", "shasum": "" }, "require": { @@ -1357,7 +1473,7 @@ "MIT" ], "description": "Dependency Injection, Console and Kernel toolkit for Symplify packages.", - "time": "2018-11-09T00:40:00+00:00" + "time": "2018-12-12T11:50:51+00:00" }, { "name": "thecodingmachine/safe", diff --git a/vendor-bin/cs-fixer/composer.lock b/vendor-bin/cs-fixer/composer.lock index 5409cc32..058aec12 100644 --- a/vendor-bin/cs-fixer/composer.lock +++ b/vendor-bin/cs-fixer/composer.lock @@ -70,16 +70,16 @@ }, { "name": "composer/xdebug-handler", - "version": "1.3.0", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c" + "reference": "dc523135366eb68f22268d069ea7749486458562" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/b8e9745fb9b06ea6664d8872c4505fb16df4611c", - "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562", + "reference": "dc523135366eb68f22268d069ea7749486458562", "shasum": "" }, "require": { @@ -110,7 +110,7 @@ "Xdebug", "performance" ], - "time": "2018-08-31T19:07:57+00:00" + "time": "2018-11-29T10:59:02+00:00" }, { "name": "doctrine/annotations", @@ -423,16 +423,16 @@ }, { "name": "psr/log", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", "shasum": "" }, "require": { @@ -466,24 +466,25 @@ "psr", "psr-3" ], - "time": "2016-10-10T12:19:37+00:00" + "time": "2018-11-20T15:27:04+00:00" }, { "name": "symfony/console", - "version": "v4.1.6", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b" + "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/dc7122fe5f6113cfaba3b3de575d31112c9aa60b", - "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b", + "url": "https://api.github.com/repos/symfony/console/zipball/4dff24e5d01e713818805c1862d2e3f901ee7dd0", + "reference": "4dff24e5d01e713818805c1862d2e3f901ee7dd0", "shasum": "" }, "require": { "php": "^7.1.3", + "symfony/contracts": "^1.0", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -507,7 +508,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -534,24 +535,93 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-10-03T08:15:46+00:00" + "time": "2018-11-27T07:40:44+00:00" + }, + { + "name": "symfony/contracts", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/contracts.git", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\": "" + }, + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A set of abstractions extracted out of the Symfony components", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2018-12-05T08:06:11+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.1.6", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e" + "reference": "921f49c3158a276d27c0d770a5a347a3b718b328" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e", - "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/921f49c3158a276d27c0d770a5a347a3b718b328", + "reference": "921f49c3158a276d27c0d770a5a347a3b718b328", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/contracts": "^1.0" }, "conflict": { "symfony/dependency-injection": "<3.4" @@ -570,7 +640,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -597,20 +667,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-07-26T09:10:45+00:00" + "time": "2018-12-01T08:52:38+00:00" }, { "name": "symfony/filesystem", - "version": "v4.1.6", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "596d12b40624055c300c8b619755b748ca5cf0b5" + "reference": "2f4c8b999b3b7cadb2a69390b01af70886753710" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/596d12b40624055c300c8b619755b748ca5cf0b5", - "reference": "596d12b40624055c300c8b619755b748ca5cf0b5", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/2f4c8b999b3b7cadb2a69390b01af70886753710", + "reference": "2f4c8b999b3b7cadb2a69390b01af70886753710", "shasum": "" }, "require": { @@ -620,7 +690,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -647,20 +717,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:40:59+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/finder", - "version": "v4.1.6", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "1f17195b44543017a9c9b2d437c670627e96ad06" + "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/1f17195b44543017a9c9b2d437c670627e96ad06", - "reference": "1f17195b44543017a9c9b2d437c670627e96ad06", + "url": "https://api.github.com/repos/symfony/finder/zipball/e53d477d7b5c4982d0e1bfd2298dbee63d01441d", + "reference": "e53d477d7b5c4982d0e1bfd2298dbee63d01441d", "shasum": "" }, "require": { @@ -669,7 +739,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -696,20 +766,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-10-03T08:47:56+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/options-resolver", - "version": "v4.1.6", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "40f0e40d37c1c8a762334618dea597d64bbb75ff" + "reference": "a9c38e8a3da2c03b3e71fdffa6efb0bda51390ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/40f0e40d37c1c8a762334618dea597d64bbb75ff", - "reference": "40f0e40d37c1c8a762334618dea597d64bbb75ff", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a9c38e8a3da2c03b3e71fdffa6efb0bda51390ba", + "reference": "a9c38e8a3da2c03b3e71fdffa6efb0bda51390ba", "shasum": "" }, "require": { @@ -718,7 +788,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -750,11 +820,11 @@ "configuration", "options" ], - "time": "2018-09-18T12:45:12+00:00" + "time": "2018-11-11T19:52:12+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -812,16 +882,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", - "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", "shasum": "" }, "require": { @@ -867,20 +937,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T13:07:52+00:00" }, { "name": "symfony/polyfill-php70", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934" + "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/1e24b0c4a56d55aaf368763a06c6d1c7d3194934", - "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/6b88000cdd431cd2e940caa2cb569201f3f84224", + "reference": "6b88000cdd431cd2e940caa2cb569201f3f84224", "shasum": "" }, "require": { @@ -926,20 +996,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T06:26:08+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae" + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/95c50420b0baed23852452a7f0c7b527303ed5ae", - "reference": "95c50420b0baed23852452a7f0c7b527303ed5ae", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", "shasum": "" }, "require": { @@ -981,20 +1051,20 @@ "portable", "shim" ], - "time": "2018-08-06T14:22:27+00:00" + "time": "2018-09-21T13:07:52+00:00" }, { "name": "symfony/process", - "version": "v4.1.6", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529" + "reference": "2b341009ccec76837a7f46f59641b431e4d4c2b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ee33c0322a8fee0855afcc11fff81e6b1011b529", - "reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529", + "url": "https://api.github.com/repos/symfony/process/zipball/2b341009ccec76837a7f46f59641b431e4d4c2b0", + "reference": "2b341009ccec76837a7f46f59641b431e4d4c2b0", "shasum": "" }, "require": { @@ -1003,7 +1073,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1030,29 +1100,30 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:40:59+00:00" + "time": "2018-11-20T16:22:05+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.1.6", + "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "5bfc064125b73ff81229e19381ce1c34d3416f4b" + "reference": "ec076716412274e51f8a7ea675d9515e5c311123" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5bfc064125b73ff81229e19381ce1c34d3416f4b", - "reference": "5bfc064125b73ff81229e19381ce1c34d3416f4b", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/ec076716412274e51f8a7ea675d9515e5c311123", + "reference": "ec076716412274e51f8a7ea675d9515e5c311123", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/contracts": "^1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1079,7 +1150,7 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2018-10-02T12:40:59+00:00" + "time": "2018-11-11T19:52:12+00:00" } ], "packages-dev": [],