55 lines
2.1 KiB
C#
55 lines
2.1 KiB
C#
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using NozCli.Repl;
|
|
using Spectre.Console;
|
|
|
|
namespace NozCli.Commands;
|
|
|
|
public class StatusCommand : ICommand
|
|
{
|
|
public string Name => "status";
|
|
public string Description => "Show diff between a local folder and the server";
|
|
public string Usage => "status <local-path>";
|
|
|
|
public async Task ExecuteAsync(string[] args, ReplContext ctx)
|
|
{
|
|
var localPath = args.FirstOrDefault();
|
|
if (localPath is null) { AnsiConsole.MarkupLine("[red]Usage: status <local-path>[/]"); return; }
|
|
|
|
localPath = Path.GetFullPath(localPath);
|
|
if (!Directory.Exists(localPath)) { AnsiConsole.MarkupLine($"[red]Not found: {localPath}[/]"); return; }
|
|
|
|
var serverMap = ctx.NoteCache.ToDictionary(n => n.Slug, n => n.Hash ?? "");
|
|
var localFiles = Directory.EnumerateFiles(localPath, "*.md", SearchOption.AllDirectories)
|
|
.Where(f => !Path.GetFileName(f).StartsWith("_"));
|
|
|
|
var added = new List<string>();
|
|
var modified = new List<string>();
|
|
|
|
foreach (var file in localFiles)
|
|
{
|
|
var slug = Path.GetRelativePath(localPath, file).Replace(Path.DirectorySeparatorChar, '/').Replace(".md", "");
|
|
var markdown = await File.ReadAllTextAsync(file);
|
|
var localHash = Sha256(markdown);
|
|
|
|
if (!serverMap.ContainsKey(slug))
|
|
added.Add(slug);
|
|
else if (serverMap[slug] != localHash)
|
|
modified.Add(slug);
|
|
}
|
|
|
|
if (added.Count == 0 && modified.Count == 0)
|
|
{
|
|
AnsiConsole.MarkupLine("[green]✓ Everything up to date[/]");
|
|
return;
|
|
}
|
|
|
|
foreach (var s in added) AnsiConsole.MarkupLine($" [green]+[/] {s}");
|
|
foreach (var s in modified) AnsiConsole.MarkupLine($" [yellow]~[/] {s}");
|
|
|
|
AnsiConsole.MarkupLine($"\n[dim]{added.Count} new · {modified.Count} modified[/]");
|
|
}
|
|
|
|
private static string Sha256(string text) =>
|
|
Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(text))).ToLower();
|
|
}
|