Skip to content

Commit

Permalink
πŸ§‘β€πŸ’» improve CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
koeeenig committed Dec 18, 2023
1 parent 0b759cd commit ef76bc4
Show file tree
Hide file tree
Showing 20 changed files with 896 additions and 4 deletions.
6 changes: 5 additions & 1 deletion src/BlazeKit.Abstraction/BlazeKit.Abstraction.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Text.Json" Version="8.0.0" />
</ItemGroup>

</Project>
56 changes: 56 additions & 0 deletions src/BlazeKit.Abstraction/Config/BkConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System.IO;
using System.Text.Json;

namespace BlazeKit.Abstraction.Config;

internal class BkConfig
{
public BkConfig()
{
Routes = "Routes";
Tailwindcss = null;
}
public string Routes { get; set; }
public TailwindcssConfig Tailwindcss { get; set; }


public static bool TryLoad(out BkConfig config)
{
return
TryLoad(
new DirectoryInfo(Directory.GetCurrentDirectory()),
out config
);
}


public static bool TryLoad(DirectoryInfo directory, out BkConfig config)
{
var exists = false;
config = new BkConfig();
var path = Path.Combine(directory.FullName, "blazekit.config.json");
// load blazekit.config.json file if it exists
if (File.Exists(path))
{
exists = true;
config = JsonSerializer.Deserialize<BkConfig>(File.ReadAllText("blazekit.config.json"))!;
}

return exists;
}
}

internal class TailwindcssConfig
{
public string Input { get; set; }
public string Output { get; set; }
}

internal static class BkConfigExtensions
{
public static bool HasTailwindcss(this BkConfig config)
{
return config.Tailwindcss != null;
}
}

22 changes: 20 additions & 2 deletions src/BlazeKit.CLI/BlazeKit.CLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,26 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Spectre.Console" Version="0.47.0" />
<PackageReference Include="Spectre.Console.Cli" Version="0.47.0" />
<Compile Include="..\BlazeKit.Abstraction\**\*.cs" Exclude="..\BlazeKit.Abstraction\obj\**\*.cs;">
<Link>BlazeKit.Abstraction\%(RecursiveDir)/%(FileName)%(Extension)</Link>
</Compile>
</ItemGroup>

<ItemGroup>
<None Remove="Templates\tailwind.config.js" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Templates\tailwind.config.js" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Spectre.Console" Version="0.48.0" />
<PackageReference Include="Spectre.Console.Analyzer" Version="0.48.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Spectre.Console.Cli" Version="0.48.0" />
<PackageReference Include="Yaapii.Atoms" Version="3.0.0" />
</ItemGroup>

Expand Down
72 changes: 72 additions & 0 deletions src/BlazeKit.CLI/Commands/Add/TailwindcssCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using BlazeKit.CLI.Tasks.Utils;
using Spectre.Console;
using Spectre.Console.Cli;
using Yaapii.Atoms.IO;
using Yaapii.Atoms.Text;

namespace BlazeKit.CLI.Commands.Add;
public class TailwindcssCommand : AsyncCommand
{
public override async Task<int> ExecuteAsync(CommandContext context)
{
// check if tailwindcss cli is installed as dotnet global tool
var installed = false;
new ExecCliCommand("dotnet", (output) => {
if(output.Contains("tailwindcss.cli")) {
installed = true;
}
},
"tool", "list", "-g"
)
.Run()
.WaitForExit();

if(!installed) {
AnsiConsole.MarkupLine("[yellow]Tailwindcss CLI is not installed as dotnet global tool... let's fix this.[/]");
var installTailwindCli = AnsiConsole.Confirm("Install Standalone Tailwindcss CLI from 'tailwindcss.cli' Nuget Package?", defaultValue:true);
if(!installTailwindCli)
{
AnsiConsole.MarkupLine("[ornage]Tailwindcss CLI has not been installed. Adding Tailwindcss support canceled.[/]");
return -1;
}
// check if tailwindcss global tool is installed
await
Task.Run(() => {
var process =
new ExecCliCommand(
"dotnet",
(output) => {
AnsiConsole.MarkupLine($"[purple]{$"[DOTNET]".EscapeMarkup()} {output.EscapeMarkup()}[/]");
},
"tool", "install", "-g", "tailwindcss.cli"
).Run();
process.WaitForExit();
});

// write to console that tailwindcss cli has been installed as dotnet global tool
AnsiConsole.MarkupLine("[yellow]Tailwindcss CLI has been installed as dotnet global tool.[/]");
}

// check if tailwindcss config file exists
if(File.Exists("tailwind.config.js")) {
// prompt for overwrite
var overwrite = AnsiConsole.Confirm("tailwind.config.js already exists. Do you want to overwrite it?");
if(!overwrite) {
AnsiConsole.MarkupLine("[yellow]Tailwindcss config file has not been overwritten.[/]");
return 0;
} else {
// delete tailwindcss config file
File.Delete("tailwind.config.js");
}
}

// Add tailwindcss config file
File.WriteAllText("tailwind.config.js", new TextOf(new ResourceOf("Templates/tailwind.config.js", this.GetType())).AsString());

// write to console that tailwindcss config has been updated
AnsiConsole.MarkupLine("[yellow]tailwind.config.js has been updated for BlazeKit.[/]");

return 0;
}
}
173 changes: 173 additions & 0 deletions src/BlazeKit.CLI/Commands/Build/BuildCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
using BlazeKit.CLI.Commands.New;
using BlazeKit.CLI.Tasks.Utils;
using Spectre.Console;
using Spectre.Console.Cli;
using System.Diagnostics;
using System.Text.Json;

