1+ #: package Spectre . Console@0 . *
2+ #: package ConsoleAppFramework @5 . *
3+ #: property Nullable = enable
4+ #: property ImportDirectoryBuildProps = false
5+ #: property ImportDirectoryBuildTargets = false
6+
7+ using System . IO ;
8+ using System . Linq ;
9+ using System . Text . RegularExpressions ;
10+ using ConsoleAppFramework ;
11+ using Spectre . Console ;
12+
13+ ConsoleApp . Run ( args , FixProto ) ;
14+
15+ /// <summary>Check and fix imports in .proto files.</summary>
16+ /// <para name="dir">Optional directory, defaults to current directory.</para>
17+ static int FixProto( bool dryRun , [ Argument ] string ? dir = default )
18+ {
19+ dir ??= Directory . GetCurrentDirectory ( ) ;
20+ var regex = ImportExpr ( ) ;
21+ var result = 0 ;
22+ foreach ( var file in Directory . EnumerateFiles ( dir , "* . proto", SearchOption . AllDirectories ) )
23+ {
24+ var lines = File . ReadAllLines ( file ) . ToList ( ) ;
25+ var changed = false ;
26+ for ( var i = 0 ; i < lines . Count ; i++ )
27+ {
28+ var line = lines [ i ] ;
29+ if ( regex . Match ( line ) is { Success : true } match )
30+ {
31+ var path = match . Groups [ 1 ] . Value ;
32+ var baseDir = Path . GetDirectoryName ( file ) ! ;
33+ if ( File . Exists ( Path . Combine ( baseDir , path ) ) )
34+ {
35+ AnsiConsole . MarkupLine( $":check_mark_button: {Path.GetRelativePath(dir, file)} [lime]{path}[/]" ) ;
36+ continue ;
37+ }
38+
39+ if ( File . Exists ( Path . Combine ( baseDir , Path . GetFileName ( path ) ) ) )
40+ {
41+ AnsiConsole . MarkupLine ( $ ":pencil:{ ( dryRun ? ":ghost:" : "" ) } { Path . GetRelativePath ( dir , file ) } : { path } > { Path . GetFileName ( path ) } ") ;
42+ if ( ! dryRun )
43+ {
44+ lines [ i ] = line . Replace ( path , Path . GetFileName ( path ) ) ;
45+ changed = true ;
46+ }
47+ continue ;
48+ }
49+
50+ result = 1 ;
51+ AnsiConsole . MarkupLine ( $ ":cross_mark: { Path . GetRelativePath ( dir , file ) } : import not found [yellow]{ path } [/]") ;
52+ }
53+ }
54+ if ( changed && ! dryRun )
55+ {
56+ File . WriteAllLines ( file , lines ) ;
57+ }
58+ }
59+
60+ return result ;
61+ }
62+
63+ partial class Program
64+ {
65+ [ GeneratedRegex ( @"^import\s+""([^""]+\.proto)"";$" , RegexOptions . Multiline ) ]
66+ private static partial Regex ImportExpr ( ) ;
67+ }
0 commit comments