@@ -58,7 +58,7 @@ public function handle(): int
5858 $ content = $ generator ->generate ($ groups , $ title );
5959
6060 if ($ this ->option ('check ' )) {
61- return $ this ->runCheck ($ content , $ resolvedOutput );
61+ return $ this ->runCheck ($ content , $ resolvedOutput, $ format );
6262 }
6363
6464 $ this ->writeOutput ($ content , $ resolvedOutput );
@@ -115,7 +115,9 @@ private function gatherCommands(): array
115115 continue ;
116116 }
117117
118- // Only-custom filter (overrides vendor filter)
118+ // Only-custom filter: restricts output to application-defined commands only
119+ // (matched against app_command_paths). Runs independently of the vendor
120+ // filter; application commands are never vendor commands.
119121 if ($ onlyCustom && ! $ this ->inspector ->isApplicationCommand ($ command , $ appPaths )) {
120122 continue ;
121123 }
@@ -213,8 +215,13 @@ private function writeOutput(string $content, string $absolutePath): void
213215 /**
214216 * Compare generated content against the existing file on disk.
215217 * Exits with code 1 when the file is missing or differs.
218+ *
219+ * Timestamps embedded by the generators (Markdown blockquote, JSON
220+ * "generated_at" field, HTML meta line) are stripped from both strings
221+ * before comparison so that --check does not fail solely because the
222+ * documentation was generated at an earlier point in time.
216223 */
217- private function runCheck (string $ content , string $ absolutePath ): int
224+ private function runCheck (string $ content , string $ absolutePath, string $ format ): int
218225 {
219226 if (! File ::exists ($ absolutePath )) {
220227 $ this ->error ("❌ Check failed: documentation file does not exist at [ {$ absolutePath }]. " );
@@ -225,7 +232,10 @@ private function runCheck(string $content, string $absolutePath): int
225232
226233 $ existing = File ::get ($ absolutePath );
227234
228- if (trim ($ existing ) === trim ($ content )) {
235+ $ normalizedExisting = $ this ->normalizeForCheck (trim ($ existing ), $ format );
236+ $ normalizedContent = $ this ->normalizeForCheck (trim ($ content ), $ format );
237+
238+ if ($ normalizedExisting === $ normalizedContent ) {
229239 $ this ->info ('✅ Documentation is up-to-date. ' );
230240
231241 return self ::SUCCESS ;
@@ -236,4 +246,26 @@ private function runCheck(string $content, string $absolutePath): int
236246
237247 return self ::FAILURE ;
238248 }
249+
250+ /**
251+ * Strip format-specific timestamp markers from generated content before
252+ * performing an equality check.
253+ *
254+ * Each generator embeds a live timestamp that changes on every run:
255+ * – Markdown : the "Auto-generated on …" blockquote line
256+ * – JSON : the "generated_at" top-level property
257+ * – HTML : the "Generated …" suffix inside the <p class="meta"> element
258+ *
259+ * Removing these markers allows --check to compare only the structural
260+ * content (commands, arguments, options, groups) and pass even when the
261+ * documentation file was generated at an earlier time.
262+ */
263+ private function normalizeForCheck (string $ content , string $ format ): string
264+ {
265+ return match (strtolower ($ format )) {
266+ 'json ' => (string ) preg_replace ('/"generated_at"\s*:\s*"[^"]*",?\n?/ ' , '' , $ content ),
267+ 'html ' => (string ) preg_replace ('/ — Generated [^<]+/ ' , '' , $ content ),
268+ default => (string ) preg_replace ('/^> Auto-generated on .+$/m ' , '' , $ content ),
269+ };
270+ }
239271}
0 commit comments