namespace BlazeKit.CLI.Commands.Build;

public class BuildCommand : AsyncCommand<RunSettings>
{
public override async Task<int> ExecuteAsync(CommandContext context, RunSettings settings)
{
// load blazekit.config.json file if it exists
if (File.Exists("blazekit.config.json"))
{
AnsiConsole.MarkupLine("[yellow]Loading blazekit.config.json...[/]");
var config = JsonSerializer.Deserialize<JsonDocument>(File.ReadAllText("blazekit.config.json"));

config!.RootElement.TryGetProperty("tailwindcss", out var tailwindcss);

var input = tailwindcss.GetProperty("input").GetString();
var output = tailwindcss.GetProperty("output").GetString();

settings.Tailwindcss = $"-i {input} -o {output}";
}

// run dotnet watch command
AnsiConsole.MarkupLine("[yellow] Running Tailwindcss build process...[/]");
var cancel = new CancellationTokenSource();

var publishTask =
Task.Run(async () =>
{
var process =
new ExecCliCommand(
"tailwindcss",
output =>
{
AnsiConsole.MarkupLine($"[blue]{"[TAILWINDCSS]".EscapeMarkup()} {output.EscapeMarkup()}[/]");
},
string.IsNullOrEmpty(settings.Tailwindcss) ? "-i app.css -o wwwroot/css/app.css --minify" : settings.Tailwindcss
).Run();
while (!process.HasExited)
{
if (cancel.IsCancellationRequested)
{
AnsiConsole.MarkupLine("[yellow]Stopping tailwindcss build...[/]");
process.Kill();
break;
}
await Task.Delay(500);
}
});

await Task.WhenAll(publishTask);


publishTask =
Task.Run(async () =>
{
var process =
new ExecCliCommand(
"dotnet",
output =>
{
AnsiConsole.MarkupLine($"[purple]{$"[DOTNET PUBLISH]".EscapeMarkup()} {output.EscapeMarkup()}[/]");
},
(string.IsNullOrEmpty(settings.Dotnet) ? "publish -c Release" : settings.Dotnet) + " -o ./blazekit/build"
).Run();
while (!process.HasExited)
{
if (cancel.IsCancellationRequested)
{
AnsiConsole.MarkupLine("[yellow]Stopping dotnet publish...[/]");
process.Kill();
break;
}
await Task.Delay(500);
}
});


// Wait for CTRL+C input to cancel running dotnet watch
AnsiConsole.MarkupLine("[yellow]Press CTRL+C to stop dotnet watch...[/]");
// Start a console read operation. Do not display the input.
Console.TreatControlCAsInput = true;
var cancelTask = Task.Run(async () =>
{
while (true)
{
var key = Console.ReadKey(true);
if (key.Key == ConsoleKey.C && key.Modifiers == ConsoleModifiers.Control)
{
Console.WriteLine("CTRL+C pressed");
cancel.Cancel();
break;
}
await Task.Delay(100);
}
});

await Task.WhenAll(publishTask);
return 0;
}

private Process RunDotNetCommand(string command, IList<string> output, IList<string> error, Action<string> refresh, params string[] arguments)
{
AnsiConsole.MarkupLine($"[yellow]{"[BlazeKit]".EscapeMarkup()} running 'dotnet {command} {string.Join(" ", arguments)}'[/]");
// print working directory
// AnsiConsole.MarkupLine($"[yellow]Working directory: {Directory.GetCurrentDirectory()}[/]");
var startInfo =
new ProcessStartInfo("dotnet", $"{command} {string.Join(" ", arguments)}")
{
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
UseShellExecute = false,
CreateNoWindow = true,
// DOTNET_WATCH_SUPPRESS_EMOJIS=1
WorkingDirectory = Directory.GetCurrentDirectory()
};
startInfo.Environment.Add("DOTNET_WATCH_SUPPRESS_EMOJIS", "1");
var process =
Process.Start(
startInfo
);
process.EnableRaisingEvents = true;
process.OutputDataReceived += (sender, args) => { output.Add(args.Data); refresh(args.Data); };
process.ErrorDataReceived += (sender, args) => { error.Add(args.Data); refresh(args.Data); };

process.BeginOutputReadLine();
process.BeginErrorReadLine();

return process;
}

private Process RunTailwindcss(string command, IList<string> output, IList<string> error, Action<string> refresh, params string[] arguments)
{
AnsiConsole.MarkupLine($"[yellow]{"[BlazeKit]".EscapeMarkup()} running 'tailwindcss {command} {string.Join(" ", arguments)}'[/]");
// print working directory
// AnsiConsole.MarkupLine($"[yellow]Working directory: {Directory.GetCurrentDirectory()}[/]");
var startInfo =
new ProcessStartInfo("tailwindcss", $"{command} {string.Join(" ", arguments)}")
{
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
UseShellExecute = false,
CreateNoWindow = true,
// DOTNET_WATCH_SUPPRESS_EMOJIS=1
WorkingDirectory = Directory.GetCurrentDirectory()
};

var process =
Process.Start(
startInfo
);
process.EnableRaisingEvents = true;
process.OutputDataReceived += (sender, args) => { output.Add(args.Data); refresh(args.Data); };
process.ErrorDataReceived += (sender, args) => { error.Add(args.Data); refresh(args.Data); };

process.BeginOutputReadLine();
process.BeginErrorReadLine();

return process;
}
}
Loading

0 comments on commit ef76bc4

Please sign in to comment.