22// Subsequently: dnx runfile oss --yes
33#: package Spectre . Console@*
44#: package CliWrap@*
5+ #: package ConsoleAppFramework@*
56
67using System ;
78using System . IO ;
1011using System . Threading . Tasks ;
1112using System . Xml . Linq ;
1213using CliWrap ;
14+ using ConsoleAppFramework ;
1315using Spectre . Console ;
1416
15- string dotnet = Path . GetFullPath (
16- Path . Combine ( RuntimeEnvironment . GetRuntimeDirectory ( ) , ".." , ".." , ".." ,
17- RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ? "dotnet.exe" : "dotnet" ) ) ;
18-
19- AnsiConsole . Write ( new FigletText ( "devlooped oss" ) . Color ( Color . Green ) ) ;
20- AnsiConsole . WriteLine ( ) ;
21-
22- var projectName = AnsiConsole . Prompt (
23- new TextPrompt < string > ( "[green]Project name[/]:" )
24- . PromptStyle ( "yellow" )
25- . ValidationErrorMessage ( "[red]Project name cannot be empty[/]" )
26- . Validate ( v => ! string . IsNullOrWhiteSpace ( v ) ) ) ;
27-
28- var repoName = AnsiConsole . Prompt (
29- new TextPrompt < string > ( "[green]Repo name[/]:" )
30- . PromptStyle ( "yellow" )
31- . DefaultValue ( projectName ) ) ;
32-
33- var packageId = AnsiConsole . Prompt (
34- new TextPrompt < string > ( "[green]Package ID[/]:" )
35- . PromptStyle ( "yellow" )
36- . DefaultValue ( $ "Devlooped.{ projectName } ") ) ;
37-
38- AnsiConsole . WriteLine ( ) ;
39- AnsiConsole . Write ( new Rule ( "[yellow]Setting up OSS project[/]" ) . RuleStyle ( "grey" ) . LeftJustified ( ) ) ;
40- AnsiConsole . WriteLine ( ) ;
41-
42- await RunDotNet ( "file init https://github.com/devlooped/oss/blob/main/.netconfig" , "Initializing dotnet file sync from devlooped/oss" ) ;
43- await RunDotNet ( $ "new classlib -n { projectName } -o src/{ projectName } -f net10.0", $ "Creating class library src/{ projectName } ") ;
44- File . Delete ( $ "src/{ projectName } /Class1.cs") ;
45- await RunDotNet ( $ "package add NuGetizer --project src/{ projectName } /{ projectName } .csproj", "Adding NuGetizer" ) ;
46- await RunDotNet ( $ "new xunit -n Tests -o src/Tests -f net10.0", "Creating xUnit test project src/Tests" ) ;
47- File . Delete ( $ "src/Tests/UnitTest1.cs") ;
48- await RunDotNet ( $ "add src/Tests/Tests.csproj reference src/{ projectName } /{ projectName } .csproj", $ "Adding reference from Tests to { projectName } ") ;
49-
50- var doc = XDocument . Load ( $ "src/{ projectName } /{ projectName } .csproj", LoadOptions . None ) ;
51- doc . Root ? . Element ( "PropertyGroup" ) ? . Element ( "ImplicitUsings" ) ? . Remove ( ) ;
52- doc . Root ? . Element ( "PropertyGroup" ) ? . Element ( "Nullable" ) ? . Remove ( ) ;
53- doc . Root ? . Element ( "PropertyGroup" ) ? . Add ( new XElement ( "PackageId" , packageId ) ) ;
54- doc . Save ( $ "src/{ projectName } /{ projectName } .csproj") ;
55-
56- doc = XDocument . Load ( $ "src/Tests/Tests.csproj", LoadOptions . None ) ;
57- doc . Root ? . Element ( "PropertyGroup" ) ? . Element ( "ImplicitUsings" ) ? . Remove ( ) ;
58- doc . Root ? . Element ( "PropertyGroup" ) ? . Element ( "Nullable" ) ? . Remove ( ) ;
59- doc . Root ? . Element ( "PropertyGroup" ) ? . Element ( "IsPackable" ) ? . Remove ( ) ;
60- doc . Save ( $ "src/Tests/Tests.csproj") ;
61-
62- File . WriteAllText ( $ "src/Directory.props",
63- $ """
64- <Project>
65- <PropertyGroup>
66- <Product>{ projectName } </Product>
67- <ImplicitUsings>true</ImplicitUsings>
68- </PropertyGroup>
69- </Project>
70- """ ) ;
71-
72- await RunDotNet ( $ "new solution -n { projectName } ", $ "Creating solution { projectName } .slnx") ;
73- await RunDotNet ( $ "sln { projectName } .slnx add --in-root src/{ projectName } /{ projectName } .csproj src/Tests/Tests.csproj", $ "Adding projects to { projectName } .slnx") ;
74-
75- await AnsiConsole . Status ( )
76- . Spinner ( Spinner . Known . Dots )
77- . SpinnerStyle ( Style . Parse ( "green" ) )
78- . StartAsync ( "Downloading readme.md template..." , async ctx =>
79- {
80- using var http = new HttpClient ( ) ;
81- var readmeContent = await http . GetStringAsync (
82- "https://raw.githubusercontent.com/devlooped/oss/main/readme.tmp.md" ) ;
83-
84- readmeContent = readmeContent
85- . Replace ( "{{PROJECT_NAME}}" , projectName )
86- . Replace ( "{{PACKAGE_ID}}" , packageId )
87- . Replace ( "{{REPO_NAME}}" , repoName ) ;
88-
89- await File . WriteAllTextAsync ( "readme.md" , readmeContent ) ;
90- ctx . Status ( "Downloaded and processed readme.md" ) ;
91- } ) ;
92-
93- AnsiConsole . MarkupLine ( "[green]✓[/] Created [yellow]readme.md[/]" ) ;
94-
95- await File . WriteAllTextAsync (
96- Path . Combine ( "src" , projectName , "readme.md" ) ,
97- $ """
98- [](osmfeula.txt)
99- [](license.txt)
100- [](https://github.com/devlooped/{ repoName } )
101-
102- <!-- include ../../readme.md#content -->
103-
104- <!-- include https://github.com/devlooped/.github/raw/main/osmf.md -->
105-
106- <!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->
107-
108- <!-- exclude -->
109- """ ) ;
110-
111- AnsiConsole . WriteLine ( ) ;
112- AnsiConsole . Write ( new Rule ( "[green]Done![/]" ) . RuleStyle ( "grey" ) . LeftJustified ( ) ) ;
113- AnsiConsole . WriteLine ( ) ;
114- AnsiConsole . MarkupLine ( $ "[bold]Project:[/] [yellow]{ projectName } [/]") ;
115- AnsiConsole . MarkupLine ( $ "[bold]Repo:[/] [yellow]{ repoName } [/]") ;
116- AnsiConsole . MarkupLine ( $ "[bold]Package ID:[/] [yellow]{ packageId } [/]") ;
117-
118- async Task RunDotNet ( string command , string description )
17+ await ConsoleApp . RunAsync ( args , async (
18+ /// <summary>Project name</summary>
19+ string ? project = null ,
20+ /// <summary>Repo name (defaults to project name)</summary>
21+ string ? repo = null ,
22+ /// <summary>Package ID (defaults to Devlooped.{project})</summary>
23+ string ? package = null ) =>
11924{
120- AnsiConsole . MarkupLine ( $ "[grey]{ Markup . Escape ( description ) } ...[/]") ;
121- await Cli . Wrap ( dotnet )
122- . WithArguments ( command )
123- . WithStandardOutputPipe ( PipeTarget . ToStream ( Console . OpenStandardOutput ( ) ) )
124- . WithStandardErrorPipe ( PipeTarget . ToStream ( Console . OpenStandardError ( ) ) )
125- . ExecuteAsync ( ) ;
126- AnsiConsole . MarkupLine ( $ "[green]✓[/] { Markup . Escape ( description ) } ") ;
127- }
25+ string dotnet = Path . GetFullPath (
26+ Path . Combine ( RuntimeEnvironment . GetRuntimeDirectory ( ) , ".." , ".." , ".." ,
27+ RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ? "dotnet.exe" : "dotnet" ) ) ;
28+
29+ AnsiConsole . Write ( new FigletText ( "devlooped oss" ) . Color ( Color . Green ) ) ;
30+ AnsiConsole . WriteLine ( ) ;
31+
32+ var projectName = project ?? AnsiConsole . Prompt (
33+ new TextPrompt < string > ( "[green]Project name[/]:" )
34+ . PromptStyle ( "yellow" )
35+ . ValidationErrorMessage ( "[red]Project name cannot be empty[/]" )
36+ . Validate ( v => ! string . IsNullOrWhiteSpace ( v ) ) ) ;
37+
38+ var repoName = repo ?? AnsiConsole . Prompt (
39+ new TextPrompt < string > ( "[green]Repo name[/]:" )
40+ . PromptStyle ( "yellow" )
41+ . DefaultValue ( projectName ) ) ;
42+
43+ var packageId = package ?? AnsiConsole . Prompt (
44+ new TextPrompt < string > ( "[green]Package ID[/]:" )
45+ . PromptStyle ( "yellow" )
46+ . DefaultValue ( $ "Devlooped.{ projectName } ") ) ;
47+
48+ AnsiConsole . WriteLine ( ) ;
49+ AnsiConsole . Write ( new Rule ( "[yellow]Setting up OSS project[/]" ) . RuleStyle ( "grey" ) . LeftJustified ( ) ) ;
50+ AnsiConsole . WriteLine ( ) ;
51+
52+ await RunDotNet ( "file init https://github.com/devlooped/oss/blob/main/.netconfig" , "Initializing dotnet file sync from devlooped/oss" ) ;
53+ await RunDotNet ( $ "new classlib -n { projectName } -o src/{ projectName } -f net10.0", $ "Creating class library src/{ projectName } ") ;
54+ File . Delete ( $ "src/{ projectName } /Class1.cs") ;
55+ await RunDotNet ( $ "package add NuGetizer --project src/{ projectName } /{ projectName } .csproj", "Adding NuGetizer" ) ;
56+ await RunDotNet ( $ "new xunit -n Tests -o src/Tests -f net10.0", "Creating xUnit test project src/Tests" ) ;
57+ File . Delete ( $ "src/Tests/UnitTest1.cs") ;
58+ await RunDotNet ( $ "add src/Tests/Tests.csproj reference src/{ projectName } /{ projectName } .csproj", $ "Adding reference from Tests to { projectName } ") ;
59+
60+ var doc = XDocument . Load ( $ "src/{ projectName } /{ projectName } .csproj", LoadOptions . None ) ;
61+ doc . Root ? . Element ( "PropertyGroup" ) ? . Element ( "ImplicitUsings" ) ? . Remove ( ) ;
62+ doc . Root ? . Element ( "PropertyGroup" ) ? . Element ( "Nullable" ) ? . Remove ( ) ;
63+ doc . Root ? . Element ( "PropertyGroup" ) ? . Add ( new XElement ( "PackageId" , packageId ) ) ;
64+ doc . Save ( $ "src/{ projectName } /{ projectName } .csproj") ;
65+
66+ doc = XDocument . Load ( $ "src/Tests/Tests.csproj", LoadOptions . None ) ;
67+ doc . Root ? . Element ( "PropertyGroup" ) ? . Element ( "ImplicitUsings" ) ? . Remove ( ) ;
68+ doc . Root ? . Element ( "PropertyGroup" ) ? . Element ( "Nullable" ) ? . Remove ( ) ;
69+ doc . Root ? . Element ( "PropertyGroup" ) ? . Element ( "IsPackable" ) ? . Remove ( ) ;
70+ doc . Save ( $ "src/Tests/Tests.csproj") ;
71+
72+ File . WriteAllText ( $ "src/Directory.props",
73+ $ """
74+ <Project>
75+ <PropertyGroup>
76+ <Product>{ projectName } </Product>
77+ <ImplicitUsings>true</ImplicitUsings>
78+ </PropertyGroup>
79+ </Project>
80+ """ ) ;
81+
82+ await RunDotNet ( $ "new solution -n { projectName } ", $ "Creating solution { projectName } .slnx") ;
83+ await RunDotNet ( $ "sln { projectName } .slnx add --in-root src/{ projectName } /{ projectName } .csproj src/Tests/Tests.csproj", $ "Adding projects to { projectName } .slnx") ;
84+
85+ await AnsiConsole . Status ( )
86+ . Spinner ( Spinner . Known . Dots )
87+ . SpinnerStyle ( Style . Parse ( "green" ) )
88+ . StartAsync ( "Downloading readme.md template..." , async ctx =>
89+ {
90+ using var http = new HttpClient ( ) ;
91+ var readmeContent = await http . GetStringAsync (
92+ "https://raw.githubusercontent.com/devlooped/oss/main/readme.tmp.md" ) ;
93+
94+ readmeContent = readmeContent
95+ . Replace ( "{{PROJECT_NAME}}" , projectName )
96+ . Replace ( "{{PACKAGE_ID}}" , packageId )
97+ . Replace ( "{{REPO_NAME}}" , repoName ) ;
98+
99+ await File . WriteAllTextAsync ( "readme.md" , readmeContent ) ;
100+ ctx . Status ( "Downloaded and processed readme.md" ) ;
101+ } ) ;
102+
103+ AnsiConsole . MarkupLine ( "[green]✓[/] Created [yellow]readme.md[/]" ) ;
104+
105+ await File . WriteAllTextAsync (
106+ Path . Combine ( "src" , projectName , "readme.md" ) ,
107+ $ """
108+ [](osmfeula.txt)
109+ [](license.txt)
110+ [](https://github.com/devlooped/{ repoName } )
111+
112+ <!-- include ../../readme.md#content -->
113+
114+ <!-- include https://github.com/devlooped/.github/raw/main/osmf.md -->
115+
116+ <!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->
117+
118+ <!-- exclude -->
119+ """ ) ;
120+
121+ AnsiConsole . WriteLine ( ) ;
122+ AnsiConsole . Write ( new Rule ( "[green]Done![/]" ) . RuleStyle ( "grey" ) . LeftJustified ( ) ) ;
123+ AnsiConsole . WriteLine ( ) ;
124+ AnsiConsole . MarkupLine ( $ "[bold]Project:[/] [yellow]{ projectName } [/]") ;
125+ AnsiConsole . MarkupLine ( $ "[bold]Repo:[/] [yellow]{ repoName } [/]") ;
126+ AnsiConsole . MarkupLine ( $ "[bold]Package ID:[/] [yellow]{ packageId } [/]") ;
127+
128+ async Task RunDotNet ( string command , string description )
129+ {
130+ AnsiConsole . MarkupLine ( $ "[grey]{ Markup . Escape ( description ) } ...[/]") ;
131+ await Cli . Wrap ( dotnet )
132+ . WithArguments ( command )
133+ . WithStandardOutputPipe ( PipeTarget . ToStream ( Console . OpenStandardOutput ( ) ) )
134+ . WithStandardErrorPipe ( PipeTarget . ToStream ( Console . OpenStandardError ( ) ) )
135+ . ExecuteAsync ( ) ;
136+ AnsiConsole . MarkupLine ( $ "[green]✓[/] { Markup . Escape ( description ) } ") ;
137+ }
138+ } ) ;
0 commit comments