@@ -80,10 +80,6 @@ public static async Task<int> MigrateAsync(
80
80
if ( repo is null )
81
81
return 1 ;
82
82
83
- await using var authorsFileStream = LoadAuthorsFileStream ( authors ) ;
84
- var fileHasNewline = FileEndsInNewline ( authorsFileStream ) ;
85
- var authorsLookup = LoadAuthors ( authorsFileStream ) ;
86
-
87
83
Console . WriteLine ( "Connecting..." ) ;
88
84
89
85
using var connection = new VssConnection (
@@ -117,26 +113,11 @@ pat is not null
117
113
top : int . MaxValue )
118
114
) . ConfigureAwait ( false ) ;
119
115
120
- var unmappedAuthors = changesets . Select ( c => c . Author )
121
- . Concat ( changesets . Select ( c => c . CheckedInBy ) )
122
- . Concat ( allLabels . Select ( l => l . Owner ) )
123
- . Where ( identity => ! authorsLookup . ContainsKey ( identity . UniqueName ) )
124
- . DistinctBy ( i => i . UniqueName , StringComparer . OrdinalIgnoreCase )
125
- . ToList ( ) ;
126
-
127
- if ( unmappedAuthors . Any ( ) )
128
- {
129
- Console . WriteLine ( "A valid email address must be added to the authors file for each of the following TFVC users:" ) ;
130
- await using var writer = new StreamWriter ( authors , append : true ) ;
131
- if ( ! fileHasNewline ) await writer . WriteLineAsync ( ) ;
132
-
133
- foreach ( var user in unmappedAuthors )
134
- {
135
- Console . WriteLine ( user . UniqueName ) ;
136
- await writer . WriteLineAsync ( $ "{ user . UniqueName } = { user . DisplayName } <email>") ;
137
- }
138
- return 1 ;
139
- }
116
+ var authorsLookup = await LoadAuthors (
117
+ authors ,
118
+ changesets . Select ( c => c . Author )
119
+ . Concat ( changesets . Select ( c => c . CheckedInBy ) )
120
+ . Concat ( allLabels . Select ( l => l . Owner ) ) ) ;
140
121
141
122
Console . WriteLine ( "Downloading changesets and converting to commits..." ) ;
142
123
@@ -564,11 +545,36 @@ private static FileStream LoadAuthorsFileStream(string authorsPath)
564
545
return new FileStream ( authorsPath , FileMode . OpenOrCreate , FileAccess . Read , FileShare . Write ) ;
565
546
}
566
547
567
- private static ImmutableDictionary < string , Identity > LoadAuthors ( Stream authorsFileStream )
548
+ private static async Task < ImmutableDictionary < string , Identity > > LoadAuthors ( string authorsLookupPath , IEnumerable < IdentityRef > changesetAuthors )
549
+ {
550
+ await using var authorsFileStream = LoadAuthorsFileStream ( authorsLookupPath ) ;
551
+ var authorsLookup = LoadAuthors ( authorsFileStream , leaveStreamOpen : true ) ;
552
+
553
+ var unmappedAuthors = changesetAuthors
554
+ . Where ( identity => ! authorsLookup . ContainsKey ( identity . UniqueName ) )
555
+ . DistinctBy ( i => i . UniqueName , StringComparer . OrdinalIgnoreCase )
556
+ . ToList ( ) ;
557
+
558
+ if ( ! unmappedAuthors . Any ( ) ) return authorsLookup ;
559
+
560
+ await using var writer = new StreamWriter ( authorsLookupPath , append : true ) ;
561
+ if ( ! FileEndsInNewline ( authorsFileStream ) ) await writer . WriteLineAsync ( ) ;
562
+
563
+ foreach ( var user in unmappedAuthors )
564
+ await writer . WriteLineAsync ( $ "{ user . UniqueName } = { user . DisplayName } <email>") ;
565
+
566
+ var outMessageToWrite = $ """
567
+ A valid email address must be added to the authors file for each of the following TFVC users:
568
+ { string . Join ( Environment . NewLine , unmappedAuthors . Select ( a => a . UniqueName ) ) }
569
+ """ ;
570
+ throw new CommandLineException ( outMessageToWrite ) ;
571
+ }
572
+
573
+ private static ImmutableDictionary < string , Identity > LoadAuthors ( Stream authorsFileStream , bool leaveStreamOpen )
568
574
{
569
575
var builder = ImmutableDictionary . CreateBuilder < string , Identity > ( StringComparer . OrdinalIgnoreCase ) ;
570
576
571
- using var reader = new StreamReader ( authorsFileStream ) ;
577
+ using var reader = new StreamReader ( authorsFileStream , leaveOpen : leaveStreamOpen ) ;
572
578
while ( reader . ReadLine ( ) is { } line )
573
579
{
574
580
if ( string . IsNullOrWhiteSpace ( line ) ) continue ;
@@ -660,9 +666,10 @@ public static bool FileEndsInNewline(FileStream fileStream)
660
666
var streamStartsOnNewLine = true ;
661
667
if ( fileStream . Length <= 0 ) return streamStartsOnNewLine ;
662
668
669
+ var position = fileStream . Position ;
663
670
fileStream . Seek ( - 1 , SeekOrigin . End ) ;
664
671
streamStartsOnNewLine = ( char ) ( ( byte ) fileStream . ReadByte ( ) ) == '\n ' ;
665
- fileStream . Seek ( 0 , SeekOrigin . Begin ) ;
672
+ fileStream . Seek ( position , SeekOrigin . Begin ) ;
666
673
667
674
return streamStartsOnNewLine ;
668
675
}
0 commit comments