@@ -261,6 +261,31 @@ function Get-ApostropheTypoHints {
261261 return @ ($hints | Sort-Object )
262262}
263263
264+ function Test-ApostropheVariant {
265+ param (
266+ [Parameter (Mandatory = $true )]
267+ [string ]$SourceText ,
268+ [Parameter (Mandatory = $true )]
269+ [string ]$CanonicalText
270+ )
271+
272+ if ($CanonicalText -notmatch " '" ) {
273+ return $false
274+ }
275+
276+ $source = $SourceText.Trim ()
277+ $canonical = $CanonicalText.Trim ()
278+ if ($source -ceq $canonical ) {
279+ return $false
280+ }
281+
282+ if ((Normalize- MapNameForMatch - Text $source ) -ne (Normalize- MapNameForMatch - Text $canonical )) {
283+ return $false
284+ }
285+
286+ return ($source -notmatch " '" )
287+ }
288+
264289function Resolve-FileMapContext {
265290 param (
266291 [Parameter (Mandatory = $true )]
@@ -356,6 +381,18 @@ foreach ($name in $canonicalMapNames) {
356381 }
357382}
358383
384+ $canonicalListByNormalized = @ {}
385+ foreach ($name in $canonicalMapNames ) {
386+ $normalized = Normalize- MapNameForMatch - Text $name
387+ if (-not $canonicalListByNormalized.ContainsKey ($normalized )) {
388+ $canonicalListByNormalized [$normalized ] = New-Object System.Collections.Generic.List[string ]
389+ }
390+
391+ if (-not $canonicalListByNormalized [$normalized ].Contains($name )) {
392+ [void ]$canonicalListByNormalized [$normalized ].Add($name )
393+ }
394+ }
395+
359396$canonicalByNearPluralKey = @ {}
360397foreach ($name in $canonicalMapNames ) {
361398 $key = Get-NearPluralKey - Text $name
@@ -393,10 +430,12 @@ if ($files.Count -eq 0) {
393430$checkedScopeFolders = New-Object ' System.Collections.Generic.HashSet[string]' ([System.StringComparer ]::Ordinal)
394431$checkedMapFolders = New-Object ' System.Collections.Generic.HashSet[string]' ([System.StringComparer ]::Ordinal)
395432$unknownMapFolders = New-Object ' System.Collections.Generic.HashSet[string]' ([System.StringComparer ]::Ordinal)
433+ $apostropheMapFolders = New-Object ' System.Collections.Generic.HashSet[string]' ([System.StringComparer ]::Ordinal)
396434$mapNameMismatchWarnings = 0
397435$nearTypoWarnings = 0
398436$inferenceByFile = @ {}
399437$nearFolderSuggestions = @ {}
438+ $apostropheFolderSuggestions = @ {}
400439$repoExactCanonicalNames = New-Object ' System.Collections.Generic.HashSet[string]' ([System.StringComparer ]::Ordinal)
401440
402441foreach ($file in $files ) {
@@ -419,6 +458,11 @@ foreach ($file in $files) {
419458 if ($inferred.MatchKind -eq " exact" ) {
420459 [void ]$checkedMapFolders.Add ($folderKey )
421460 [void ]$repoExactCanonicalNames.Add ($inferred.Canonical )
461+
462+ if (Test-ApostropheVariant - SourceText $inferred.Segment - CanonicalText $inferred.Canonical ) {
463+ [void ]$apostropheMapFolders.Add ($folderKey )
464+ $apostropheFolderSuggestions [$folderKey ] = " $ ( $inferred.Segment ) -> $ ( $inferred.Canonical ) "
465+ }
422466 }
423467 else {
424468 [void ]$unknownMapFolders.Add ($folderKey )
@@ -473,7 +517,23 @@ if ($WarnOnNearMapTypos) {
473517 }
474518
475519 $baseNormalized = Normalize- MapNameForMatch - Text $baseName
476- if ($canonicalByNormalized.ContainsKey ($baseNormalized )) {
520+ if ($canonicalListByNormalized.ContainsKey ($baseNormalized )) {
521+ $apostropheHints = New-Object ' System.Collections.Generic.HashSet[string]' ([System.StringComparer ]::Ordinal)
522+ foreach ($candidate in $canonicalListByNormalized [$baseNormalized ]) {
523+ if ($knownMapNames -notcontains $candidate ) {
524+ continue
525+ }
526+
527+ if ($candidate -match " '" -and $baseName -notmatch " '" -and $baseName -cne $candidate ) {
528+ [void ]$apostropheHints.Add (" $baseName -> $candidate " )
529+ }
530+ }
531+
532+ if ($apostropheHints.Count -gt 0 ) {
533+ $nearTypoWarnings ++
534+ Write-Host " [MAP-NAME][WARN] $relativePath : possible apostrophe typo(s): $ ( $apostropheHints -join ' ; ' ) "
535+ }
536+
477537 continue
478538 }
479539
@@ -521,18 +581,23 @@ foreach ($entry in ($unknownMapFolders | Sort-Object)) {
521581 }
522582}
523583
584+ foreach ($entry in ($apostropheMapFolders | Sort-Object )) {
585+ Write-Host " [MAP-NAME][WARN] $entry : possible apostrophe typo: $ ( $apostropheFolderSuggestions [$entry ]) "
586+ }
587+
524588Write-Host " "
525589Write-Host " Checked scope folders: $ ( $checkedScopeFolders.Count ) "
526590Write-Host " Checked map folders: $ ( $checkedMapFolders.Count ) "
527591Write-Host " Unknown map folders: $ ( $unknownMapFolders.Count ) "
592+ Write-Host " Apostrophe map folder warnings: $ ( $apostropheMapFolders.Count ) "
528593if ($WarnOnMapNameInFileMismatch ) {
529594 Write-Host " File-name map mismatch warnings: $mapNameMismatchWarnings "
530595}
531596if ($WarnOnNearMapTypos ) {
532597 Write-Host " Near map typo warnings: $nearTypoWarnings "
533598}
534599
535- if ($unknownMapFolders.Count -gt 0 ) {
600+ if ($unknownMapFolders.Count -gt 0 -or $apostropheMapFolders .Count -gt 0 ) {
536601 exit 1
537602}
538603
0 commit comments