@@ -320,7 +320,6 @@ public static string ProductVersion
320320 }
321321 }
322322
323-
324323 return _productVersion ;
325324 }
326325 }
@@ -355,7 +354,7 @@ public static void MergeHeaders(IList<MockResponseHeader> allHeaders, IList<Mock
355354 }
356355
357356 public static JsonSerializerOptions JsonSerializerOptions => jsonSerializerOptions ;
358-
357+
359358 public static JsonDocumentOptions JsonDocumentOptions { get ; } = new ( )
360359 {
361360 AllowTrailingCommas = true ,
@@ -425,7 +424,8 @@ public static List<string> GetWildcardPatterns(List<string> urls)
425424 }
426425
427426 // For multiple URLs, find the common prefix
428- var paths = group . Select ( url => {
427+ var paths = group . Select ( url =>
428+ {
429429 if ( url . Contains ( '*' ) )
430430 {
431431 return url ;
@@ -518,10 +518,126 @@ public static string ReplaceVariables(string s, Dictionary<string, string> varia
518518 return s1 ;
519519 }
520520
521- public static string GetVersionString ( string productVersion )
521+ public static void ValidateSchemaVersion ( string schemaUrl , ILogger logger )
522+ {
523+ if ( string . IsNullOrWhiteSpace ( schemaUrl ) )
524+ {
525+ logger . LogDebug ( "Schema is empty, skipping schema version validation." ) ;
526+ return ;
527+ }
528+
529+ try
530+ {
531+ var uri = new Uri ( schemaUrl ) ;
532+ if ( uri . Segments . Length > 2 )
533+ {
534+ var schemaVersion = uri . Segments [ ^ 2 ]
535+ . TrimStart ( 'v' )
536+ . TrimEnd ( '/' ) ;
537+ var currentVersion = NormalizeVersion ( ProductVersion ) ;
538+ if ( CompareSemVer ( currentVersion , schemaVersion ) != 0 )
539+ {
540+ var currentSchemaUrl = uri . ToString ( ) . Replace ( $ "/v{ schemaVersion } /", $ "/v{ currentVersion } /") ;
541+ logger . LogWarning ( "The version of schema does not match the installed Dev Proxy version, the expected schema is {schema}" , currentSchemaUrl ) ;
542+ }
543+ }
544+ else
545+ {
546+ logger . LogDebug ( "Invalid schema {schemaUrl}, skipping schema version validation." , schemaUrl ) ;
547+ }
548+ }
549+ catch ( Exception ex )
550+ {
551+ logger . LogWarning ( "Invalid schema {schemaUrl}, skipping schema version validation. Error: {error}" , schemaUrl , ex . Message ) ;
552+ }
553+ }
554+
555+ /// <summary>
556+ /// Compares two semantic versions strings.
557+ /// </summary>
558+ /// <param name="a">ver1</param>
559+ /// <param name="b">ver2</param>
560+ /// <returns>
561+ /// Returns 0 if the versions are equal, -1 if a is less than b, and 1 if a is greater than b.
562+ /// An invalid argument is "rounded" to a minimal version.
563+ /// </returns>
564+ public static int CompareSemVer ( string ? a , string ? b )
565+ {
566+ if ( string . IsNullOrWhiteSpace ( a ) && string . IsNullOrWhiteSpace ( b ) )
567+ {
568+ return 0 ;
569+ }
570+ else if ( string . IsNullOrWhiteSpace ( a ) )
571+ {
572+ return - 1 ;
573+ }
574+ else if ( string . IsNullOrWhiteSpace ( b ) )
575+ {
576+ return 1 ;
577+ }
578+
579+ a = a . TrimStart ( 'v' ) ;
580+ b = b . TrimStart ( 'v' ) ;
581+
582+ var aParts = a . Split ( '-' ) ;
583+ var bParts = b . Split ( '-' ) ;
584+
585+ var aParsed = Version . TryParse ( aParts [ 0 ] , out var aVersion ) ;
586+ var bParsed = Version . TryParse ( bParts [ 0 ] , out var bVersion ) ;
587+ if ( ! aParsed && ! bParsed )
588+ {
589+ return 0 ;
590+ }
591+ else if ( ! aParsed )
592+ {
593+ return - 1 ;
594+ }
595+ else if ( ! bParsed )
596+ {
597+ return 1 ;
598+ }
599+
600+ var compare = aVersion ! . CompareTo ( bVersion ) ;
601+ if ( compare != 0 )
602+ {
603+ // if the versions are different, return the comparison result
604+ return compare ;
605+ }
606+
607+ // if the versions are the same, compare the prerelease tags
608+ if ( aParts . Length == 1 && bParts . Length == 1 )
609+ {
610+ // if both versions are stable, they are equal
611+ return 0 ;
612+ }
613+ else if ( aParts . Length == 1 )
614+ {
615+ // if a is stable and b is not, a is greater
616+ return 1 ;
617+ }
618+ else if ( bParts . Length == 1 )
619+ {
620+ // if b is stable and a is not, b is greater
621+ return - 1 ;
622+ }
623+ else if ( aParts [ 1 ] == bParts [ 1 ] )
624+ {
625+ // if both versions are prerelease and the tags are the same, they are equal
626+ return 0 ;
627+ }
628+ else
629+ {
630+ // if both versions are prerelease, b is greater
631+ return - 1 ;
632+ }
633+ }
634+
635+ /// <summary>
636+ /// Produces major.minor.patch version dropping a pre-release suffix.
637+ /// </summary>
638+ /// <param name="version">A version looks like "0.28.1", "0.28.1-alpha", "0.28.10-beta.1", "0.28.10-rc.1", or "0.28.0-preview-1", etc.</param>
639+ public static string NormalizeVersion ( string version )
522640 {
523- return productVersion . Contains ( "-beta" )
524- ? productVersion . Split ( "-" ) [ 0 ]
525- : productVersion ;
641+ return version . Split ( '-' , StringSplitOptions . None ) [ 0 ] ;
526642 }
527643}
0 commit comments