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
|
|||
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
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 ![]() |
|||
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 |
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.