├── var
└── .gitkeep
├── .gitignore
├── app
├── bootstrap.php
└── routes.php
├── db
└── schema.sql
├── web
└── index.php
├── .scrutinizer.yml
├── cli
├── deploy_test
└── deploy_production
├── src
├── ReleaseRepository.php
├── ReleaseStateWriter.php
├── Deployer.php
├── PdoReleaseRepository.php
└── TopLevelFactory.php
├── .travis.yml
├── tests
├── TestEnvironment.php
├── Integration
│ ├── ReleaseFailureLoggingTest.php
│ └── PdoReleaseRepositoryTest.php
├── EdgeToEdge
│ ├── WebRouteTestCase.php
│ └── DeploymentRouteTest.php
├── Unit
│ └── DeployerTest.php
└── files
│ └── push-payload.json
├── phpunit.xml.dist
├── composer.json
├── README.md
├── phpcs.xml
└── composer.lock
/var/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 | var/
--------------------------------------------------------------------------------
/app/bootstrap.php:
--------------------------------------------------------------------------------
1 | run();
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | build: true
2 | inherit: true
3 |
4 | tools:
5 | external_code_coverage: true
6 | php_code_sniffer: true
7 | php_cpd: true
8 | php_cs_fixer: true
9 | php_loc: true
10 | php_mess_detector: true
11 | php_pdepend: true
12 | php_analyzer: true
13 | sensiolabs_security_checker: true
14 |
15 | filter:
16 | excluded_paths:
17 | - 'vendor/*'
18 |
--------------------------------------------------------------------------------
/cli/deploy_test:
--------------------------------------------------------------------------------
1 | #!/bin/env php
2 | newDeployer( 'master' )->run( $command );
16 | } );
17 |
--------------------------------------------------------------------------------
/cli/deploy_production:
--------------------------------------------------------------------------------
1 | #!/bin/env php
2 | newDeployer( 'production' )->run( $command );
16 | } );
17 |
--------------------------------------------------------------------------------
/src/ReleaseRepository.php:
--------------------------------------------------------------------------------
1 |
8 | */
9 | interface ReleaseRepository {
10 |
11 | public function hasUndeployedReleases(): bool;
12 |
13 | public function deploymentInProcess(): bool;
14 |
15 | public function getLatestReleaseId(): string;
16 |
17 | public function markDeploymentAsStarted( string $refId, string $now = '' );
18 |
19 | public function markDeploymentAsFinished( string $refId, string $now = '' );
20 |
21 | public function markDeploymentAsFailed( string $refId, string $now = '' );
22 | }
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | matrix:
4 | include:
5 | - php: 7.1
6 | env: DB=sqlite
7 | fast_finish: true
8 |
9 | sudo: false
10 |
11 | install: travis_retry composer install
12 |
13 | script: composer ci
14 |
15 | after_success:
16 | - if [[ "`phpenv version-name`" != "7.1" ]]; then exit 0; fi
17 | - vendor/bin/phpunit --coverage-clover coverage.clover
18 | - wget https://scrutinizer-ci.com/ocular.phar
19 | - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
20 |
21 | cache:
22 | directories:
23 | - "$HOME/.composer/cache"
24 |
25 | notifications:
26 | email:
27 | on_success: change
28 | on_failure: always
29 |
--------------------------------------------------------------------------------
/src/ReleaseStateWriter.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | class ReleaseStateWriter {
12 |
13 | private $db;
14 |
15 | public function __construct( \PDO $db ) {
16 | $this->db = $db;
17 | }
18 |
19 | public function addRelease( string $branchName, string $refId, $now = '' ) {
20 | $stmt = $this->db->prepare( 'INSERT INTO releases VALUES( :refId, :branchName, :timestampAdded, NULL, NULL, 0 )' );
21 | $stmt->execute( [
22 | 'branchName' => $branchName,
23 | 'refId' => $refId,
24 | 'timestampAdded' => $now ?: date( DATE_ISO8601 )
25 | ] );
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/tests/TestEnvironment.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | class TestEnvironment {
12 |
13 | public static function newInstance(): self {
14 | $instance = new self( 'sqlite::memory:' );
15 |
16 | $instance->factory->getPdo()->exec( file_get_contents( __DIR__ .'/../db/schema.sql' ) );
17 |
18 | return $instance;
19 | }
20 |
21 | private $factory;
22 |
23 | private function __construct( string $dbDsn ) {
24 | $this->factory = new TopLevelFactory( $dbDsn );
25 | }
26 |
27 | public function getFactory(): TopLevelFactory {
28 | return $this->factory;
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 | tests
17 |
18 |
19 |
20 |
21 | src
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wmde/fundraising-github-webhook",
3 | "description": "Run actions for github webhooks",
4 | "license": "GPL-2.0+",
5 | "require": {
6 | "php": ">=7.1",
7 | "silex/silex": "~2.0",
8 | "symfony/process": "^3.1",
9 | "psr/log": "~1.0",
10 | "monolog/monolog": "~1.21"
11 | },
12 | "require-dev": {
13 | "phpunit/phpunit": "^6.1",
14 | "wmde/psr-log-test-doubles": "^2.1",
15 | "symfony/browser-kit": "^3.1",
16 |
17 | "squizlabs/php_codesniffer": "~2.9",
18 | "mediawiki/mediawiki-codesniffer": "~0.8.0"
19 | },
20 | "autoload": {
21 | "psr-4": {
22 | "WMDE\\Fundraising\\Deployment\\": "src/"
23 | }
24 | },
25 | "autoload-dev": {
26 | "psr-4": {
27 | "WMDE\\Fundraising\\Deployment\\Tests\\": "tests/"
28 | }
29 | },
30 | "scripts": {
31 | "ci": [
32 | "@test",
33 | "@cs"
34 | ],
35 | "test": [
36 | "composer validate --no-interaction",
37 | "vendor/bin/phpunit"
38 | ],
39 | "cs": [
40 | "@phpcs"
41 | ],
42 | "phpcs": [
43 | "vendor/bin/phpcs --standard=phpcs.xml"
44 | ]
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WMDE GitHub webhooks
2 |
3 | [](http://travis-ci.org/wmde/github-webhooks)
4 | [](https://scrutinizer-ci.com/g/wmde/github-webhooks/?branch=master)
5 | [](https://scrutinizer-ci.com/g/wmde/github-webhooks/?branch=master)
6 |
7 | Continuous deployment for the WMDE fundraising projects.
8 |
9 | At present only the master and production branches of the FundraisingFrontend application are supported.
10 |
11 | ## High level workflow
12 |
13 | * The application exposes a `/deploy` endpoint which gets called by GitHub webhooks.
14 | * The `/deploy` endpoint saves the data it got, when relevant, into a database table.
15 | * Something (i.e. Cron) invokes one of the deployment scripts in `/cli`
16 | * The deployment script checks if there is something that needs deploying,
17 | and if so, executes an (Ansible) command that takes care of deployment.
18 |
19 | ## Running the tests
20 |
21 | For tests only
22 |
23 | composer test
24 |
25 | For style checks only
26 |
27 | composer cs
28 |
29 | For a full CI run
30 |
31 | composer ci
--------------------------------------------------------------------------------
/tests/Integration/ReleaseFailureLoggingTest.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | class ReleaseFailureLoggingTest extends TestCase {
17 |
18 | const BRANCH_NAME = 'master';
19 |
20 | public function testWhenDeploymentFails_loggerGetsAlerted() {
21 | $loggerSpy = new LoggerSpy();
22 |
23 | $factory = TestEnvironment::newInstance()->getFactory();
24 | $factory->setLogger( $loggerSpy );
25 |
26 | $this->insertRelease( $factory );
27 |
28 | $command = new Process( 'cd plaintext-passwords/' );
29 |
30 | $factory->newDeployer( self::BRANCH_NAME )->run( $command );
31 |
32 | $this->assertNotEmpty( $loggerSpy->getLogCalls() );
33 | $this->assertSame( LogLevel::ALERT, $loggerSpy->getLogCalls()->getFirstCall()->getLevel() );
34 | }
35 |
36 | private function insertRelease( TopLevelFactory $factory ) {
37 | $factory->getReleaseStateWriter()->addRelease( self::BRANCH_NAME, 'deadbeef' );
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/app/routes.php:
--------------------------------------------------------------------------------
1 | post( '/deploy', function ( Request $request ) use ( $topLevelFactory ) {
12 | if ( !$request->headers->has( 'X-GitHub-Event' ) ) {
13 | return new Response( 'Bad request - X-GitHub-Event header missing', Response::HTTP_BAD_REQUEST );
14 | }
15 |
16 | if ( $request->headers->get( 'X-GitHub-Event' ) !== 'push' ) {
17 | return new Response( 'Unsupported event.', Response::HTTP_NOT_IMPLEMENTED );
18 | }
19 |
20 | $payload = json_decode( $request->getContent() );
21 |
22 | if ( !$payload ) {
23 | return new Response( 'Bad request - Could not decode payload', Response::HTTP_BAD_REQUEST );
24 | }
25 |
26 | if ( !empty( $payload->repository->full_name ) &&
27 | !empty( $payload->ref ) &&
28 | $payload->repository->full_name === 'wmde/FundraisingFrontend' &&
29 | in_array( $payload->ref, [ 'refs/heads/master', 'refs/heads/production' ] ) ) {
30 | $branchName = str_replace( 'refs/heads/', '', $payload->ref );
31 |
32 | $topLevelFactory->getReleaseStateWriter()->addRelease( $branchName, $payload->after );
33 | }
34 |
35 | return new Response( 'Ok' );
36 | } );
--------------------------------------------------------------------------------
/src/Deployer.php:
--------------------------------------------------------------------------------
1 |
12 | */
13 | class Deployer {
14 |
15 | private $releaseRepository;
16 | private $onDeploymentFailed;
17 |
18 | public function __construct( ReleaseRepository $releaseRepository, callable $onDeploymentFailed = null ) {
19 | $this->releaseRepository = $releaseRepository;
20 | $this->onDeploymentFailed = $onDeploymentFailed;
21 | }
22 |
23 | public function run( Process $deployCommand ) {
24 | if ( !$this->releaseRepository->hasUndeployedReleases() || $this->releaseRepository->deploymentInProcess() ) {
25 | return;
26 | }
27 |
28 | $latestReleaseId = $this->releaseRepository->getLatestReleaseId();
29 | $this->releaseRepository->markDeploymentAsStarted( $latestReleaseId );
30 |
31 | $deployCommand->run();
32 |
33 | if ( $deployCommand->isSuccessful() ) {
34 | $this->releaseRepository->markDeploymentAsFinished( $latestReleaseId );
35 | } else {
36 | $this->releaseRepository->markDeploymentAsFailed( $latestReleaseId );
37 |
38 | if ( is_callable( $this->onDeploymentFailed ) ) {
39 | call_user_func( $this->onDeploymentFailed, $latestReleaseId, $deployCommand->getErrorOutput() );
40 | }
41 | }
42 |
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/tests/EdgeToEdge/WebRouteTestCase.php:
--------------------------------------------------------------------------------
1 | getFactory();
30 |
31 | $app = $this->createApplication( $debug, $topLevelFactory );
32 |
33 | if ( is_callable( $onAppCreated ) ) {
34 | call_user_func( $onAppCreated, $topLevelFactory, $app );
35 | }
36 |
37 | return new Client( $app );
38 | }
39 |
40 | private function createApplication( bool $debug, TopLevelFactory $topLevelFactory ) : Application {
41 | $app = require __DIR__ . ' /../../app/bootstrap.php';
42 |
43 | require __DIR__ . ' /../../app/routes.php';
44 |
45 | if ( $debug ) {
46 | $app['debug'] = true;
47 | unset( $app['exception_handler'] );
48 | }
49 |
50 | return $app;
51 | }
52 |
53 | protected function assert404( Response $response ) {
54 | $this->assertSame( 404, $response->getStatusCode() );
55 | }
56 |
57 | }
--------------------------------------------------------------------------------
/tests/EdgeToEdge/DeploymentRouteTest.php:
--------------------------------------------------------------------------------
1 | createClient();
13 | $client->request( 'POST', '/deploy' );
14 | $this->assertSame( Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode() );
15 | }
16 |
17 | public function testGivenWrongGithubEvent_requestIsRejected() {
18 | $client = $this->createClient();
19 | $client->request( 'POST', '/deploy', [], [], [ 'HTTP_X-GitHub-Event' => 'dummy' ] );
20 | $this->assertSame( Response::HTTP_NOT_IMPLEMENTED, $client->getResponse()->getStatusCode() );
21 | }
22 |
23 | public function testGivenInvalidJsonContent_requestIsRejected() {
24 | $client = $this->createClient();
25 | $client->request( 'POST', '/deploy', [], [], $this->getValidHeaders(), '~=[,,_,,]:3' );
26 | $this->assertSame( Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode() );
27 | }
28 |
29 | public function testGivenAValidPayload_aReleaseIsCreated() {
30 | $client = $this->createClient( function ( TopLevelFactory $factory ) {
31 | $releaseStateWriter = $this->getMockBuilder( ReleaseStateWriter::class )->disableOriginalConstructor()->getMock();
32 | $releaseStateWriter->expects( $this->once() )
33 | ->method( 'addRelease' )
34 | ->with( 'master', '0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c' );
35 |
36 | $factory->setReleaseStateWriter( $releaseStateWriter );
37 | } );
38 |
39 | $client->request( 'POST', '/deploy', [], [], $this->getValidHeaders(), $this->getValidPayload() );
40 | $this->assertTrue( $client->getResponse()->isOk() );
41 | }
42 |
43 | public function testGivenADifferentRepositoryName_noReleaseIsCreated() {
44 | $client = $this->createClient( function ( TopLevelFactory $factory ) {
45 | $releaseStateWriter = $this->getMockBuilder( ReleaseStateWriter::class )->disableOriginalConstructor()->getMock();
46 | $releaseStateWriter->expects( $this->never() )
47 | ->method( 'addRelease' );
48 |
49 | $factory->setReleaseStateWriter( $releaseStateWriter );
50 | } );
51 |
52 | $client->request( 'POST', '/deploy', [], [], $this->getValidHeaders(), $this->getPayloadWithDifferentRepositoryName() );
53 | $this->assertTrue( $client->getResponse()->isOk() );
54 | }
55 |
56 | private function getValidHeaders() {
57 | return [ 'HTTP_X-GitHub-Event' => 'push' ];
58 | }
59 |
60 | private function getValidPayload() {
61 | return file_get_contents( __DIR__ . '/../files/push-payload.json' );
62 | }
63 |
64 | private function getPayloadWithDifferentRepositoryName() {
65 | return str_replace( 'wmde/FundraisingFrontend', 'wmde/FundraisingBackend', $this->getValidPayload() );
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/src/PdoReleaseRepository.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | class PdoReleaseRepository implements ReleaseRepository {
12 |
13 | private $db;
14 | private $branchName;
15 |
16 | public function __construct( \PDO $db, string $branchName ) {
17 | $this->db = $db;
18 | $this->branchName = $branchName;
19 | }
20 |
21 | public function hasUndeployedReleases(): bool {
22 | $stmt = $this->db->prepare( 'SELECT COUNT(*) FROM releases WHERE branch = :branchName AND ts_ended IS NULL AND ts_started IS NULL' );
23 | $stmt->execute( [ 'branchName' => $this->branchName ] );
24 | return $stmt->fetchColumn() > 0;
25 | }
26 |
27 | public function deploymentInProcess(): bool {
28 | $stmt = $this->db->prepare( 'SELECT COUNT(*) FROM releases WHERE branch = :branchName AND ts_ended IS NULL AND ts_started IS NOT NULL' );
29 | $stmt->execute( [ 'branchName' => $this->branchName ] );
30 | return $stmt->fetchColumn() > 0;
31 | }
32 |
33 | public function getLatestReleaseId(): string {
34 | $stmt = $this->db->prepare(
35 | 'SELECT refid FROM releases WHERE ts_ended IS NULL AND ts_started IS NULL AND branch = :branchName ORDER BY ts_added DESC LIMIT 1'
36 | );
37 | $stmt->execute( [ 'branchName' => $this->branchName ] );
38 | return $stmt->fetchColumn();
39 | }
40 |
41 | public function markDeploymentAsStarted( string $refId, string $now = '' ) {
42 | $stmt = $this->db->prepare( 'UPDATE releases SET ts_started = :timestampStarted WHERE refid = :refId' );
43 | $stmt->execute( [
44 | 'refId' => $refId,
45 | 'timestampStarted' => $now ?: date( DATE_ISO8601 )
46 | ] );
47 | }
48 |
49 | public function markDeploymentAsFinished( string $refId, string $now = '' ) {
50 | $stmt = $this->db->prepare( 'UPDATE releases SET ts_ended = :timestampEnded WHERE refid = :refId' );
51 | $stmt->execute( [
52 | 'refId' => $refId,
53 | 'timestampEnded' => $now ?: date( DATE_ISO8601 )
54 | ] );
55 | $this->updateOlderReleases( $refId );
56 | }
57 |
58 | public function markDeploymentAsFailed( string $refId, string $now = '' ) {
59 | $stmt = $this->db->prepare( 'UPDATE releases SET num_tries = num_tries + 1, ts_started = NULL, ts_ended = NULL WHERE refid = :refId' );
60 | $stmt->execute( [
61 | 'refId' => $refId,
62 | ] );
63 | }
64 |
65 | private function updateOlderReleases( string $refId ) {
66 | $stmt = $this->db->prepare( 'SELECT * FROM releases WHERE refid = :refId' );
67 | $stmt->execute( [ 'refId' => $refId ] );
68 | $row = $stmt->fetch();
69 |
70 | $stmt = $this->db->prepare(
71 | 'UPDATE releases SET ts_started = :timestampStarted, ts_ended = :timestampEnded ' .
72 | 'WHERE ts_started IS NULL AND ts_ended IS NULL AND branch = :branchName AND ts_added < :timestampAdded'
73 | );
74 | $stmt->execute( [
75 | 'branchName' => $row['branch'],
76 | 'timestampAdded' => $row['ts_added'],
77 | 'timestampStarted' => $row['ts_started'],
78 | 'timestampEnded' => $row['ts_ended'],
79 | ] );
80 | }
81 | }
--------------------------------------------------------------------------------
/src/TopLevelFactory.php:
--------------------------------------------------------------------------------
1 |
18 | */
19 | class TopLevelFactory {
20 |
21 | public static function newFromConfig(): self {
22 | return new self( self::getVarPath() . '/releases.sqlite' );
23 | }
24 |
25 | private $dbDsn;
26 |
27 | /**
28 | * @var LoggerInterface
29 | */
30 | private $logger;
31 |
32 | /**
33 | * @var \PDO|null
34 | */
35 | private $pdo = null;
36 |
37 | /**
38 | * @var ReleaseStateWriter|null
39 | */
40 | private $releaseStateWriter = null;
41 |
42 | public function __construct( string $dbDsn ) {
43 | $this->dbDsn = $dbDsn;
44 | $this->logger = $this->newDefaultLogger();
45 | }
46 |
47 | private function newDefaultLogger(): LoggerInterface {
48 | $logger = new Logger( 'Deployment logger' );
49 |
50 | $streamHandler = new StreamHandler(
51 | $this->getLoggingPath() . '/error-debug.log'
52 | );
53 |
54 | $fingersCrossedHandler = new FingersCrossedHandler( $streamHandler );
55 | $streamHandler->setFormatter( new LineFormatter( LineFormatter::SIMPLE_FORMAT ) );
56 | $logger->pushHandler( $fingersCrossedHandler );
57 |
58 | $errorHandler = new StreamHandler(
59 | $this->getLoggingPath() . '/error.log',
60 | Logger::ERROR
61 | );
62 |
63 | $errorHandler->setFormatter( new JsonFormatter() );
64 | $logger->pushHandler( $errorHandler );
65 |
66 | return $logger;
67 | }
68 |
69 | private function getLoggingPath(): string {
70 | return self::getVarPath() . '/log';
71 | }
72 |
73 | private static function getVarPath(): string {
74 | return __DIR__ . '/../var';
75 | }
76 |
77 | public function newDeployer( string $branchName ): Deployer {
78 | return new Deployer(
79 | $this->newReleaseRepository( $branchName ),
80 | function( string $releaseId, string $errorText ) {
81 | $this->logger->alert(
82 | 'Deployment failed',
83 | [
84 | 'Release ID' => $releaseId,
85 | 'Command error output' => $errorText,
86 | ]
87 | );
88 | }
89 | );
90 | }
91 |
92 | private function newReleaseRepository( string $branchName ): ReleaseRepository {
93 | return new PdoReleaseRepository( $this->getPdo(), $branchName );
94 | }
95 |
96 | public function getPdo(): \PDO {
97 | if ( $this->pdo === null ) {
98 | $this->pdo = new \PDO( $this->dbDsn );
99 | }
100 |
101 | return $this->pdo;
102 | }
103 |
104 | public function getReleaseStateWriter(): ReleaseStateWriter {
105 | if ( $this->releaseStateWriter === null ) {
106 | $this->releaseStateWriter = new ReleaseStateWriter( $this->getPdo() );
107 | }
108 |
109 | return $this->releaseStateWriter;
110 | }
111 |
112 | public function setReleaseStateWriter( ReleaseStateWriter $releaseStateWriter ) {
113 | $this->releaseStateWriter = $releaseStateWriter;
114 | }
115 |
116 | public function setLogger( LoggerInterface $logger ) {
117 | $this->logger = $logger;
118 | }
119 |
120 | }
--------------------------------------------------------------------------------
/tests/Unit/DeployerTest.php:
--------------------------------------------------------------------------------
1 | createMock( ReleaseRepository::class );
17 | $releaseState->method( 'hasUndeployedReleases' )->willReturn( false );
18 |
19 | $process = $this->createMock( Process::class );
20 | $process->expects( $this->never() )
21 | ->method( 'run' );
22 |
23 | $deployer = new Deployer( $releaseState );
24 | $deployer->run( $process );
25 | }
26 |
27 | public function testGivenReleaseForBranch_deployCommandIsExecuted() {
28 | $releaseState = $this->createDeployableReleaseState();
29 |
30 | $process = $this->createMock( Process::class );
31 | $process->expects( $this->once() )
32 | ->method( 'run' );
33 |
34 | $deployer = new Deployer( $releaseState );
35 | $deployer->run( $process );
36 | }
37 |
38 | public function testGivenReleaseInDeployment_deployCommandIsNotCalled() {
39 | $releaseState = $this->createMock( ReleaseRepository::class );
40 | $releaseState->method( 'hasUndeployedReleases' )->willReturn( true );
41 | $releaseState->method( 'deploymentInProcess' )->willReturn( true );
42 |
43 | $process = $this->createMock( Process::class );
44 | $process->expects( $this->never() )
45 | ->method( 'run' );
46 |
47 | $deployer = new Deployer( $releaseState );
48 | $deployer->run( $process );
49 | }
50 |
51 | public function testDeploymentWillBeStartedAndEnded() {
52 | $releaseState = $this->createDeployableReleaseState();
53 |
54 | $releaseState->expects( $this->once() )
55 | ->method( 'markDeploymentAsStarted' )
56 | ->with( $this->equalTo( self::RELEASE_ID ) );
57 | $releaseState->expects( $this->once() )
58 | ->method( 'markDeploymentAsFinished' )
59 | ->with( $this->equalTo( self::RELEASE_ID ) );
60 |
61 | $deployer = new Deployer( $releaseState );
62 | $deployer->run( $this->newSucceedingDeployProcess() );
63 | }
64 |
65 | private function newSucceedingDeployProcess(): Process {
66 | $process = $this->createMock( Process::class );
67 | $process->method( 'isSuccessful' )->willReturn( true );
68 | return $process;
69 | }
70 |
71 | public function testWhenDeployProcessFails_releaseIsMarkedAsFailed() {
72 | $releaseState = $this->createDeployableReleaseState();
73 |
74 | $releaseState->expects( $this->once() )
75 | ->method( 'markDeploymentAsFailed' )
76 | ->with( $this->equalTo( self::RELEASE_ID ) );
77 |
78 | $deployer = new Deployer( $releaseState );
79 | $deployer->run( $this->newFailingDeployProcess() );
80 | }
81 |
82 | private function newFailingDeployProcess(): Process {
83 | $process = $this->createMock( Process::class );
84 |
85 | $process->method( 'isSuccessful' )->willReturn( false );
86 | $process->method( 'getErrorOutput' )->willReturn( self::PROCESS_ERROR_MESSAGE );
87 |
88 | return $process;
89 | }
90 |
91 | /**
92 | * @return ReleaseRepository|\PHPUnit_Framework_MockObject_MockObject
93 | */
94 | private function createDeployableReleaseState() {
95 | $releaseState = $this->createMock( ReleaseRepository::class );
96 | $releaseState->method( 'hasUndeployedReleases' )->willReturn( true );
97 | $releaseState->method( 'deploymentInProcess' )->willReturn( false );
98 | $releaseState->method( 'getLatestReleaseId' )->willReturn( self::RELEASE_ID );
99 | return $releaseState;
100 | }
101 |
102 | public function testWhenDeploymentFails_onDeploymentFailedCallbackGetsCalled() {
103 | $argumentsPassedToCallback = null;
104 |
105 | $onDeploymentFailedCallback = function() use ( &$argumentsPassedToCallback ) {
106 | $argumentsPassedToCallback = func_get_args();
107 | };
108 |
109 | $deployer = new Deployer( $this->createDeployableReleaseState(), $onDeploymentFailedCallback );
110 | $deployer->run( $this->newFailingDeployProcess() );
111 |
112 | $this->assertSame(
113 | [ self::RELEASE_ID, self::PROCESS_ERROR_MESSAGE ],
114 | $argumentsPassedToCallback
115 | );
116 | }
117 |
118 | public function testWhenDeploymentSucceeds_onDeploymentFailedCallbackDoesNotGetCalled() {
119 | $deployer = new Deployer(
120 | $this->createDeployableReleaseState(),
121 | function() {
122 | $this->fail( 'Should not have been called' );
123 | }
124 | );
125 |
126 | $deployer->run( $this->newSucceedingDeployProcess() );
127 |
128 | $this->assertTrue( (bool)'Sebastian does not like this' );
129 | }
130 |
131 | }
132 |
--------------------------------------------------------------------------------
/phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | app/
8 | cli/
9 | src/
10 | tests/
11 | web/
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | 0
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | 0
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | 0
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 | 0
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/tests/Integration/PdoReleaseRepositoryTest.php:
--------------------------------------------------------------------------------
1 | getFactory();
29 | $factory->getPdo()->setAttribute( \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION );
30 |
31 | $this->db = $factory->getPdo();
32 | $this->releaseStateWriter = $factory->getReleaseStateWriter();
33 | }
34 |
35 | public function testGivenNewRelaseState_itHasNoUndeployedReleases() {
36 | $releaseState = new PdoReleaseRepository( $this->db, self::BRANCH_NAME );
37 | $this->assertFalse( $releaseState->hasUndeployedReleases() );
38 | }
39 |
40 | public function testWhenAddingARelease_itIsUndeployed() {
41 | $releaseState = new PdoReleaseRepository( $this->db, self::BRANCH_NAME );
42 | $this->insertFirstRelease();
43 |
44 | $this->assertTrue( $releaseState->hasUndeployedReleases() );
45 | }
46 |
47 | public function testWhenAddingARelease_deploymentInProcessReturnsFalse() {
48 | $releaseState = new PdoReleaseRepository( $this->db, self::BRANCH_NAME );
49 | $this->insertFirstRelease();
50 |
51 | $this->assertFalse( $releaseState->deploymentInProcess() );
52 | }
53 |
54 | public function testGivenSeveralReleases_getLatestReleasesReturnsTheMostRecent() {
55 | $releaseState = new PdoReleaseRepository( $this->db, self::BRANCH_NAME );
56 | $this->insertThreeReleases();
57 |
58 | $this->assertEquals( self::THIRD_RELEASE, $releaseState->getLatestReleaseId() );
59 | }
60 |
61 | public function testWhenAReleaseIsMarkedForDeployment_deploymentInProcessReturnsTrue() {
62 | $releaseState = new PdoReleaseRepository( $this->db, self::BRANCH_NAME );
63 | $this->insertFirstRelease();
64 |
65 | $releaseState->markDeploymentAsStarted( self::FIRST_RELEASE );
66 | $this->assertTrue( $releaseState->deploymentInProcess() );
67 | }
68 |
69 | public function testWhenAddingAndDeployingARelease_itIsNotUndeployed() {
70 | $releaseState = new PdoReleaseRepository( $this->db, self::BRANCH_NAME );
71 | $this->insertFirstRelease();
72 | $releaseState->markDeploymentAsStarted( self::FIRST_RELEASE );
73 |
74 | $this->assertFalse( $releaseState->hasUndeployedReleases() );
75 | }
76 |
77 | public function testWhenEndingADeployment_deploymentInProcessReturnsFalse() {
78 | $releaseState = new PdoReleaseRepository( $this->db, self::BRANCH_NAME );
79 | $this->insertFirstRelease();
80 | $releaseState->markDeploymentAsStarted( self::FIRST_RELEASE );
81 | $releaseState->markDeploymentAsFinished( self::FIRST_RELEASE );
82 |
83 | $this->assertFalse( $releaseState->deploymentInProcess() );
84 | $this->assertFalse( $releaseState->hasUndeployedReleases() );
85 | }
86 |
87 | public function testWhenEndingADeployment_previousUndeployedReleasesAreMarkedAsEnded() {
88 | $releaseState = new PdoReleaseRepository( $this->db, self::BRANCH_NAME );
89 | $this->insertThreeReleases();
90 | $releaseState->markDeploymentAsStarted( self::THIRD_RELEASE );
91 | $releaseState->markDeploymentAsFinished( self::THIRD_RELEASE );
92 |
93 | $this->assertFalse( $releaseState->deploymentInProcess() );
94 | $this->assertFalse( $releaseState->hasUndeployedReleases() );
95 | }
96 |
97 | public function testWhenEndingADeployment_subsequentReleasesAreNotTouched() {
98 | $releaseState = new PdoReleaseRepository( $this->db, self::BRANCH_NAME );
99 | $this->insertThreeReleases();
100 | $releaseState->markDeploymentAsStarted( self::SECOND_RELEASE );
101 | $releaseState->markDeploymentAsFinished( self::SECOND_RELEASE );
102 |
103 | $this->assertFalse( $releaseState->deploymentInProcess() );
104 | $this->assertTrue( $releaseState->hasUndeployedReleases() );
105 | $this->assertEquals( self::THIRD_RELEASE, $releaseState->getLatestReleaseId() );
106 | }
107 |
108 | public function testWhenMarkingADeploymentAsFailed_ItCanBeDeployedAgain() {
109 | $releaseState = new PdoReleaseRepository( $this->db, self::BRANCH_NAME );
110 | $this->insertFirstRelease();
111 | $releaseState->markDeploymentAsStarted( self::FIRST_RELEASE );
112 | $releaseState->markDeploymentAsFailed( self::FIRST_RELEASE );
113 |
114 | $this->assertFalse( $releaseState->deploymentInProcess() );
115 | $this->assertTrue( $releaseState->hasUndeployedReleases() );
116 | }
117 |
118 | private function insertFirstRelease() {
119 | $this->releaseStateWriter->addRelease( self::BRANCH_NAME, self::FIRST_RELEASE );
120 | }
121 |
122 | private function insertThreeReleases() {
123 | $this->releaseStateWriter->addRelease( self::BRANCH_NAME, self::FIRST_RELEASE, '2016-01-02 09:00:00' );
124 | $this->releaseStateWriter->addRelease( self::BRANCH_NAME, self::SECOND_RELEASE, '2016-01-02 10:00:00' );
125 | $this->releaseStateWriter->addRelease( self::BRANCH_NAME, self::THIRD_RELEASE, '2016-01-02 11:00:00' );
126 | }
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/tests/files/push-payload.json:
--------------------------------------------------------------------------------
1 | {
2 | "ref": "refs/heads/master",
3 | "before": "9049f1265b7d61be4a8904a9a27120d2064dab3b",
4 | "after": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c",
5 | "created": false,
6 | "deleted": false,
7 | "forced": false,
8 | "base_ref": null,
9 | "compare": "https://github.com/wmde/FundraisingFrontend/compare/9049f1265b7d...0d1a26e67d8f",
10 | "commits": [
11 | {
12 | "id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c",
13 | "tree_id": "f9d2a07e9488b91af2641b26b9407fe22a451433",
14 | "distinct": true,
15 | "message": "Update README.md",
16 | "timestamp": "2015-05-05T19:40:15-04:00",
17 | "url": "https://github.com/wmde/FundraisingFrontend/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c",
18 | "author": {
19 | "name": "baxterthehacker",
20 | "email": "baxterthehacker@users.noreply.github.com",
21 | "username": "baxterthehacker"
22 | },
23 | "committer": {
24 | "name": "baxterthehacker",
25 | "email": "baxterthehacker@users.noreply.github.com",
26 | "username": "baxterthehacker"
27 | },
28 | "added": [
29 |
30 | ],
31 | "removed": [
32 |
33 | ],
34 | "modified": [
35 | "README.md"
36 | ]
37 | }
38 | ],
39 | "head_commit": {
40 | "id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c",
41 | "tree_id": "f9d2a07e9488b91af2641b26b9407fe22a451433",
42 | "distinct": true,
43 | "message": "Update README.md",
44 | "timestamp": "2015-05-05T19:40:15-04:00",
45 | "url": "https://github.com/wmde/FundraisingFrontend/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c",
46 | "author": {
47 | "name": "baxterthehacker",
48 | "email": "baxterthehacker@users.noreply.github.com",
49 | "username": "baxterthehacker"
50 | },
51 | "committer": {
52 | "name": "baxterthehacker",
53 | "email": "baxterthehacker@users.noreply.github.com",
54 | "username": "baxterthehacker"
55 | },
56 | "added": [
57 |
58 | ],
59 | "removed": [
60 |
61 | ],
62 | "modified": [
63 | "README.md"
64 | ]
65 | },
66 | "repository": {
67 | "id": 35129377,
68 | "name": "public-repo",
69 | "full_name": "wmde/FundraisingFrontend",
70 | "owner": {
71 | "name": "baxterthehacker",
72 | "email": "baxterthehacker@users.noreply.github.com"
73 | },
74 | "private": false,
75 | "html_url": "https://github.com/wmde/FundraisingFrontend",
76 | "description": "",
77 | "fork": false,
78 | "url": "https://github.com/wmde/FundraisingFrontend",
79 | "forks_url": "https://api.github.com/repos/wmde/FundraisingFrontend/forks",
80 | "keys_url": "https://api.github.com/repos/wmde/FundraisingFrontend/keys{/key_id}",
81 | "collaborators_url": "https://api.github.com/repos/wmde/FundraisingFrontend/collaborators{/collaborator}",
82 | "teams_url": "https://api.github.com/repos/wmde/FundraisingFrontend/teams",
83 | "hooks_url": "https://api.github.com/repos/wmde/FundraisingFrontend/hooks",
84 | "issue_events_url": "https://api.github.com/repos/wmde/FundraisingFrontend/issues/events{/number}",
85 | "events_url": "https://api.github.com/repos/wmde/FundraisingFrontend/events",
86 | "assignees_url": "https://api.github.com/repos/wmde/FundraisingFrontend/assignees{/user}",
87 | "branches_url": "https://api.github.com/repos/wmde/FundraisingFrontend/branches{/branch}",
88 | "tags_url": "https://api.github.com/repos/wmde/FundraisingFrontend/tags",
89 | "blobs_url": "https://api.github.com/repos/wmde/FundraisingFrontend/git/blobs{/sha}",
90 | "git_tags_url": "https://api.github.com/repos/wmde/FundraisingFrontend/git/tags{/sha}",
91 | "git_refs_url": "https://api.github.com/repos/wmde/FundraisingFrontend/git/refs{/sha}",
92 | "trees_url": "https://api.github.com/repos/wmde/FundraisingFrontend/git/trees{/sha}",
93 | "statuses_url": "https://api.github.com/repos/wmde/FundraisingFrontend/statuses/{sha}",
94 | "languages_url": "https://api.github.com/repos/wmde/FundraisingFrontend/languages",
95 | "stargazers_url": "https://api.github.com/repos/wmde/FundraisingFrontend/stargazers",
96 | "contributors_url": "https://api.github.com/repos/wmde/FundraisingFrontend/contributors",
97 | "subscribers_url": "https://api.github.com/repos/wmde/FundraisingFrontend/subscribers",
98 | "subscription_url": "https://api.github.com/repos/wmde/FundraisingFrontend/subscription",
99 | "commits_url": "https://api.github.com/repos/wmde/FundraisingFrontend/commits{/sha}",
100 | "git_commits_url": "https://api.github.com/repos/wmde/FundraisingFrontend/git/commits{/sha}",
101 | "comments_url": "https://api.github.com/repos/wmde/FundraisingFrontend/comments{/number}",
102 | "issue_comment_url": "https://api.github.com/repos/wmde/FundraisingFrontend/issues/comments{/number}",
103 | "contents_url": "https://api.github.com/repos/wmde/FundraisingFrontend/contents/{+path}",
104 | "compare_url": "https://api.github.com/repos/wmde/FundraisingFrontend/compare/{base}...{head}",
105 | "merges_url": "https://api.github.com/repos/wmde/FundraisingFrontend/merges",
106 | "archive_url": "https://api.github.com/repos/wmde/FundraisingFrontend/{archive_format}{/ref}",
107 | "downloads_url": "https://api.github.com/repos/wmde/FundraisingFrontend/downloads",
108 | "issues_url": "https://api.github.com/repos/wmde/FundraisingFrontend/issues{/number}",
109 | "pulls_url": "https://api.github.com/repos/wmde/FundraisingFrontend/pulls{/number}",
110 | "milestones_url": "https://api.github.com/repos/wmde/FundraisingFrontend/milestones{/number}",
111 | "notifications_url": "https://api.github.com/repos/wmde/FundraisingFrontend/notifications{?since,all,participating}",
112 | "labels_url": "https://api.github.com/repos/wmde/FundraisingFrontend/labels{/name}",
113 | "releases_url": "https://api.github.com/repos/wmde/FundraisingFrontend/releases{/id}",
114 | "created_at": 1430869212,
115 | "updated_at": "2015-05-05T23:40:12Z",
116 | "pushed_at": 1430869217,
117 | "git_url": "git://github.com/wmde/FundraisingFrontend.git",
118 | "ssh_url": "git@github.com:wmde/FundraisingFrontend.git",
119 | "clone_url": "https://github.com/wmde/FundraisingFrontend.git",
120 | "svn_url": "https://github.com/wmde/FundraisingFrontend",
121 | "homepage": null,
122 | "size": 0,
123 | "stargazers_count": 0,
124 | "watchers_count": 0,
125 | "language": null,
126 | "has_issues": true,
127 | "has_downloads": true,
128 | "has_wiki": true,
129 | "has_pages": true,
130 | "forks_count": 0,
131 | "mirror_url": null,
132 | "open_issues_count": 0,
133 | "forks": 0,
134 | "open_issues": 0,
135 | "watchers": 0,
136 | "default_branch": "master",
137 | "stargazers": 0,
138 | "master_branch": "master"
139 | },
140 | "pusher": {
141 | "name": "baxterthehacker",
142 | "email": "baxterthehacker@users.noreply.github.com"
143 | },
144 | "sender": {
145 | "login": "baxterthehacker",
146 | "id": 6752317,
147 | "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
148 | "gravatar_id": "",
149 | "url": "https://api.github.com/users/baxterthehacker",
150 | "html_url": "https://github.com/baxterthehacker",
151 | "followers_url": "https://api.github.com/users/baxterthehacker/followers",
152 | "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}",
153 | "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}",
154 | "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}",
155 | "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions",
156 | "organizations_url": "https://api.github.com/users/baxterthehacker/orgs",
157 | "repos_url": "https://api.github.com/users/baxterthehacker/repos",
158 | "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}",
159 | "received_events_url": "https://api.github.com/users/baxterthehacker/received_events",
160 | "type": "User",
161 | "site_admin": false
162 | }
163 | }
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "5f37067ae2a887b246925109ee88b28f",
8 | "packages": [
9 | {
10 | "name": "monolog/monolog",
11 | "version": "1.22.1",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/Seldaek/monolog.git",
15 | "reference": "1e044bc4b34e91743943479f1be7a1d5eb93add0"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1e044bc4b34e91743943479f1be7a1d5eb93add0",
20 | "reference": "1e044bc4b34e91743943479f1be7a1d5eb93add0",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "php": ">=5.3.0",
25 | "psr/log": "~1.0"
26 | },
27 | "provide": {
28 | "psr/log-implementation": "1.0.0"
29 | },
30 | "require-dev": {
31 | "aws/aws-sdk-php": "^2.4.9 || ^3.0",
32 | "doctrine/couchdb": "~1.0@dev",
33 | "graylog2/gelf-php": "~1.0",
34 | "jakub-onderka/php-parallel-lint": "0.9",
35 | "php-amqplib/php-amqplib": "~2.4",
36 | "php-console/php-console": "^3.1.3",
37 | "phpunit/phpunit": "~4.5",
38 | "phpunit/phpunit-mock-objects": "2.3.0",
39 | "ruflin/elastica": ">=0.90 <3.0",
40 | "sentry/sentry": "^0.13",
41 | "swiftmailer/swiftmailer": "~5.3"
42 | },
43 | "suggest": {
44 | "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
45 | "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
46 | "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
47 | "ext-mongo": "Allow sending log messages to a MongoDB server",
48 | "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
49 | "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver",
50 | "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
51 | "php-console/php-console": "Allow sending log messages to Google Chrome",
52 | "rollbar/rollbar": "Allow sending log messages to Rollbar",
53 | "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
54 | "sentry/sentry": "Allow sending log messages to a Sentry server"
55 | },
56 | "type": "library",
57 | "extra": {
58 | "branch-alias": {
59 | "dev-master": "2.0.x-dev"
60 | }
61 | },
62 | "autoload": {
63 | "psr-4": {
64 | "Monolog\\": "src/Monolog"
65 | }
66 | },
67 | "notification-url": "https://packagist.org/downloads/",
68 | "license": [
69 | "MIT"
70 | ],
71 | "authors": [
72 | {
73 | "name": "Jordi Boggiano",
74 | "email": "j.boggiano@seld.be",
75 | "homepage": "http://seld.be"
76 | }
77 | ],
78 | "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
79 | "homepage": "http://github.com/Seldaek/monolog",
80 | "keywords": [
81 | "log",
82 | "logging",
83 | "psr-3"
84 | ],
85 | "time": "2017-03-13T07:08:03+00:00"
86 | },
87 | {
88 | "name": "pimple/pimple",
89 | "version": "v3.0.2",
90 | "source": {
91 | "type": "git",
92 | "url": "https://github.com/silexphp/Pimple.git",
93 | "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a"
94 | },
95 | "dist": {
96 | "type": "zip",
97 | "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a",
98 | "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a",
99 | "shasum": ""
100 | },
101 | "require": {
102 | "php": ">=5.3.0"
103 | },
104 | "type": "library",
105 | "extra": {
106 | "branch-alias": {
107 | "dev-master": "3.0.x-dev"
108 | }
109 | },
110 | "autoload": {
111 | "psr-0": {
112 | "Pimple": "src/"
113 | }
114 | },
115 | "notification-url": "https://packagist.org/downloads/",
116 | "license": [
117 | "MIT"
118 | ],
119 | "authors": [
120 | {
121 | "name": "Fabien Potencier",
122 | "email": "fabien@symfony.com"
123 | }
124 | ],
125 | "description": "Pimple, a simple Dependency Injection Container",
126 | "homepage": "http://pimple.sensiolabs.org",
127 | "keywords": [
128 | "container",
129 | "dependency injection"
130 | ],
131 | "time": "2015-09-11T15:10:35+00:00"
132 | },
133 | {
134 | "name": "psr/log",
135 | "version": "1.0.2",
136 | "source": {
137 | "type": "git",
138 | "url": "https://github.com/php-fig/log.git",
139 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
140 | },
141 | "dist": {
142 | "type": "zip",
143 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
144 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
145 | "shasum": ""
146 | },
147 | "require": {
148 | "php": ">=5.3.0"
149 | },
150 | "type": "library",
151 | "extra": {
152 | "branch-alias": {
153 | "dev-master": "1.0.x-dev"
154 | }
155 | },
156 | "autoload": {
157 | "psr-4": {
158 | "Psr\\Log\\": "Psr/Log/"
159 | }
160 | },
161 | "notification-url": "https://packagist.org/downloads/",
162 | "license": [
163 | "MIT"
164 | ],
165 | "authors": [
166 | {
167 | "name": "PHP-FIG",
168 | "homepage": "http://www.php-fig.org/"
169 | }
170 | ],
171 | "description": "Common interface for logging libraries",
172 | "homepage": "https://github.com/php-fig/log",
173 | "keywords": [
174 | "log",
175 | "psr",
176 | "psr-3"
177 | ],
178 | "time": "2016-10-10T12:19:37+00:00"
179 | },
180 | {
181 | "name": "silex/silex",
182 | "version": "v2.1.0",
183 | "source": {
184 | "type": "git",
185 | "url": "https://github.com/silexphp/Silex.git",
186 | "reference": "d5a9d9af14a1424ddecc3da481769cf64e7d3b34"
187 | },
188 | "dist": {
189 | "type": "zip",
190 | "url": "https://api.github.com/repos/silexphp/Silex/zipball/d5a9d9af14a1424ddecc3da481769cf64e7d3b34",
191 | "reference": "d5a9d9af14a1424ddecc3da481769cf64e7d3b34",
192 | "shasum": ""
193 | },
194 | "require": {
195 | "php": ">=5.5.9",
196 | "pimple/pimple": "~3.0",
197 | "symfony/event-dispatcher": "~2.8|^3.0",
198 | "symfony/http-foundation": "~2.8|^3.0",
199 | "symfony/http-kernel": "~2.8|^3.0",
200 | "symfony/routing": "~2.8|^3.0"
201 | },
202 | "replace": {
203 | "silex/api": "self.version",
204 | "silex/providers": "self.version"
205 | },
206 | "require-dev": {
207 | "doctrine/dbal": "~2.2",
208 | "monolog/monolog": "^1.4.1",
209 | "swiftmailer/swiftmailer": "~5",
210 | "symfony/asset": "~2.8|^3.0",
211 | "symfony/browser-kit": "~2.8|^3.0",
212 | "symfony/config": "~2.8|^3.0",
213 | "symfony/css-selector": "~2.8|^3.0",
214 | "symfony/debug": "~2.8|^3.0",
215 | "symfony/doctrine-bridge": "~2.8|^3.0",
216 | "symfony/dom-crawler": "~2.8|^3.0",
217 | "symfony/expression-language": "~2.8|^3.0",
218 | "symfony/finder": "~2.8|^3.0",
219 | "symfony/form": "~2.8|^3.0",
220 | "symfony/intl": "~2.8|^3.0",
221 | "symfony/monolog-bridge": "~2.8|^3.0",
222 | "symfony/options-resolver": "~2.8|^3.0",
223 | "symfony/phpunit-bridge": "^3.2",
224 | "symfony/process": "~2.8|^3.0",
225 | "symfony/security": "~2.8|^3.0",
226 | "symfony/serializer": "~2.8|^3.0",
227 | "symfony/translation": "~2.8|^3.0",
228 | "symfony/twig-bridge": "~2.8|^3.0",
229 | "symfony/validator": "~2.8|^3.0",
230 | "symfony/var-dumper": "~2.8|^3.0",
231 | "symfony/web-link": "^3.3",
232 | "twig/twig": "~1.28|~2.0"
233 | },
234 | "type": "library",
235 | "extra": {
236 | "branch-alias": {
237 | "dev-master": "2.1.x-dev"
238 | }
239 | },
240 | "autoload": {
241 | "psr-4": {
242 | "Silex\\": "src/Silex"
243 | }
244 | },
245 | "notification-url": "https://packagist.org/downloads/",
246 | "license": [
247 | "MIT"
248 | ],
249 | "authors": [
250 | {
251 | "name": "Fabien Potencier",
252 | "email": "fabien@symfony.com"
253 | },
254 | {
255 | "name": "Igor Wiedler",
256 | "email": "igor@wiedler.ch"
257 | }
258 | ],
259 | "description": "The PHP micro-framework based on the Symfony Components",
260 | "homepage": "http://silex.sensiolabs.org",
261 | "keywords": [
262 | "microframework"
263 | ],
264 | "time": "2017-05-03T15:21:42+00:00"
265 | },
266 | {
267 | "name": "symfony/debug",
268 | "version": "v3.2.8",
269 | "source": {
270 | "type": "git",
271 | "url": "https://github.com/symfony/debug.git",
272 | "reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686"
273 | },
274 | "dist": {
275 | "type": "zip",
276 | "url": "https://api.github.com/repos/symfony/debug/zipball/fd6eeee656a5a7b384d56f1072243fe1c0e81686",
277 | "reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686",
278 | "shasum": ""
279 | },
280 | "require": {
281 | "php": ">=5.5.9",
282 | "psr/log": "~1.0"
283 | },
284 | "conflict": {
285 | "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
286 | },
287 | "require-dev": {
288 | "symfony/class-loader": "~2.8|~3.0",
289 | "symfony/http-kernel": "~2.8|~3.0"
290 | },
291 | "type": "library",
292 | "extra": {
293 | "branch-alias": {
294 | "dev-master": "3.2-dev"
295 | }
296 | },
297 | "autoload": {
298 | "psr-4": {
299 | "Symfony\\Component\\Debug\\": ""
300 | },
301 | "exclude-from-classmap": [
302 | "/Tests/"
303 | ]
304 | },
305 | "notification-url": "https://packagist.org/downloads/",
306 | "license": [
307 | "MIT"
308 | ],
309 | "authors": [
310 | {
311 | "name": "Fabien Potencier",
312 | "email": "fabien@symfony.com"
313 | },
314 | {
315 | "name": "Symfony Community",
316 | "homepage": "https://symfony.com/contributors"
317 | }
318 | ],
319 | "description": "Symfony Debug Component",
320 | "homepage": "https://symfony.com",
321 | "time": "2017-04-19T20:17:50+00:00"
322 | },
323 | {
324 | "name": "symfony/event-dispatcher",
325 | "version": "v3.2.8",
326 | "source": {
327 | "type": "git",
328 | "url": "https://github.com/symfony/event-dispatcher.git",
329 | "reference": "b8a401f733b43251e1d088c589368b2a94155e40"
330 | },
331 | "dist": {
332 | "type": "zip",
333 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b8a401f733b43251e1d088c589368b2a94155e40",
334 | "reference": "b8a401f733b43251e1d088c589368b2a94155e40",
335 | "shasum": ""
336 | },
337 | "require": {
338 | "php": ">=5.5.9"
339 | },
340 | "require-dev": {
341 | "psr/log": "~1.0",
342 | "symfony/config": "~2.8|~3.0",
343 | "symfony/dependency-injection": "~2.8|~3.0",
344 | "symfony/expression-language": "~2.8|~3.0",
345 | "symfony/stopwatch": "~2.8|~3.0"
346 | },
347 | "suggest": {
348 | "symfony/dependency-injection": "",
349 | "symfony/http-kernel": ""
350 | },
351 | "type": "library",
352 | "extra": {
353 | "branch-alias": {
354 | "dev-master": "3.2-dev"
355 | }
356 | },
357 | "autoload": {
358 | "psr-4": {
359 | "Symfony\\Component\\EventDispatcher\\": ""
360 | },
361 | "exclude-from-classmap": [
362 | "/Tests/"
363 | ]
364 | },
365 | "notification-url": "https://packagist.org/downloads/",
366 | "license": [
367 | "MIT"
368 | ],
369 | "authors": [
370 | {
371 | "name": "Fabien Potencier",
372 | "email": "fabien@symfony.com"
373 | },
374 | {
375 | "name": "Symfony Community",
376 | "homepage": "https://symfony.com/contributors"
377 | }
378 | ],
379 | "description": "Symfony EventDispatcher Component",
380 | "homepage": "https://symfony.com",
381 | "time": "2017-05-01T14:58:48+00:00"
382 | },
383 | {
384 | "name": "symfony/http-foundation",
385 | "version": "v3.2.8",
386 | "source": {
387 | "type": "git",
388 | "url": "https://github.com/symfony/http-foundation.git",
389 | "reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef"
390 | },
391 | "dist": {
392 | "type": "zip",
393 | "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9de6add7f731e5af7f5b2e9c0da365e43383ebef",
394 | "reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef",
395 | "shasum": ""
396 | },
397 | "require": {
398 | "php": ">=5.5.9",
399 | "symfony/polyfill-mbstring": "~1.1"
400 | },
401 | "require-dev": {
402 | "symfony/expression-language": "~2.8|~3.0"
403 | },
404 | "type": "library",
405 | "extra": {
406 | "branch-alias": {
407 | "dev-master": "3.2-dev"
408 | }
409 | },
410 | "autoload": {
411 | "psr-4": {
412 | "Symfony\\Component\\HttpFoundation\\": ""
413 | },
414 | "exclude-from-classmap": [
415 | "/Tests/"
416 | ]
417 | },
418 | "notification-url": "https://packagist.org/downloads/",
419 | "license": [
420 | "MIT"
421 | ],
422 | "authors": [
423 | {
424 | "name": "Fabien Potencier",
425 | "email": "fabien@symfony.com"
426 | },
427 | {
428 | "name": "Symfony Community",
429 | "homepage": "https://symfony.com/contributors"
430 | }
431 | ],
432 | "description": "Symfony HttpFoundation Component",
433 | "homepage": "https://symfony.com",
434 | "time": "2017-05-01T14:55:58+00:00"
435 | },
436 | {
437 | "name": "symfony/http-kernel",
438 | "version": "v3.2.8",
439 | "source": {
440 | "type": "git",
441 | "url": "https://github.com/symfony/http-kernel.git",
442 | "reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05"
443 | },
444 | "dist": {
445 | "type": "zip",
446 | "url": "https://api.github.com/repos/symfony/http-kernel/zipball/46e8b209abab55c072c47d72d5cd1d62c0585e05",
447 | "reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05",
448 | "shasum": ""
449 | },
450 | "require": {
451 | "php": ">=5.5.9",
452 | "psr/log": "~1.0",
453 | "symfony/debug": "~2.8|~3.0",
454 | "symfony/event-dispatcher": "~2.8|~3.0",
455 | "symfony/http-foundation": "~2.8.13|~3.1.6|~3.2"
456 | },
457 | "conflict": {
458 | "symfony/config": "<2.8"
459 | },
460 | "require-dev": {
461 | "symfony/browser-kit": "~2.8|~3.0",
462 | "symfony/class-loader": "~2.8|~3.0",
463 | "symfony/config": "~2.8|~3.0",
464 | "symfony/console": "~2.8|~3.0",
465 | "symfony/css-selector": "~2.8|~3.0",
466 | "symfony/dependency-injection": "~2.8|~3.0",
467 | "symfony/dom-crawler": "~2.8|~3.0",
468 | "symfony/expression-language": "~2.8|~3.0",
469 | "symfony/finder": "~2.8|~3.0",
470 | "symfony/process": "~2.8|~3.0",
471 | "symfony/routing": "~2.8|~3.0",
472 | "symfony/stopwatch": "~2.8|~3.0",
473 | "symfony/templating": "~2.8|~3.0",
474 | "symfony/translation": "~2.8|~3.0",
475 | "symfony/var-dumper": "~3.2"
476 | },
477 | "suggest": {
478 | "symfony/browser-kit": "",
479 | "symfony/class-loader": "",
480 | "symfony/config": "",
481 | "symfony/console": "",
482 | "symfony/dependency-injection": "",
483 | "symfony/finder": "",
484 | "symfony/var-dumper": ""
485 | },
486 | "type": "library",
487 | "extra": {
488 | "branch-alias": {
489 | "dev-master": "3.2-dev"
490 | }
491 | },
492 | "autoload": {
493 | "psr-4": {
494 | "Symfony\\Component\\HttpKernel\\": ""
495 | },
496 | "exclude-from-classmap": [
497 | "/Tests/"
498 | ]
499 | },
500 | "notification-url": "https://packagist.org/downloads/",
501 | "license": [
502 | "MIT"
503 | ],
504 | "authors": [
505 | {
506 | "name": "Fabien Potencier",
507 | "email": "fabien@symfony.com"
508 | },
509 | {
510 | "name": "Symfony Community",
511 | "homepage": "https://symfony.com/contributors"
512 | }
513 | ],
514 | "description": "Symfony HttpKernel Component",
515 | "homepage": "https://symfony.com",
516 | "time": "2017-05-01T17:46:48+00:00"
517 | },
518 | {
519 | "name": "symfony/polyfill-mbstring",
520 | "version": "v1.3.0",
521 | "source": {
522 | "type": "git",
523 | "url": "https://github.com/symfony/polyfill-mbstring.git",
524 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
525 | },
526 | "dist": {
527 | "type": "zip",
528 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
529 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
530 | "shasum": ""
531 | },
532 | "require": {
533 | "php": ">=5.3.3"
534 | },
535 | "suggest": {
536 | "ext-mbstring": "For best performance"
537 | },
538 | "type": "library",
539 | "extra": {
540 | "branch-alias": {
541 | "dev-master": "1.3-dev"
542 | }
543 | },
544 | "autoload": {
545 | "psr-4": {
546 | "Symfony\\Polyfill\\Mbstring\\": ""
547 | },
548 | "files": [
549 | "bootstrap.php"
550 | ]
551 | },
552 | "notification-url": "https://packagist.org/downloads/",
553 | "license": [
554 | "MIT"
555 | ],
556 | "authors": [
557 | {
558 | "name": "Nicolas Grekas",
559 | "email": "p@tchwork.com"
560 | },
561 | {
562 | "name": "Symfony Community",
563 | "homepage": "https://symfony.com/contributors"
564 | }
565 | ],
566 | "description": "Symfony polyfill for the Mbstring extension",
567 | "homepage": "https://symfony.com",
568 | "keywords": [
569 | "compatibility",
570 | "mbstring",
571 | "polyfill",
572 | "portable",
573 | "shim"
574 | ],
575 | "time": "2016-11-14T01:06:16+00:00"
576 | },
577 | {
578 | "name": "symfony/process",
579 | "version": "v3.2.8",
580 | "source": {
581 | "type": "git",
582 | "url": "https://github.com/symfony/process.git",
583 | "reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0"
584 | },
585 | "dist": {
586 | "type": "zip",
587 | "url": "https://api.github.com/repos/symfony/process/zipball/999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0",
588 | "reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0",
589 | "shasum": ""
590 | },
591 | "require": {
592 | "php": ">=5.5.9"
593 | },
594 | "type": "library",
595 | "extra": {
596 | "branch-alias": {
597 | "dev-master": "3.2-dev"
598 | }
599 | },
600 | "autoload": {
601 | "psr-4": {
602 | "Symfony\\Component\\Process\\": ""
603 | },
604 | "exclude-from-classmap": [
605 | "/Tests/"
606 | ]
607 | },
608 | "notification-url": "https://packagist.org/downloads/",
609 | "license": [
610 | "MIT"
611 | ],
612 | "authors": [
613 | {
614 | "name": "Fabien Potencier",
615 | "email": "fabien@symfony.com"
616 | },
617 | {
618 | "name": "Symfony Community",
619 | "homepage": "https://symfony.com/contributors"
620 | }
621 | ],
622 | "description": "Symfony Process Component",
623 | "homepage": "https://symfony.com",
624 | "time": "2017-04-12T14:13:17+00:00"
625 | },
626 | {
627 | "name": "symfony/routing",
628 | "version": "v3.2.8",
629 | "source": {
630 | "type": "git",
631 | "url": "https://github.com/symfony/routing.git",
632 | "reference": "5029745d6d463585e8b487dbc83d6333f408853a"
633 | },
634 | "dist": {
635 | "type": "zip",
636 | "url": "https://api.github.com/repos/symfony/routing/zipball/5029745d6d463585e8b487dbc83d6333f408853a",
637 | "reference": "5029745d6d463585e8b487dbc83d6333f408853a",
638 | "shasum": ""
639 | },
640 | "require": {
641 | "php": ">=5.5.9"
642 | },
643 | "conflict": {
644 | "symfony/config": "<2.8"
645 | },
646 | "require-dev": {
647 | "doctrine/annotations": "~1.0",
648 | "doctrine/common": "~2.2",
649 | "psr/log": "~1.0",
650 | "symfony/config": "~2.8|~3.0",
651 | "symfony/expression-language": "~2.8|~3.0",
652 | "symfony/http-foundation": "~2.8|~3.0",
653 | "symfony/yaml": "~2.8|~3.0"
654 | },
655 | "suggest": {
656 | "doctrine/annotations": "For using the annotation loader",
657 | "symfony/config": "For using the all-in-one router or any loader",
658 | "symfony/dependency-injection": "For loading routes from a service",
659 | "symfony/expression-language": "For using expression matching",
660 | "symfony/http-foundation": "For using a Symfony Request object",
661 | "symfony/yaml": "For using the YAML loader"
662 | },
663 | "type": "library",
664 | "extra": {
665 | "branch-alias": {
666 | "dev-master": "3.2-dev"
667 | }
668 | },
669 | "autoload": {
670 | "psr-4": {
671 | "Symfony\\Component\\Routing\\": ""
672 | },
673 | "exclude-from-classmap": [
674 | "/Tests/"
675 | ]
676 | },
677 | "notification-url": "https://packagist.org/downloads/",
678 | "license": [
679 | "MIT"
680 | ],
681 | "authors": [
682 | {
683 | "name": "Fabien Potencier",
684 | "email": "fabien@symfony.com"
685 | },
686 | {
687 | "name": "Symfony Community",
688 | "homepage": "https://symfony.com/contributors"
689 | }
690 | ],
691 | "description": "Symfony Routing Component",
692 | "homepage": "https://symfony.com",
693 | "keywords": [
694 | "router",
695 | "routing",
696 | "uri",
697 | "url"
698 | ],
699 | "time": "2017-04-12T14:13:17+00:00"
700 | }
701 | ],
702 | "packages-dev": [
703 | {
704 | "name": "doctrine/instantiator",
705 | "version": "1.0.5",
706 | "source": {
707 | "type": "git",
708 | "url": "https://github.com/doctrine/instantiator.git",
709 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
710 | },
711 | "dist": {
712 | "type": "zip",
713 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
714 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
715 | "shasum": ""
716 | },
717 | "require": {
718 | "php": ">=5.3,<8.0-DEV"
719 | },
720 | "require-dev": {
721 | "athletic/athletic": "~0.1.8",
722 | "ext-pdo": "*",
723 | "ext-phar": "*",
724 | "phpunit/phpunit": "~4.0",
725 | "squizlabs/php_codesniffer": "~2.0"
726 | },
727 | "type": "library",
728 | "extra": {
729 | "branch-alias": {
730 | "dev-master": "1.0.x-dev"
731 | }
732 | },
733 | "autoload": {
734 | "psr-4": {
735 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
736 | }
737 | },
738 | "notification-url": "https://packagist.org/downloads/",
739 | "license": [
740 | "MIT"
741 | ],
742 | "authors": [
743 | {
744 | "name": "Marco Pivetta",
745 | "email": "ocramius@gmail.com",
746 | "homepage": "http://ocramius.github.com/"
747 | }
748 | ],
749 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
750 | "homepage": "https://github.com/doctrine/instantiator",
751 | "keywords": [
752 | "constructor",
753 | "instantiate"
754 | ],
755 | "time": "2015-06-14T21:17:01+00:00"
756 | },
757 | {
758 | "name": "mediawiki/mediawiki-codesniffer",
759 | "version": "v0.8.0",
760 | "source": {
761 | "type": "git",
762 | "url": "https://github.com/wikimedia/mediawiki-tools-codesniffer.git",
763 | "reference": "439149cc2fe5ccc29aadfd49ce22c36122d51c4c"
764 | },
765 | "dist": {
766 | "type": "zip",
767 | "url": "https://api.github.com/repos/wikimedia/mediawiki-tools-codesniffer/zipball/439149cc2fe5ccc29aadfd49ce22c36122d51c4c",
768 | "reference": "439149cc2fe5ccc29aadfd49ce22c36122d51c4c",
769 | "shasum": ""
770 | },
771 | "require": {
772 | "php": ">= 5.5.9",
773 | "squizlabs/php_codesniffer": "2.9.0"
774 | },
775 | "require-dev": {
776 | "jakub-onderka/php-parallel-lint": "0.9.*",
777 | "mikey179/vfsstream": "~1.6",
778 | "phpunit/phpunit": "~4.1"
779 | },
780 | "type": "library",
781 | "notification-url": "https://packagist.org/downloads/",
782 | "license": [
783 | "GPL-2.0+"
784 | ],
785 | "description": "MediaWiki CodeSniffer Standards",
786 | "homepage": "https://www.mediawiki.org/wiki/Manual:Coding_conventions/PHP",
787 | "keywords": [
788 | "codesniffer",
789 | "mediawiki"
790 | ],
791 | "time": "2017-05-04T19:15:03+00:00"
792 | },
793 | {
794 | "name": "myclabs/deep-copy",
795 | "version": "1.6.1",
796 | "source": {
797 | "type": "git",
798 | "url": "https://github.com/myclabs/DeepCopy.git",
799 | "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102"
800 | },
801 | "dist": {
802 | "type": "zip",
803 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8e6e04167378abf1ddb4d3522d8755c5fd90d102",
804 | "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102",
805 | "shasum": ""
806 | },
807 | "require": {
808 | "php": ">=5.4.0"
809 | },
810 | "require-dev": {
811 | "doctrine/collections": "1.*",
812 | "phpunit/phpunit": "~4.1"
813 | },
814 | "type": "library",
815 | "autoload": {
816 | "psr-4": {
817 | "DeepCopy\\": "src/DeepCopy/"
818 | }
819 | },
820 | "notification-url": "https://packagist.org/downloads/",
821 | "license": [
822 | "MIT"
823 | ],
824 | "description": "Create deep copies (clones) of your objects",
825 | "homepage": "https://github.com/myclabs/DeepCopy",
826 | "keywords": [
827 | "clone",
828 | "copy",
829 | "duplicate",
830 | "object",
831 | "object graph"
832 | ],
833 | "time": "2017-04-12T18:52:22+00:00"
834 | },
835 | {
836 | "name": "phar-io/manifest",
837 | "version": "1.0.1",
838 | "source": {
839 | "type": "git",
840 | "url": "https://github.com/phar-io/manifest.git",
841 | "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0"
842 | },
843 | "dist": {
844 | "type": "zip",
845 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0",
846 | "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0",
847 | "shasum": ""
848 | },
849 | "require": {
850 | "ext-dom": "*",
851 | "ext-phar": "*",
852 | "phar-io/version": "^1.0.1",
853 | "php": "^5.6 || ^7.0"
854 | },
855 | "type": "library",
856 | "extra": {
857 | "branch-alias": {
858 | "dev-master": "1.0.x-dev"
859 | }
860 | },
861 | "autoload": {
862 | "classmap": [
863 | "src/"
864 | ]
865 | },
866 | "notification-url": "https://packagist.org/downloads/",
867 | "license": [
868 | "BSD-3-Clause"
869 | ],
870 | "authors": [
871 | {
872 | "name": "Arne Blankerts",
873 | "email": "arne@blankerts.de",
874 | "role": "Developer"
875 | },
876 | {
877 | "name": "Sebastian Heuer",
878 | "email": "sebastian@phpeople.de",
879 | "role": "Developer"
880 | },
881 | {
882 | "name": "Sebastian Bergmann",
883 | "email": "sebastian@phpunit.de",
884 | "role": "Developer"
885 | }
886 | ],
887 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
888 | "time": "2017-03-05T18:14:27+00:00"
889 | },
890 | {
891 | "name": "phar-io/version",
892 | "version": "1.0.1",
893 | "source": {
894 | "type": "git",
895 | "url": "https://github.com/phar-io/version.git",
896 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df"
897 | },
898 | "dist": {
899 | "type": "zip",
900 | "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df",
901 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df",
902 | "shasum": ""
903 | },
904 | "require": {
905 | "php": "^5.6 || ^7.0"
906 | },
907 | "type": "library",
908 | "autoload": {
909 | "classmap": [
910 | "src/"
911 | ]
912 | },
913 | "notification-url": "https://packagist.org/downloads/",
914 | "license": [
915 | "BSD-3-Clause"
916 | ],
917 | "authors": [
918 | {
919 | "name": "Arne Blankerts",
920 | "email": "arne@blankerts.de",
921 | "role": "Developer"
922 | },
923 | {
924 | "name": "Sebastian Heuer",
925 | "email": "sebastian@phpeople.de",
926 | "role": "Developer"
927 | },
928 | {
929 | "name": "Sebastian Bergmann",
930 | "email": "sebastian@phpunit.de",
931 | "role": "Developer"
932 | }
933 | ],
934 | "description": "Library for handling version information and constraints",
935 | "time": "2017-03-05T17:38:23+00:00"
936 | },
937 | {
938 | "name": "phpdocumentor/reflection-common",
939 | "version": "1.0",
940 | "source": {
941 | "type": "git",
942 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
943 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
944 | },
945 | "dist": {
946 | "type": "zip",
947 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
948 | "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
949 | "shasum": ""
950 | },
951 | "require": {
952 | "php": ">=5.5"
953 | },
954 | "require-dev": {
955 | "phpunit/phpunit": "^4.6"
956 | },
957 | "type": "library",
958 | "extra": {
959 | "branch-alias": {
960 | "dev-master": "1.0.x-dev"
961 | }
962 | },
963 | "autoload": {
964 | "psr-4": {
965 | "phpDocumentor\\Reflection\\": [
966 | "src"
967 | ]
968 | }
969 | },
970 | "notification-url": "https://packagist.org/downloads/",
971 | "license": [
972 | "MIT"
973 | ],
974 | "authors": [
975 | {
976 | "name": "Jaap van Otterdijk",
977 | "email": "opensource@ijaap.nl"
978 | }
979 | ],
980 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
981 | "homepage": "http://www.phpdoc.org",
982 | "keywords": [
983 | "FQSEN",
984 | "phpDocumentor",
985 | "phpdoc",
986 | "reflection",
987 | "static analysis"
988 | ],
989 | "time": "2015-12-27T11:43:31+00:00"
990 | },
991 | {
992 | "name": "phpdocumentor/reflection-docblock",
993 | "version": "3.1.1",
994 | "source": {
995 | "type": "git",
996 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
997 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
998 | },
999 | "dist": {
1000 | "type": "zip",
1001 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
1002 | "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
1003 | "shasum": ""
1004 | },
1005 | "require": {
1006 | "php": ">=5.5",
1007 | "phpdocumentor/reflection-common": "^1.0@dev",
1008 | "phpdocumentor/type-resolver": "^0.2.0",
1009 | "webmozart/assert": "^1.0"
1010 | },
1011 | "require-dev": {
1012 | "mockery/mockery": "^0.9.4",
1013 | "phpunit/phpunit": "^4.4"
1014 | },
1015 | "type": "library",
1016 | "autoload": {
1017 | "psr-4": {
1018 | "phpDocumentor\\Reflection\\": [
1019 | "src/"
1020 | ]
1021 | }
1022 | },
1023 | "notification-url": "https://packagist.org/downloads/",
1024 | "license": [
1025 | "MIT"
1026 | ],
1027 | "authors": [
1028 | {
1029 | "name": "Mike van Riel",
1030 | "email": "me@mikevanriel.com"
1031 | }
1032 | ],
1033 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
1034 | "time": "2016-09-30T07:12:33+00:00"
1035 | },
1036 | {
1037 | "name": "phpdocumentor/type-resolver",
1038 | "version": "0.2.1",
1039 | "source": {
1040 | "type": "git",
1041 | "url": "https://github.com/phpDocumentor/TypeResolver.git",
1042 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
1043 | },
1044 | "dist": {
1045 | "type": "zip",
1046 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
1047 | "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
1048 | "shasum": ""
1049 | },
1050 | "require": {
1051 | "php": ">=5.5",
1052 | "phpdocumentor/reflection-common": "^1.0"
1053 | },
1054 | "require-dev": {
1055 | "mockery/mockery": "^0.9.4",
1056 | "phpunit/phpunit": "^5.2||^4.8.24"
1057 | },
1058 | "type": "library",
1059 | "extra": {
1060 | "branch-alias": {
1061 | "dev-master": "1.0.x-dev"
1062 | }
1063 | },
1064 | "autoload": {
1065 | "psr-4": {
1066 | "phpDocumentor\\Reflection\\": [
1067 | "src/"
1068 | ]
1069 | }
1070 | },
1071 | "notification-url": "https://packagist.org/downloads/",
1072 | "license": [
1073 | "MIT"
1074 | ],
1075 | "authors": [
1076 | {
1077 | "name": "Mike van Riel",
1078 | "email": "me@mikevanriel.com"
1079 | }
1080 | ],
1081 | "time": "2016-11-25T06:54:22+00:00"
1082 | },
1083 | {
1084 | "name": "phpspec/prophecy",
1085 | "version": "v1.7.0",
1086 | "source": {
1087 | "type": "git",
1088 | "url": "https://github.com/phpspec/prophecy.git",
1089 | "reference": "93d39f1f7f9326d746203c7c056f300f7f126073"
1090 | },
1091 | "dist": {
1092 | "type": "zip",
1093 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073",
1094 | "reference": "93d39f1f7f9326d746203c7c056f300f7f126073",
1095 | "shasum": ""
1096 | },
1097 | "require": {
1098 | "doctrine/instantiator": "^1.0.2",
1099 | "php": "^5.3|^7.0",
1100 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
1101 | "sebastian/comparator": "^1.1|^2.0",
1102 | "sebastian/recursion-context": "^1.0|^2.0|^3.0"
1103 | },
1104 | "require-dev": {
1105 | "phpspec/phpspec": "^2.5|^3.2",
1106 | "phpunit/phpunit": "^4.8 || ^5.6.5"
1107 | },
1108 | "type": "library",
1109 | "extra": {
1110 | "branch-alias": {
1111 | "dev-master": "1.6.x-dev"
1112 | }
1113 | },
1114 | "autoload": {
1115 | "psr-0": {
1116 | "Prophecy\\": "src/"
1117 | }
1118 | },
1119 | "notification-url": "https://packagist.org/downloads/",
1120 | "license": [
1121 | "MIT"
1122 | ],
1123 | "authors": [
1124 | {
1125 | "name": "Konstantin Kudryashov",
1126 | "email": "ever.zet@gmail.com",
1127 | "homepage": "http://everzet.com"
1128 | },
1129 | {
1130 | "name": "Marcello Duarte",
1131 | "email": "marcello.duarte@gmail.com"
1132 | }
1133 | ],
1134 | "description": "Highly opinionated mocking framework for PHP 5.3+",
1135 | "homepage": "https://github.com/phpspec/prophecy",
1136 | "keywords": [
1137 | "Double",
1138 | "Dummy",
1139 | "fake",
1140 | "mock",
1141 | "spy",
1142 | "stub"
1143 | ],
1144 | "time": "2017-03-02T20:05:34+00:00"
1145 | },
1146 | {
1147 | "name": "phpunit/php-code-coverage",
1148 | "version": "5.2.1",
1149 | "source": {
1150 | "type": "git",
1151 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
1152 | "reference": "dc421f9ca5082a0c0cb04afb171c765f79add85b"
1153 | },
1154 | "dist": {
1155 | "type": "zip",
1156 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/dc421f9ca5082a0c0cb04afb171c765f79add85b",
1157 | "reference": "dc421f9ca5082a0c0cb04afb171c765f79add85b",
1158 | "shasum": ""
1159 | },
1160 | "require": {
1161 | "ext-dom": "*",
1162 | "ext-xmlwriter": "*",
1163 | "php": "^7.0",
1164 | "phpunit/php-file-iterator": "^1.3",
1165 | "phpunit/php-text-template": "^1.2",
1166 | "phpunit/php-token-stream": "^1.4.11 || ^2.0",
1167 | "sebastian/code-unit-reverse-lookup": "^1.0",
1168 | "sebastian/environment": "^3.0",
1169 | "sebastian/version": "^2.0",
1170 | "theseer/tokenizer": "^1.1"
1171 | },
1172 | "require-dev": {
1173 | "ext-xdebug": "^2.5",
1174 | "phpunit/phpunit": "^6.0"
1175 | },
1176 | "suggest": {
1177 | "ext-xdebug": "^2.5.3"
1178 | },
1179 | "type": "library",
1180 | "extra": {
1181 | "branch-alias": {
1182 | "dev-master": "5.2.x-dev"
1183 | }
1184 | },
1185 | "autoload": {
1186 | "classmap": [
1187 | "src/"
1188 | ]
1189 | },
1190 | "notification-url": "https://packagist.org/downloads/",
1191 | "license": [
1192 | "BSD-3-Clause"
1193 | ],
1194 | "authors": [
1195 | {
1196 | "name": "Sebastian Bergmann",
1197 | "email": "sb@sebastian-bergmann.de",
1198 | "role": "lead"
1199 | }
1200 | ],
1201 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
1202 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
1203 | "keywords": [
1204 | "coverage",
1205 | "testing",
1206 | "xunit"
1207 | ],
1208 | "time": "2017-04-21T08:03:57+00:00"
1209 | },
1210 | {
1211 | "name": "phpunit/php-file-iterator",
1212 | "version": "1.4.2",
1213 | "source": {
1214 | "type": "git",
1215 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
1216 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
1217 | },
1218 | "dist": {
1219 | "type": "zip",
1220 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
1221 | "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
1222 | "shasum": ""
1223 | },
1224 | "require": {
1225 | "php": ">=5.3.3"
1226 | },
1227 | "type": "library",
1228 | "extra": {
1229 | "branch-alias": {
1230 | "dev-master": "1.4.x-dev"
1231 | }
1232 | },
1233 | "autoload": {
1234 | "classmap": [
1235 | "src/"
1236 | ]
1237 | },
1238 | "notification-url": "https://packagist.org/downloads/",
1239 | "license": [
1240 | "BSD-3-Clause"
1241 | ],
1242 | "authors": [
1243 | {
1244 | "name": "Sebastian Bergmann",
1245 | "email": "sb@sebastian-bergmann.de",
1246 | "role": "lead"
1247 | }
1248 | ],
1249 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
1250 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
1251 | "keywords": [
1252 | "filesystem",
1253 | "iterator"
1254 | ],
1255 | "time": "2016-10-03T07:40:28+00:00"
1256 | },
1257 | {
1258 | "name": "phpunit/php-text-template",
1259 | "version": "1.2.1",
1260 | "source": {
1261 | "type": "git",
1262 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
1263 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
1264 | },
1265 | "dist": {
1266 | "type": "zip",
1267 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1268 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1269 | "shasum": ""
1270 | },
1271 | "require": {
1272 | "php": ">=5.3.3"
1273 | },
1274 | "type": "library",
1275 | "autoload": {
1276 | "classmap": [
1277 | "src/"
1278 | ]
1279 | },
1280 | "notification-url": "https://packagist.org/downloads/",
1281 | "license": [
1282 | "BSD-3-Clause"
1283 | ],
1284 | "authors": [
1285 | {
1286 | "name": "Sebastian Bergmann",
1287 | "email": "sebastian@phpunit.de",
1288 | "role": "lead"
1289 | }
1290 | ],
1291 | "description": "Simple template engine.",
1292 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
1293 | "keywords": [
1294 | "template"
1295 | ],
1296 | "time": "2015-06-21T13:50:34+00:00"
1297 | },
1298 | {
1299 | "name": "phpunit/php-timer",
1300 | "version": "1.0.9",
1301 | "source": {
1302 | "type": "git",
1303 | "url": "https://github.com/sebastianbergmann/php-timer.git",
1304 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
1305 | },
1306 | "dist": {
1307 | "type": "zip",
1308 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
1309 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
1310 | "shasum": ""
1311 | },
1312 | "require": {
1313 | "php": "^5.3.3 || ^7.0"
1314 | },
1315 | "require-dev": {
1316 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
1317 | },
1318 | "type": "library",
1319 | "extra": {
1320 | "branch-alias": {
1321 | "dev-master": "1.0-dev"
1322 | }
1323 | },
1324 | "autoload": {
1325 | "classmap": [
1326 | "src/"
1327 | ]
1328 | },
1329 | "notification-url": "https://packagist.org/downloads/",
1330 | "license": [
1331 | "BSD-3-Clause"
1332 | ],
1333 | "authors": [
1334 | {
1335 | "name": "Sebastian Bergmann",
1336 | "email": "sb@sebastian-bergmann.de",
1337 | "role": "lead"
1338 | }
1339 | ],
1340 | "description": "Utility class for timing",
1341 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
1342 | "keywords": [
1343 | "timer"
1344 | ],
1345 | "time": "2017-02-26T11:10:40+00:00"
1346 | },
1347 | {
1348 | "name": "phpunit/php-token-stream",
1349 | "version": "1.4.11",
1350 | "source": {
1351 | "type": "git",
1352 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
1353 | "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7"
1354 | },
1355 | "dist": {
1356 | "type": "zip",
1357 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7",
1358 | "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7",
1359 | "shasum": ""
1360 | },
1361 | "require": {
1362 | "ext-tokenizer": "*",
1363 | "php": ">=5.3.3"
1364 | },
1365 | "require-dev": {
1366 | "phpunit/phpunit": "~4.2"
1367 | },
1368 | "type": "library",
1369 | "extra": {
1370 | "branch-alias": {
1371 | "dev-master": "1.4-dev"
1372 | }
1373 | },
1374 | "autoload": {
1375 | "classmap": [
1376 | "src/"
1377 | ]
1378 | },
1379 | "notification-url": "https://packagist.org/downloads/",
1380 | "license": [
1381 | "BSD-3-Clause"
1382 | ],
1383 | "authors": [
1384 | {
1385 | "name": "Sebastian Bergmann",
1386 | "email": "sebastian@phpunit.de"
1387 | }
1388 | ],
1389 | "description": "Wrapper around PHP's tokenizer extension.",
1390 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
1391 | "keywords": [
1392 | "tokenizer"
1393 | ],
1394 | "time": "2017-02-27T10:12:30+00:00"
1395 | },
1396 | {
1397 | "name": "phpunit/phpunit",
1398 | "version": "6.1.4",
1399 | "source": {
1400 | "type": "git",
1401 | "url": "https://github.com/sebastianbergmann/phpunit.git",
1402 | "reference": "42b7f394a8e009516582331b1e03a1aba40175d1"
1403 | },
1404 | "dist": {
1405 | "type": "zip",
1406 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/42b7f394a8e009516582331b1e03a1aba40175d1",
1407 | "reference": "42b7f394a8e009516582331b1e03a1aba40175d1",
1408 | "shasum": ""
1409 | },
1410 | "require": {
1411 | "ext-dom": "*",
1412 | "ext-json": "*",
1413 | "ext-libxml": "*",
1414 | "ext-mbstring": "*",
1415 | "ext-xml": "*",
1416 | "myclabs/deep-copy": "^1.3",
1417 | "phar-io/manifest": "^1.0.1",
1418 | "phar-io/version": "^1.0",
1419 | "php": "^7.0",
1420 | "phpspec/prophecy": "^1.7",
1421 | "phpunit/php-code-coverage": "^5.2",
1422 | "phpunit/php-file-iterator": "^1.4",
1423 | "phpunit/php-text-template": "^1.2",
1424 | "phpunit/php-timer": "^1.0.6",
1425 | "phpunit/phpunit-mock-objects": "^4.0",
1426 | "sebastian/comparator": "^2.0",
1427 | "sebastian/diff": "^1.4.3 || ^2.0",
1428 | "sebastian/environment": "^3.0.2",
1429 | "sebastian/exporter": "^3.1",
1430 | "sebastian/global-state": "^1.1 || ^2.0",
1431 | "sebastian/object-enumerator": "^3.0.2",
1432 | "sebastian/resource-operations": "^1.0",
1433 | "sebastian/version": "^2.0"
1434 | },
1435 | "conflict": {
1436 | "phpdocumentor/reflection-docblock": "3.0.2",
1437 | "phpunit/dbunit": "<3.0"
1438 | },
1439 | "require-dev": {
1440 | "ext-pdo": "*"
1441 | },
1442 | "suggest": {
1443 | "ext-xdebug": "*",
1444 | "phpunit/php-invoker": "^1.1"
1445 | },
1446 | "bin": [
1447 | "phpunit"
1448 | ],
1449 | "type": "library",
1450 | "extra": {
1451 | "branch-alias": {
1452 | "dev-master": "6.1.x-dev"
1453 | }
1454 | },
1455 | "autoload": {
1456 | "classmap": [
1457 | "src/"
1458 | ]
1459 | },
1460 | "notification-url": "https://packagist.org/downloads/",
1461 | "license": [
1462 | "BSD-3-Clause"
1463 | ],
1464 | "authors": [
1465 | {
1466 | "name": "Sebastian Bergmann",
1467 | "email": "sebastian@phpunit.de",
1468 | "role": "lead"
1469 | }
1470 | ],
1471 | "description": "The PHP Unit Testing framework.",
1472 | "homepage": "https://phpunit.de/",
1473 | "keywords": [
1474 | "phpunit",
1475 | "testing",
1476 | "xunit"
1477 | ],
1478 | "time": "2017-05-22T07:45:30+00:00"
1479 | },
1480 | {
1481 | "name": "phpunit/phpunit-mock-objects",
1482 | "version": "4.0.1",
1483 | "source": {
1484 | "type": "git",
1485 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
1486 | "reference": "eabce450df194817a7d7e27e19013569a903a2bf"
1487 | },
1488 | "dist": {
1489 | "type": "zip",
1490 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/eabce450df194817a7d7e27e19013569a903a2bf",
1491 | "reference": "eabce450df194817a7d7e27e19013569a903a2bf",
1492 | "shasum": ""
1493 | },
1494 | "require": {
1495 | "doctrine/instantiator": "^1.0.2",
1496 | "php": "^7.0",
1497 | "phpunit/php-text-template": "^1.2",
1498 | "sebastian/exporter": "^3.0"
1499 | },
1500 | "conflict": {
1501 | "phpunit/phpunit": "<6.0"
1502 | },
1503 | "require-dev": {
1504 | "phpunit/phpunit": "^6.0"
1505 | },
1506 | "suggest": {
1507 | "ext-soap": "*"
1508 | },
1509 | "type": "library",
1510 | "extra": {
1511 | "branch-alias": {
1512 | "dev-master": "4.0.x-dev"
1513 | }
1514 | },
1515 | "autoload": {
1516 | "classmap": [
1517 | "src/"
1518 | ]
1519 | },
1520 | "notification-url": "https://packagist.org/downloads/",
1521 | "license": [
1522 | "BSD-3-Clause"
1523 | ],
1524 | "authors": [
1525 | {
1526 | "name": "Sebastian Bergmann",
1527 | "email": "sb@sebastian-bergmann.de",
1528 | "role": "lead"
1529 | }
1530 | ],
1531 | "description": "Mock Object library for PHPUnit",
1532 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
1533 | "keywords": [
1534 | "mock",
1535 | "xunit"
1536 | ],
1537 | "time": "2017-03-03T06:30:20+00:00"
1538 | },
1539 | {
1540 | "name": "sebastian/code-unit-reverse-lookup",
1541 | "version": "1.0.1",
1542 | "source": {
1543 | "type": "git",
1544 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
1545 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
1546 | },
1547 | "dist": {
1548 | "type": "zip",
1549 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
1550 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
1551 | "shasum": ""
1552 | },
1553 | "require": {
1554 | "php": "^5.6 || ^7.0"
1555 | },
1556 | "require-dev": {
1557 | "phpunit/phpunit": "^5.7 || ^6.0"
1558 | },
1559 | "type": "library",
1560 | "extra": {
1561 | "branch-alias": {
1562 | "dev-master": "1.0.x-dev"
1563 | }
1564 | },
1565 | "autoload": {
1566 | "classmap": [
1567 | "src/"
1568 | ]
1569 | },
1570 | "notification-url": "https://packagist.org/downloads/",
1571 | "license": [
1572 | "BSD-3-Clause"
1573 | ],
1574 | "authors": [
1575 | {
1576 | "name": "Sebastian Bergmann",
1577 | "email": "sebastian@phpunit.de"
1578 | }
1579 | ],
1580 | "description": "Looks up which function or method a line of code belongs to",
1581 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
1582 | "time": "2017-03-04T06:30:41+00:00"
1583 | },
1584 | {
1585 | "name": "sebastian/comparator",
1586 | "version": "2.0.0",
1587 | "source": {
1588 | "type": "git",
1589 | "url": "https://github.com/sebastianbergmann/comparator.git",
1590 | "reference": "20f84f468cb67efee293246e6a09619b891f55f0"
1591 | },
1592 | "dist": {
1593 | "type": "zip",
1594 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/20f84f468cb67efee293246e6a09619b891f55f0",
1595 | "reference": "20f84f468cb67efee293246e6a09619b891f55f0",
1596 | "shasum": ""
1597 | },
1598 | "require": {
1599 | "php": "^7.0",
1600 | "sebastian/diff": "^1.2",
1601 | "sebastian/exporter": "^3.0"
1602 | },
1603 | "require-dev": {
1604 | "phpunit/phpunit": "^6.0"
1605 | },
1606 | "type": "library",
1607 | "extra": {
1608 | "branch-alias": {
1609 | "dev-master": "2.0.x-dev"
1610 | }
1611 | },
1612 | "autoload": {
1613 | "classmap": [
1614 | "src/"
1615 | ]
1616 | },
1617 | "notification-url": "https://packagist.org/downloads/",
1618 | "license": [
1619 | "BSD-3-Clause"
1620 | ],
1621 | "authors": [
1622 | {
1623 | "name": "Jeff Welch",
1624 | "email": "whatthejeff@gmail.com"
1625 | },
1626 | {
1627 | "name": "Volker Dusch",
1628 | "email": "github@wallbash.com"
1629 | },
1630 | {
1631 | "name": "Bernhard Schussek",
1632 | "email": "bschussek@2bepublished.at"
1633 | },
1634 | {
1635 | "name": "Sebastian Bergmann",
1636 | "email": "sebastian@phpunit.de"
1637 | }
1638 | ],
1639 | "description": "Provides the functionality to compare PHP values for equality",
1640 | "homepage": "http://www.github.com/sebastianbergmann/comparator",
1641 | "keywords": [
1642 | "comparator",
1643 | "compare",
1644 | "equality"
1645 | ],
1646 | "time": "2017-03-03T06:26:08+00:00"
1647 | },
1648 | {
1649 | "name": "sebastian/diff",
1650 | "version": "1.4.3",
1651 | "source": {
1652 | "type": "git",
1653 | "url": "https://github.com/sebastianbergmann/diff.git",
1654 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4"
1655 | },
1656 | "dist": {
1657 | "type": "zip",
1658 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4",
1659 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4",
1660 | "shasum": ""
1661 | },
1662 | "require": {
1663 | "php": "^5.3.3 || ^7.0"
1664 | },
1665 | "require-dev": {
1666 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
1667 | },
1668 | "type": "library",
1669 | "extra": {
1670 | "branch-alias": {
1671 | "dev-master": "1.4-dev"
1672 | }
1673 | },
1674 | "autoload": {
1675 | "classmap": [
1676 | "src/"
1677 | ]
1678 | },
1679 | "notification-url": "https://packagist.org/downloads/",
1680 | "license": [
1681 | "BSD-3-Clause"
1682 | ],
1683 | "authors": [
1684 | {
1685 | "name": "Kore Nordmann",
1686 | "email": "mail@kore-nordmann.de"
1687 | },
1688 | {
1689 | "name": "Sebastian Bergmann",
1690 | "email": "sebastian@phpunit.de"
1691 | }
1692 | ],
1693 | "description": "Diff implementation",
1694 | "homepage": "https://github.com/sebastianbergmann/diff",
1695 | "keywords": [
1696 | "diff"
1697 | ],
1698 | "time": "2017-05-22T07:24:03+00:00"
1699 | },
1700 | {
1701 | "name": "sebastian/environment",
1702 | "version": "3.0.3",
1703 | "source": {
1704 | "type": "git",
1705 | "url": "https://github.com/sebastianbergmann/environment.git",
1706 | "reference": "02b6b2c7aefe2cdb1185b8dbf8718b0bcedf3ab3"
1707 | },
1708 | "dist": {
1709 | "type": "zip",
1710 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/02b6b2c7aefe2cdb1185b8dbf8718b0bcedf3ab3",
1711 | "reference": "02b6b2c7aefe2cdb1185b8dbf8718b0bcedf3ab3",
1712 | "shasum": ""
1713 | },
1714 | "require": {
1715 | "php": "^7.0"
1716 | },
1717 | "require-dev": {
1718 | "phpunit/phpunit": "^6.1"
1719 | },
1720 | "type": "library",
1721 | "extra": {
1722 | "branch-alias": {
1723 | "dev-master": "3.0.x-dev"
1724 | }
1725 | },
1726 | "autoload": {
1727 | "classmap": [
1728 | "src/"
1729 | ]
1730 | },
1731 | "notification-url": "https://packagist.org/downloads/",
1732 | "license": [
1733 | "BSD-3-Clause"
1734 | ],
1735 | "authors": [
1736 | {
1737 | "name": "Sebastian Bergmann",
1738 | "email": "sebastian@phpunit.de"
1739 | }
1740 | ],
1741 | "description": "Provides functionality to handle HHVM/PHP environments",
1742 | "homepage": "http://www.github.com/sebastianbergmann/environment",
1743 | "keywords": [
1744 | "Xdebug",
1745 | "environment",
1746 | "hhvm"
1747 | ],
1748 | "time": "2017-05-18T10:10:00+00:00"
1749 | },
1750 | {
1751 | "name": "sebastian/exporter",
1752 | "version": "3.1.0",
1753 | "source": {
1754 | "type": "git",
1755 | "url": "https://github.com/sebastianbergmann/exporter.git",
1756 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937"
1757 | },
1758 | "dist": {
1759 | "type": "zip",
1760 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937",
1761 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937",
1762 | "shasum": ""
1763 | },
1764 | "require": {
1765 | "php": "^7.0",
1766 | "sebastian/recursion-context": "^3.0"
1767 | },
1768 | "require-dev": {
1769 | "ext-mbstring": "*",
1770 | "phpunit/phpunit": "^6.0"
1771 | },
1772 | "type": "library",
1773 | "extra": {
1774 | "branch-alias": {
1775 | "dev-master": "3.1.x-dev"
1776 | }
1777 | },
1778 | "autoload": {
1779 | "classmap": [
1780 | "src/"
1781 | ]
1782 | },
1783 | "notification-url": "https://packagist.org/downloads/",
1784 | "license": [
1785 | "BSD-3-Clause"
1786 | ],
1787 | "authors": [
1788 | {
1789 | "name": "Jeff Welch",
1790 | "email": "whatthejeff@gmail.com"
1791 | },
1792 | {
1793 | "name": "Volker Dusch",
1794 | "email": "github@wallbash.com"
1795 | },
1796 | {
1797 | "name": "Bernhard Schussek",
1798 | "email": "bschussek@2bepublished.at"
1799 | },
1800 | {
1801 | "name": "Sebastian Bergmann",
1802 | "email": "sebastian@phpunit.de"
1803 | },
1804 | {
1805 | "name": "Adam Harvey",
1806 | "email": "aharvey@php.net"
1807 | }
1808 | ],
1809 | "description": "Provides the functionality to export PHP variables for visualization",
1810 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
1811 | "keywords": [
1812 | "export",
1813 | "exporter"
1814 | ],
1815 | "time": "2017-04-03T13:19:02+00:00"
1816 | },
1817 | {
1818 | "name": "sebastian/global-state",
1819 | "version": "2.0.0",
1820 | "source": {
1821 | "type": "git",
1822 | "url": "https://github.com/sebastianbergmann/global-state.git",
1823 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
1824 | },
1825 | "dist": {
1826 | "type": "zip",
1827 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
1828 | "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
1829 | "shasum": ""
1830 | },
1831 | "require": {
1832 | "php": "^7.0"
1833 | },
1834 | "require-dev": {
1835 | "phpunit/phpunit": "^6.0"
1836 | },
1837 | "suggest": {
1838 | "ext-uopz": "*"
1839 | },
1840 | "type": "library",
1841 | "extra": {
1842 | "branch-alias": {
1843 | "dev-master": "2.0-dev"
1844 | }
1845 | },
1846 | "autoload": {
1847 | "classmap": [
1848 | "src/"
1849 | ]
1850 | },
1851 | "notification-url": "https://packagist.org/downloads/",
1852 | "license": [
1853 | "BSD-3-Clause"
1854 | ],
1855 | "authors": [
1856 | {
1857 | "name": "Sebastian Bergmann",
1858 | "email": "sebastian@phpunit.de"
1859 | }
1860 | ],
1861 | "description": "Snapshotting of global state",
1862 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
1863 | "keywords": [
1864 | "global state"
1865 | ],
1866 | "time": "2017-04-27T15:39:26+00:00"
1867 | },
1868 | {
1869 | "name": "sebastian/object-enumerator",
1870 | "version": "3.0.2",
1871 | "source": {
1872 | "type": "git",
1873 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1874 | "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8"
1875 | },
1876 | "dist": {
1877 | "type": "zip",
1878 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/31dd3379d16446c5d86dec32ab1ad1f378581ad8",
1879 | "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8",
1880 | "shasum": ""
1881 | },
1882 | "require": {
1883 | "php": "^7.0",
1884 | "sebastian/object-reflector": "^1.0",
1885 | "sebastian/recursion-context": "^3.0"
1886 | },
1887 | "require-dev": {
1888 | "phpunit/phpunit": "^6.0"
1889 | },
1890 | "type": "library",
1891 | "extra": {
1892 | "branch-alias": {
1893 | "dev-master": "3.0.x-dev"
1894 | }
1895 | },
1896 | "autoload": {
1897 | "classmap": [
1898 | "src/"
1899 | ]
1900 | },
1901 | "notification-url": "https://packagist.org/downloads/",
1902 | "license": [
1903 | "BSD-3-Clause"
1904 | ],
1905 | "authors": [
1906 | {
1907 | "name": "Sebastian Bergmann",
1908 | "email": "sebastian@phpunit.de"
1909 | }
1910 | ],
1911 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1912 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1913 | "time": "2017-03-12T15:17:29+00:00"
1914 | },
1915 | {
1916 | "name": "sebastian/object-reflector",
1917 | "version": "1.1.1",
1918 | "source": {
1919 | "type": "git",
1920 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
1921 | "reference": "773f97c67f28de00d397be301821b06708fca0be"
1922 | },
1923 | "dist": {
1924 | "type": "zip",
1925 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be",
1926 | "reference": "773f97c67f28de00d397be301821b06708fca0be",
1927 | "shasum": ""
1928 | },
1929 | "require": {
1930 | "php": "^7.0"
1931 | },
1932 | "require-dev": {
1933 | "phpunit/phpunit": "^6.0"
1934 | },
1935 | "type": "library",
1936 | "extra": {
1937 | "branch-alias": {
1938 | "dev-master": "1.1-dev"
1939 | }
1940 | },
1941 | "autoload": {
1942 | "classmap": [
1943 | "src/"
1944 | ]
1945 | },
1946 | "notification-url": "https://packagist.org/downloads/",
1947 | "license": [
1948 | "BSD-3-Clause"
1949 | ],
1950 | "authors": [
1951 | {
1952 | "name": "Sebastian Bergmann",
1953 | "email": "sebastian@phpunit.de"
1954 | }
1955 | ],
1956 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
1957 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
1958 | "time": "2017-03-29T09:07:27+00:00"
1959 | },
1960 | {
1961 | "name": "sebastian/recursion-context",
1962 | "version": "3.0.0",
1963 | "source": {
1964 | "type": "git",
1965 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1966 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8"
1967 | },
1968 | "dist": {
1969 | "type": "zip",
1970 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
1971 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
1972 | "shasum": ""
1973 | },
1974 | "require": {
1975 | "php": "^7.0"
1976 | },
1977 | "require-dev": {
1978 | "phpunit/phpunit": "^6.0"
1979 | },
1980 | "type": "library",
1981 | "extra": {
1982 | "branch-alias": {
1983 | "dev-master": "3.0.x-dev"
1984 | }
1985 | },
1986 | "autoload": {
1987 | "classmap": [
1988 | "src/"
1989 | ]
1990 | },
1991 | "notification-url": "https://packagist.org/downloads/",
1992 | "license": [
1993 | "BSD-3-Clause"
1994 | ],
1995 | "authors": [
1996 | {
1997 | "name": "Jeff Welch",
1998 | "email": "whatthejeff@gmail.com"
1999 | },
2000 | {
2001 | "name": "Sebastian Bergmann",
2002 | "email": "sebastian@phpunit.de"
2003 | },
2004 | {
2005 | "name": "Adam Harvey",
2006 | "email": "aharvey@php.net"
2007 | }
2008 | ],
2009 | "description": "Provides functionality to recursively process PHP variables",
2010 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
2011 | "time": "2017-03-03T06:23:57+00:00"
2012 | },
2013 | {
2014 | "name": "sebastian/resource-operations",
2015 | "version": "1.0.0",
2016 | "source": {
2017 | "type": "git",
2018 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
2019 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
2020 | },
2021 | "dist": {
2022 | "type": "zip",
2023 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
2024 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
2025 | "shasum": ""
2026 | },
2027 | "require": {
2028 | "php": ">=5.6.0"
2029 | },
2030 | "type": "library",
2031 | "extra": {
2032 | "branch-alias": {
2033 | "dev-master": "1.0.x-dev"
2034 | }
2035 | },
2036 | "autoload": {
2037 | "classmap": [
2038 | "src/"
2039 | ]
2040 | },
2041 | "notification-url": "https://packagist.org/downloads/",
2042 | "license": [
2043 | "BSD-3-Clause"
2044 | ],
2045 | "authors": [
2046 | {
2047 | "name": "Sebastian Bergmann",
2048 | "email": "sebastian@phpunit.de"
2049 | }
2050 | ],
2051 | "description": "Provides a list of PHP built-in functions that operate on resources",
2052 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
2053 | "time": "2015-07-28T20:34:47+00:00"
2054 | },
2055 | {
2056 | "name": "sebastian/version",
2057 | "version": "2.0.1",
2058 | "source": {
2059 | "type": "git",
2060 | "url": "https://github.com/sebastianbergmann/version.git",
2061 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
2062 | },
2063 | "dist": {
2064 | "type": "zip",
2065 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
2066 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
2067 | "shasum": ""
2068 | },
2069 | "require": {
2070 | "php": ">=5.6"
2071 | },
2072 | "type": "library",
2073 | "extra": {
2074 | "branch-alias": {
2075 | "dev-master": "2.0.x-dev"
2076 | }
2077 | },
2078 | "autoload": {
2079 | "classmap": [
2080 | "src/"
2081 | ]
2082 | },
2083 | "notification-url": "https://packagist.org/downloads/",
2084 | "license": [
2085 | "BSD-3-Clause"
2086 | ],
2087 | "authors": [
2088 | {
2089 | "name": "Sebastian Bergmann",
2090 | "email": "sebastian@phpunit.de",
2091 | "role": "lead"
2092 | }
2093 | ],
2094 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
2095 | "homepage": "https://github.com/sebastianbergmann/version",
2096 | "time": "2016-10-03T07:35:21+00:00"
2097 | },
2098 | {
2099 | "name": "squizlabs/php_codesniffer",
2100 | "version": "2.9.0",
2101 | "source": {
2102 | "type": "git",
2103 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
2104 | "reference": "f7dfecbee89d68ab475a6c9e17d22bc9b69aed97"
2105 | },
2106 | "dist": {
2107 | "type": "zip",
2108 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f7dfecbee89d68ab475a6c9e17d22bc9b69aed97",
2109 | "reference": "f7dfecbee89d68ab475a6c9e17d22bc9b69aed97",
2110 | "shasum": ""
2111 | },
2112 | "require": {
2113 | "ext-simplexml": "*",
2114 | "ext-tokenizer": "*",
2115 | "ext-xmlwriter": "*",
2116 | "php": ">=5.1.2"
2117 | },
2118 | "require-dev": {
2119 | "phpunit/phpunit": "~4.0"
2120 | },
2121 | "bin": [
2122 | "scripts/phpcs",
2123 | "scripts/phpcbf"
2124 | ],
2125 | "type": "library",
2126 | "extra": {
2127 | "branch-alias": {
2128 | "dev-master": "2.x-dev"
2129 | }
2130 | },
2131 | "autoload": {
2132 | "classmap": [
2133 | "CodeSniffer.php",
2134 | "CodeSniffer/CLI.php",
2135 | "CodeSniffer/Exception.php",
2136 | "CodeSniffer/File.php",
2137 | "CodeSniffer/Fixer.php",
2138 | "CodeSniffer/Report.php",
2139 | "CodeSniffer/Reporting.php",
2140 | "CodeSniffer/Sniff.php",
2141 | "CodeSniffer/Tokens.php",
2142 | "CodeSniffer/Reports/",
2143 | "CodeSniffer/Tokenizers/",
2144 | "CodeSniffer/DocGenerators/",
2145 | "CodeSniffer/Standards/AbstractPatternSniff.php",
2146 | "CodeSniffer/Standards/AbstractScopeSniff.php",
2147 | "CodeSniffer/Standards/AbstractVariableSniff.php",
2148 | "CodeSniffer/Standards/IncorrectPatternException.php",
2149 | "CodeSniffer/Standards/Generic/Sniffs/",
2150 | "CodeSniffer/Standards/MySource/Sniffs/",
2151 | "CodeSniffer/Standards/PEAR/Sniffs/",
2152 | "CodeSniffer/Standards/PSR1/Sniffs/",
2153 | "CodeSniffer/Standards/PSR2/Sniffs/",
2154 | "CodeSniffer/Standards/Squiz/Sniffs/",
2155 | "CodeSniffer/Standards/Zend/Sniffs/"
2156 | ]
2157 | },
2158 | "notification-url": "https://packagist.org/downloads/",
2159 | "license": [
2160 | "BSD-3-Clause"
2161 | ],
2162 | "authors": [
2163 | {
2164 | "name": "Greg Sherwood",
2165 | "role": "lead"
2166 | }
2167 | ],
2168 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
2169 | "homepage": "http://www.squizlabs.com/php-codesniffer",
2170 | "keywords": [
2171 | "phpcs",
2172 | "standards"
2173 | ],
2174 | "time": "2017-05-03T23:30:39+00:00"
2175 | },
2176 | {
2177 | "name": "symfony/browser-kit",
2178 | "version": "v3.2.8",
2179 | "source": {
2180 | "type": "git",
2181 | "url": "https://github.com/symfony/browser-kit.git",
2182 | "reference": "9fab1ab6f77b77f3df5fc5250fc6956811699b57"
2183 | },
2184 | "dist": {
2185 | "type": "zip",
2186 | "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9fab1ab6f77b77f3df5fc5250fc6956811699b57",
2187 | "reference": "9fab1ab6f77b77f3df5fc5250fc6956811699b57",
2188 | "shasum": ""
2189 | },
2190 | "require": {
2191 | "php": ">=5.5.9",
2192 | "symfony/dom-crawler": "~2.8|~3.0"
2193 | },
2194 | "require-dev": {
2195 | "symfony/css-selector": "~2.8|~3.0",
2196 | "symfony/process": "~2.8|~3.0"
2197 | },
2198 | "suggest": {
2199 | "symfony/process": ""
2200 | },
2201 | "type": "library",
2202 | "extra": {
2203 | "branch-alias": {
2204 | "dev-master": "3.2-dev"
2205 | }
2206 | },
2207 | "autoload": {
2208 | "psr-4": {
2209 | "Symfony\\Component\\BrowserKit\\": ""
2210 | },
2211 | "exclude-from-classmap": [
2212 | "/Tests/"
2213 | ]
2214 | },
2215 | "notification-url": "https://packagist.org/downloads/",
2216 | "license": [
2217 | "MIT"
2218 | ],
2219 | "authors": [
2220 | {
2221 | "name": "Fabien Potencier",
2222 | "email": "fabien@symfony.com"
2223 | },
2224 | {
2225 | "name": "Symfony Community",
2226 | "homepage": "https://symfony.com/contributors"
2227 | }
2228 | ],
2229 | "description": "Symfony BrowserKit Component",
2230 | "homepage": "https://symfony.com",
2231 | "time": "2017-04-12T14:13:17+00:00"
2232 | },
2233 | {
2234 | "name": "symfony/dom-crawler",
2235 | "version": "v3.2.8",
2236 | "source": {
2237 | "type": "git",
2238 | "url": "https://github.com/symfony/dom-crawler.git",
2239 | "reference": "f1ad34e8af09ed17570e027cf0c58a12eddec286"
2240 | },
2241 | "dist": {
2242 | "type": "zip",
2243 | "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/f1ad34e8af09ed17570e027cf0c58a12eddec286",
2244 | "reference": "f1ad34e8af09ed17570e027cf0c58a12eddec286",
2245 | "shasum": ""
2246 | },
2247 | "require": {
2248 | "php": ">=5.5.9",
2249 | "symfony/polyfill-mbstring": "~1.0"
2250 | },
2251 | "require-dev": {
2252 | "symfony/css-selector": "~2.8|~3.0"
2253 | },
2254 | "suggest": {
2255 | "symfony/css-selector": ""
2256 | },
2257 | "type": "library",
2258 | "extra": {
2259 | "branch-alias": {
2260 | "dev-master": "3.2-dev"
2261 | }
2262 | },
2263 | "autoload": {
2264 | "psr-4": {
2265 | "Symfony\\Component\\DomCrawler\\": ""
2266 | },
2267 | "exclude-from-classmap": [
2268 | "/Tests/"
2269 | ]
2270 | },
2271 | "notification-url": "https://packagist.org/downloads/",
2272 | "license": [
2273 | "MIT"
2274 | ],
2275 | "authors": [
2276 | {
2277 | "name": "Fabien Potencier",
2278 | "email": "fabien@symfony.com"
2279 | },
2280 | {
2281 | "name": "Symfony Community",
2282 | "homepage": "https://symfony.com/contributors"
2283 | }
2284 | ],
2285 | "description": "Symfony DomCrawler Component",
2286 | "homepage": "https://symfony.com",
2287 | "time": "2017-04-12T14:13:17+00:00"
2288 | },
2289 | {
2290 | "name": "theseer/tokenizer",
2291 | "version": "1.1.0",
2292 | "source": {
2293 | "type": "git",
2294 | "url": "https://github.com/theseer/tokenizer.git",
2295 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b"
2296 | },
2297 | "dist": {
2298 | "type": "zip",
2299 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b",
2300 | "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b",
2301 | "shasum": ""
2302 | },
2303 | "require": {
2304 | "ext-dom": "*",
2305 | "ext-tokenizer": "*",
2306 | "ext-xmlwriter": "*",
2307 | "php": "^7.0"
2308 | },
2309 | "type": "library",
2310 | "autoload": {
2311 | "classmap": [
2312 | "src/"
2313 | ]
2314 | },
2315 | "notification-url": "https://packagist.org/downloads/",
2316 | "license": [
2317 | "BSD-3-Clause"
2318 | ],
2319 | "authors": [
2320 | {
2321 | "name": "Arne Blankerts",
2322 | "email": "arne@blankerts.de",
2323 | "role": "Developer"
2324 | }
2325 | ],
2326 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
2327 | "time": "2017-04-07T12:08:54+00:00"
2328 | },
2329 | {
2330 | "name": "webmozart/assert",
2331 | "version": "1.2.0",
2332 | "source": {
2333 | "type": "git",
2334 | "url": "https://github.com/webmozart/assert.git",
2335 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f"
2336 | },
2337 | "dist": {
2338 | "type": "zip",
2339 | "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f",
2340 | "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f",
2341 | "shasum": ""
2342 | },
2343 | "require": {
2344 | "php": "^5.3.3 || ^7.0"
2345 | },
2346 | "require-dev": {
2347 | "phpunit/phpunit": "^4.6",
2348 | "sebastian/version": "^1.0.1"
2349 | },
2350 | "type": "library",
2351 | "extra": {
2352 | "branch-alias": {
2353 | "dev-master": "1.3-dev"
2354 | }
2355 | },
2356 | "autoload": {
2357 | "psr-4": {
2358 | "Webmozart\\Assert\\": "src/"
2359 | }
2360 | },
2361 | "notification-url": "https://packagist.org/downloads/",
2362 | "license": [
2363 | "MIT"
2364 | ],
2365 | "authors": [
2366 | {
2367 | "name": "Bernhard Schussek",
2368 | "email": "bschussek@gmail.com"
2369 | }
2370 | ],
2371 | "description": "Assertions to validate method input/output with nice error messages.",
2372 | "keywords": [
2373 | "assert",
2374 | "check",
2375 | "validate"
2376 | ],
2377 | "time": "2016-11-23T20:04:58+00:00"
2378 | },
2379 | {
2380 | "name": "wmde/psr-log-test-doubles",
2381 | "version": "2.1.0",
2382 | "source": {
2383 | "type": "git",
2384 | "url": "https://github.com/wmde/PsrLogTestDoubles.git",
2385 | "reference": "95e1e6bd06d18b11575eb0dd0108b08e6a742463"
2386 | },
2387 | "dist": {
2388 | "type": "zip",
2389 | "url": "https://api.github.com/repos/wmde/PsrLogTestDoubles/zipball/95e1e6bd06d18b11575eb0dd0108b08e6a742463",
2390 | "reference": "95e1e6bd06d18b11575eb0dd0108b08e6a742463",
2391 | "shasum": ""
2392 | },
2393 | "require": {
2394 | "php": ">=7.0",
2395 | "psr/log": "~1.0"
2396 | },
2397 | "require-dev": {
2398 | "mediawiki/mediawiki-codesniffer": "~0.6.0",
2399 | "ockcyp/covers-validator": "~0.4",
2400 | "squizlabs/php_codesniffer": "~2.5"
2401 | },
2402 | "type": "library",
2403 | "extra": {
2404 | "branch-alias": {
2405 | "dev-master": "2.1.x-dev"
2406 | }
2407 | },
2408 | "autoload": {
2409 | "psr-4": {
2410 | "WMDE\\PsrLogTestDoubles\\": "src/"
2411 | }
2412 | },
2413 | "notification-url": "https://packagist.org/downloads/",
2414 | "license": [
2415 | "GPL-2.0+"
2416 | ],
2417 | "description": "Test Doubles for the PSR-3 Logger Interface",
2418 | "homepage": "https://github.com/wmde/PsrLogTestDoubles",
2419 | "keywords": [
2420 | "Fixture",
2421 | "LoggerSpy",
2422 | "Test Doubles",
2423 | "fixtures",
2424 | "log",
2425 | "logger spy",
2426 | "mock",
2427 | "mocks",
2428 | "psr",
2429 | "psr-3",
2430 | "spies",
2431 | "spy",
2432 | "test",
2433 | "test double"
2434 | ],
2435 | "time": "2017-01-17T09:04:52+00:00"
2436 | }
2437 | ],
2438 | "aliases": [],
2439 | "minimum-stability": "stable",
2440 | "stability-flags": [],
2441 | "prefer-stable": false,
2442 | "prefer-lowest": false,
2443 | "platform": {
2444 | "php": ">=7.1"
2445 | },
2446 | "platform-dev": []
2447 | }
2448 |
--------------------------------------------------------------------------------