1
1
using System . CommandLine ;
2
2
using System . CommandLine . NamingConventionBinder ;
3
3
using System . Globalization ;
4
- using System . Linq ;
5
4
using System . Text ;
6
5
using LibGit2Sharp ;
7
6
using Microsoft . TeamFoundation . SourceControl . WebApi ;
@@ -13,7 +12,7 @@ namespace TfvcMigrator;
13
12
14
13
public static class Program
15
14
{
16
- public static Task < int > Main ( string [ ] args )
15
+ public static Task < int > Main ( string [ ] args )
17
16
{
18
17
var command = new RootCommand ( "Migrates TFVC source history to idiomatic Git history while preserving branch topology." )
19
18
{
@@ -117,17 +116,20 @@ pat is not null
117
116
var unmappedAuthors = changesets . Select ( c => c . Author )
118
117
. Concat ( changesets . Select ( c => c . CheckedInBy ) )
119
118
. Concat ( allLabels . Select ( l => l . Owner ) )
120
- . Select ( identity => identity . UniqueName )
121
- . Where ( name => ! authorsLookup . ContainsKey ( name ) )
122
- . Distinct ( StringComparer . OrdinalIgnoreCase )
119
+ . Where ( identity => ! authorsLookup . ContainsKey ( identity . UniqueName ) )
120
+ . GroupBy ( i => i . UniqueName )
121
+ . Select ( grouping => grouping . First ( ) )
123
122
. ToList ( ) ;
124
123
125
124
if ( unmappedAuthors . Any ( ) )
126
125
{
127
- Console . WriteLine ( "An entry must be added to the authors file for each of the following TFVC users:" ) ;
126
+ Console . WriteLine ( "A valid email address must be added to the authors file for each of the following TFVC users:" ) ;
128
127
foreach ( var user in unmappedAuthors )
129
- Console . WriteLine ( user ) ;
130
- return 1 ;
128
+ {
129
+ Console . WriteLine ( user . UniqueName ) ;
130
+ await File . AppendAllTextAsync ( authors , $ "{ user . UniqueName } = { user . DisplayName } <email>{ Environment . NewLine } ") ;
131
+ }
132
+ return 1 ;
131
133
}
132
134
133
135
Console . WriteLine ( "Downloading changesets and converting to commits..." ) ;
@@ -546,6 +548,13 @@ private static ImmutableDictionary<string, Identity> LoadAuthors(string authorsP
546
548
{
547
549
var builder = ImmutableDictionary . CreateBuilder < string , Identity > ( StringComparer . OrdinalIgnoreCase ) ;
548
550
551
+ if ( ! File . Exists ( authorsPath ) )
552
+ {
553
+ Console . WriteLine ( $ "Authors file not found. Creating: { authorsPath } ") ;
554
+ File . Create ( authorsPath ) ;
555
+ return builder . ToImmutable ( ) ;
556
+ }
557
+
549
558
using ( var reader = File . OpenText ( authorsPath ) )
550
559
{
551
560
while ( reader . ReadLine ( ) is { } line )
@@ -565,6 +574,8 @@ private static ImmutableDictionary<string, Identity> LoadAuthors(string authorsP
565
574
var name = gitIdentity [ ..openingAngleBracketIndex ] . TrimEnd ( ) . ToString ( ) ;
566
575
var email = gitIdentity [ ( openingAngleBracketIndex + 1 ) ..^ 1 ] . Trim ( ) . ToString ( ) ;
567
576
577
+ if ( email == "email" ) throw new NotImplementedException ( "<email> in authors file must be replaced with a valid email address" ) ;
578
+
568
579
builder . Add ( tfvcIdentity , new Identity ( name , email ) ) ;
569
580
}
570
581
}
0 commit comments