@@ -123,7 +123,7 @@ protected function addMetricsOptions()
123123 /**
124124 * Returns the metrics URL and collection information for the selected environment.
125125 *
126- * @return array{' href' : string, ' collection' : string}|false
126+ * @return array{href: string, collection: string, max_range : string}|false
127127 * The link data or false on failure.
128128 */
129129 protected function getMetricsLink (Environment $ environment )
@@ -332,10 +332,11 @@ protected function fetchMetrics(InputInterface $input, TimeSpec $timeSpec, Envir
332332 * @see self::startTime, self::$endTime, self::$interval
333333 *
334334 * @param InputInterface $input
335+ * @param Environment|null $environment
335336 *
336337 * @return TimeSpec|false
337338 */
338- protected function validateTimeInput (InputInterface $ input )
339+ protected function validateTimeInput (InputInterface $ input, Environment $ environment = null )
339340 {
340341 $ interval = null ;
341342 if ($ intervalStr = $ input ->getOption ('interval ' )) {
@@ -361,13 +362,24 @@ protected function validateTimeInput(InputInterface $input)
361362 $ endTime = time ();
362363 }
363364 if ($ rangeStr = $ input ->getOption ('range ' )) {
364- $ rangeSeconds = (new Duration ())->toSeconds ($ rangeStr );
365+ $ rangeDuration = $ this ->parseDuration ($ rangeStr );
366+ if (!$ rangeDuration ) {
367+ $ this ->stdErr ->writeln ('Invalid --range: <error> ' . $ rangeStr . '</error> ' );
368+ return false ;
369+ }
370+ $ rangeSeconds = $ rangeDuration ->toSeconds ();
365371 if (empty ($ rangeSeconds )) {
366372 $ this ->stdErr ->writeln ('Invalid --range: <error> ' . $ rangeStr . '</error> ' );
367373 return false ;
368374 } elseif ($ rangeSeconds < self ::MIN_RANGE ) {
369375 $ this ->stdErr ->writeln (\sprintf ('The --range <error>%s</error> is too short: it must be at least %d seconds (%s). ' , $ rangeStr , self ::MIN_RANGE , (new Duration ())->humanize (self ::MIN_RANGE )));
370376 return false ;
377+ } elseif ($ environment && ($ link = $ this ->getMetricsLink ($ environment )) && isset ($ link ['max_range ' ])) {
378+ $ maxRange = $ this ->parseDuration ($ link ['max_range ' ]);
379+ if ($ rangeSeconds > $ maxRange ->toSeconds ()) {
380+ $ this ->stdErr ->writeln (\sprintf ('The --range <error>%s</error> is too long: the maximum is %s. ' , $ rangeStr , $ link ['max_range ' ]));
381+ return false ;
382+ }
371383 }
372384 $ rangeSeconds = \intval ($ rangeSeconds );
373385 } else {
@@ -421,6 +433,22 @@ private function defaultInterval($range)
421433 return (int ) $ interval ;
422434 }
423435
436+ /**
437+ * @param string $duration
438+ * @return Duration|false
439+ */
440+ private function parseDuration ($ duration )
441+ {
442+ if (substr ($ duration , -1 ) === 'y ' ) {
443+ $ num = rtrim ($ duration , 'y ' );
444+ if (!is_numeric ($ num )) {
445+ return false ;
446+ }
447+ return new Duration (intval ($ num ) * 365.25 * 86400 );
448+ }
449+ return (new Duration ())->parse ($ duration );
450+ }
451+
424452 /**
425453 * Returns the deployment type of an environment (needed for differing queries).
426454 *
0 commit comments