SchemaSnapshotCommand::createSnapshot()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 8
c 1
b 0
f 0
dl 0
loc 15
ccs 0
cts 13
cp 0
rs 10
cc 4
nc 3
nop 3
crap 20
1
<?php
2
/*******************************************************************************
3
 *  This file is part of the GraphQL Bundle package.
4
 *
5
 *  (c) YnloUltratech <[email protected]>
6
 *
7
 *  For the full copyright and license information, please view the LICENSE
8
 *  file that was distributed with this source code.
9
 ******************************************************************************/
10
11
namespace Ynlo\GraphQLBundle\Command;
12
13
use Symfony\Component\Console\Command\Command;
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Input\InputOption;
16
use Symfony\Component\Console\Output\OutputInterface;
17
use Ynlo\GraphQLBundle\Definition\Registry\DefinitionRegistry;
18
use Ynlo\GraphQLBundle\Schema\SchemaSnapshot;
19
20
class SchemaSnapshotCommand extends Command
21
{
22
23
    /**
24
     * @var string
25
     */
26
    protected $projectDir;
27
28
    /**
29
     * @var SchemaSnapshot
30
     */
31
    protected $schemaSnapshot;
32
33
    /**
34
     * @var array
35
     */
36
    protected $endpoints;
37
38
    /**
39
     * GraphQLSchemaExportCommand constructor.
40
     *
41
     * @param SchemaSnapshot $schemaSnapshot
42
     * @param array          $endpoints
43
     * @param string         $projectDir
44
     */
45
    public function __construct(SchemaSnapshot $schemaSnapshot, $endpoints, $projectDir)
46
    {
47
        $this->schemaSnapshot = $schemaSnapshot;
48
        $this->endpoints = $endpoints;
49
        $this->projectDir = $projectDir;
50
51
        parent::__construct();
52
    }
53
54
    /**
55
     * {@inheritDoc}
56
     */
57
    protected function configure()
58
    {
59
        $this->setName('graphql:schema:snapshot')
60
             ->setDescription('Create a snapshot of your schema to compare using behat tests.')
61
             ->addOption('endpoint', null, InputOption::VALUE_REQUIRED, 'Name of the endpoint to export', DefinitionRegistry::DEFAULT_ENDPOINT)
62
             ->addOption('all', 'a', InputOption::VALUE_NONE, 'Create snapshot for all registered endpoints')
63
             ->addOption('strict', null, InputOption::VALUE_NONE, 'When use strict mode the snapshot must be updated every time your schema change')
64
             ->addOption('features', null, InputOption::VALUE_REQUIRED, 'Path where should be located the generated features and fixtures');
65
    }
66
67
    /**
68
     * {@inheritDoc}
69
     */
70
    protected function execute(InputInterface $input, OutputInterface $output)
71
    {
72
        $dir = $input->getOption('features');
73
        if (!$dir) {
74
            $dir = $this->projectDir.'/features';
75
        }
76
77
        if (!file_exists($dir)) {
78
            if (!mkdir($dir, 0777, true) && !is_dir($dir)) {
79
                throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
80
            }
81
        }
82
83
        $strictMode = $input->getOption('strict');
84
85
        $all = $input->getOption('all');
86
        if ($all && $this->endpoints) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->endpoints of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
87
            foreach ($this->endpoints as $endpoint) {
88
                $this->createSnapshot($endpoint, $dir, $strictMode);
89
            }
90
        } else {
91
            $this->createSnapshot($input->getOption('endpoint'), $dir, $strictMode);
92
        }
93
    }
94
95
    /**
96
     * @param string      $endpoint
97
     * @param string|null $where
98
     * @param bool        $strictMode
99
     *
100
     * @throws \Exception
101
     */
102
    private function createSnapshot(string $endpoint, ?string $where = null, $strictMode = false): void
103
    {
104
        if ($this->endpoints && !\in_array($endpoint, $this->endpoints)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->endpoints of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
105
            if (DefinitionRegistry::DEFAULT_ENDPOINT === $endpoint) {
106
                throw new \Exception('Must specify a valid endpoint name or use the `--all` option');
107
            }
108
109
            throw new \Exception(
110
                sprintf('The are no valid endpoint called `%s`.', $endpoint)
111
            );
112
        }
113
114
        $snapshot = $this->schemaSnapshot->createSnapshot($endpoint);
115
        file_put_contents(sprintf('%s/%s.snapshot.json', $where, $endpoint), json_encode($snapshot, JSON_PRETTY_PRINT));
116
        $this->updateFeatureFile($where, $endpoint, $strictMode);
117
    }
118
119
    private function updateFeatureFile($where, $endpoint, $strictMode = false)
120
    {
121
        $header = <<<EOS
122
Feature: Schema Snapshot
123
124
EOS;
125
        $strictStep = null;
126
        if ($strictMode) {
127
            $strictStep = "    And current schema is same after latest snapshot\n";
128
        }
129
        $scenario = <<<EOS
130
131
  Scenario: Verify "$endpoint" Endpoint
132
    Given previous schema snapshot of "$endpoint" endpoint
133
    When compare with current schema
134
    Then current schema is compatible with latest snapshot
135
$strictStep
136
EOS;
137
138
139
        $featureFile = sprintf('%s/snapshot.feature', $where);
140
        if (!file_exists($featureFile)) {
141
            file_put_contents($featureFile, $header);
142
        }
143
144
        if (!preg_match("/\"$endpoint\" endpoint/", file_get_contents($featureFile))) {
145
            file_put_contents($featureFile, $scenario, FILE_APPEND);
146
        }
147
    }
148
}
149