1313 */
1414class Checker
1515{
16+ protected const FILE_REQS = 'composer.lock ' ;
17+ protected const FILE_INSTALLED = 'installed.json ' ;
18+
1619 /**
1720 * @var string
1821 */
@@ -21,6 +24,10 @@ class Checker
2124 * @var string
2225 */
2326 private $ vendorDir ;
27+ /**
28+ * @var bool Is strictly required `composer.lock` files?
29+ */
30+ private $ strictReqs = true ;
2431
2532
2633 /**
@@ -71,17 +78,45 @@ public function validate(): void
7178 */
7279 public function isReqsValid (): bool
7380 {
74- $ definitions = $ this ->loadReqs ();
75- $ instalations = $ this ->loadInstalled ();
81+ try {
82+ $ definitions = $ this ->loadReqs ();
83+ $ instalations = $ this ->loadInstalled ();
84+
85+ $ diff = array_diff_assoc ($ definitions , $ instalations );
86+
87+ return count ($ diff ) === 0 ;
88+ } catch (FileReadException $ e ) {
89+ if ($ this ->strictReqs !== true && $ e ->getRequiredfile () === self ::FILE_REQS ) {
90+ // Ignore missing `composer.lock` file - not deployed to production?
91+ return true ;
92+ }
93+ throw $ e ;
94+ }
95+ }
7696
77- $ diff = array_diff_assoc ($ definitions , $ instalations );
7897
79- return count ($ diff ) === 0 ;
98+ /**
99+ * @return bool
100+ */
101+ public function isStrictReqs (): bool
102+ {
103+ return $ this ->strictReqs ;
104+ }
105+
106+ /**
107+ * @param bool $strictReqs
108+ * @return Checker
109+ */
110+ public function setStrictReqs (bool $ strictReqs ): self
111+ {
112+ $ this ->strictReqs = $ strictReqs ;
113+ return $ this ;
80114 }
81115
82116
83117 /**
84118 * @return array
119+ * @throws FileReadException
85120 * @throws RuntimeException
86121 */
87122 protected function loadReqs (): array
@@ -100,16 +135,18 @@ protected function loadReqs(): array
100135
101136 /**
102137 * @return array
138+ * @throws FileReadException
103139 * @throws RuntimeException
104140 */
105141 protected function loadReqsFile (): array
106142 {
107- return $ this ->readJsonFile ($ this ->rootDir . '/composer.lock ' );
143+ return $ this ->readJsonFile ($ this ->rootDir . '/ ' . self :: FILE_REQS );
108144 }
109145
110146
111147 /**
112148 * @return array
149+ * @throws FileReadException
113150 * @throws RuntimeException
114151 */
115152 protected function loadInstalled (): array
@@ -128,17 +165,19 @@ protected function loadInstalled(): array
128165
129166 /**
130167 * @return array
168+ * @throws FileReadException
131169 * @throws RuntimeException
132170 */
133171 protected function loadInstalledFile (): array
134172 {
135- return $ this ->readJsonFile ($ this ->vendorDir . '/composer/installed.json ' );
173+ return $ this ->readJsonFile ($ this ->vendorDir . '/composer/ ' . self :: FILE_INSTALLED );
136174 }
137175
138176
139177 /**
140178 * @param string $filename
141179 * @return array
180+ * @throws FileReadException
142181 * @throws RuntimeException
143182 */
144183 protected function readJsonFile (string $ filename ): array
@@ -151,15 +190,16 @@ protected function readJsonFile(string $filename): array
151190 /**
152191 * @param string $file
153192 * @return string
154- * @throws RuntimeException
193+ * @throws FileReadException
155194 * @link https://doc.nette.org/en/3.0/filesystem
156195 */
157196 protected function readFile (string $ file ): string
158197 {
159198 $ content = @file_get_contents ($ file ); // @ is escalated to exception
160199 if ($ content === false ) {
161200 $ lastError = preg_replace ('#^\w+\(.*?\): # ' , '' , (string )error_get_last ()['message ' ]);
162- throw new RuntimeException ("Unable to read file ' $ file'. " . $ lastError );
201+ $ requiredFile = basename ($ file );
202+ throw new FileReadException ($ requiredFile , "Unable to read file ' $ file'. " . $ lastError );
163203 }
164204 return $ content ;
165205 }
0 commit comments