207 lines
9.4 KiB
C#
207 lines
9.4 KiB
C#
using System.CommandLine;
|
|
using NatsNet.PortTracker.Data;
|
|
|
|
namespace NatsNet.PortTracker.Commands;
|
|
|
|
public static class LibraryCommands
|
|
{
|
|
public static Command Create(Option<string> dbOption, Option<string> schemaOption)
|
|
{
|
|
var libraryCommand = new Command("library", "Manage library mappings");
|
|
|
|
// list
|
|
var listStatus = new Option<string?>("--status") { Description = "Filter by status" };
|
|
var listCmd = new Command("list", "List library mappings");
|
|
listCmd.Add(listStatus);
|
|
listCmd.SetAction(parseResult =>
|
|
{
|
|
var dbPath = parseResult.GetValue(dbOption)!;
|
|
var status = parseResult.GetValue(listStatus);
|
|
using var db = new Database(dbPath);
|
|
var sql = "SELECT id, go_import_path, go_library_name, dotnet_package, dotnet_namespace, status FROM library_mappings";
|
|
var parameters = new List<(string, object?)>();
|
|
if (status is not null)
|
|
{
|
|
sql += " WHERE status = @status";
|
|
parameters.Add(("@status", status));
|
|
}
|
|
sql += " ORDER BY go_import_path";
|
|
|
|
var rows = db.Query(sql, parameters.ToArray());
|
|
Console.WriteLine($"{"ID",-5} {"Go Import Path",-40} {"Go Library",-20} {"DotNet Package",-25} {"DotNet Namespace",-25} {"Status",-12}");
|
|
Console.WriteLine(new string('-', 127));
|
|
foreach (var row in rows)
|
|
{
|
|
Console.WriteLine($"{row["id"],-5} {Truncate(row["go_import_path"]?.ToString(), 39),-40} {Truncate(row["go_library_name"]?.ToString(), 19),-20} {Truncate(row["dotnet_package"]?.ToString(), 24),-25} {Truncate(row["dotnet_namespace"]?.ToString(), 24),-25} {row["status"],-12}");
|
|
}
|
|
Console.WriteLine($"\nTotal: {rows.Count} library mappings");
|
|
});
|
|
|
|
// map
|
|
var mapId = new Argument<int>("id") { Description = "Library mapping ID" };
|
|
var mapPackage = new Option<string?>("--package") { Description = ".NET NuGet package" };
|
|
var mapNamespace = new Option<string?>("--namespace") { Description = ".NET namespace" };
|
|
var mapNotes = new Option<string?>("--notes") { Description = "Usage notes" };
|
|
var mapCmd = new Command("map", "Map Go library to .NET package");
|
|
mapCmd.Add(mapId);
|
|
mapCmd.Add(mapPackage);
|
|
mapCmd.Add(mapNamespace);
|
|
mapCmd.Add(mapNotes);
|
|
mapCmd.SetAction(parseResult =>
|
|
{
|
|
var dbPath = parseResult.GetValue(dbOption)!;
|
|
var id = parseResult.GetValue(mapId);
|
|
var package = parseResult.GetValue(mapPackage);
|
|
var ns = parseResult.GetValue(mapNamespace);
|
|
var notes = parseResult.GetValue(mapNotes);
|
|
using var db = new Database(dbPath);
|
|
var affected = db.Execute(
|
|
"UPDATE library_mappings SET dotnet_package = COALESCE(@package, dotnet_package), dotnet_namespace = COALESCE(@ns, dotnet_namespace), dotnet_usage_notes = COALESCE(@notes, dotnet_usage_notes), status = 'mapped' WHERE id = @id",
|
|
("@package", package), ("@ns", ns), ("@notes", notes), ("@id", id));
|
|
Console.WriteLine(affected > 0 ? $"Library {id} mapped." : $"Library {id} not found.");
|
|
});
|
|
|
|
// suggest
|
|
var suggestCmd = new Command("suggest", "Show unmapped libraries");
|
|
suggestCmd.SetAction(parseResult =>
|
|
{
|
|
var dbPath = parseResult.GetValue(dbOption)!;
|
|
using var db = new Database(dbPath);
|
|
var rows = db.Query(
|
|
"SELECT id, go_import_path, go_library_name, go_usage_description FROM library_mappings WHERE status = 'not_mapped' ORDER BY go_import_path");
|
|
if (rows.Count == 0)
|
|
{
|
|
Console.WriteLine("All libraries have been mapped!");
|
|
return;
|
|
}
|
|
Console.WriteLine($"{"ID",-5} {"Go Import Path",-45} {"Library",-20} {"Usage",-40}");
|
|
Console.WriteLine(new string('-', 110));
|
|
foreach (var row in rows)
|
|
{
|
|
Console.WriteLine($"{row["id"],-5} {Truncate(row["go_import_path"]?.ToString(), 44),-45} {Truncate(row["go_library_name"]?.ToString(), 19),-20} {Truncate(row["go_usage_description"]?.ToString(), 39),-40}");
|
|
}
|
|
Console.WriteLine($"\n{rows.Count} unmapped libraries need attention.");
|
|
});
|
|
|
|
libraryCommand.Add(listCmd);
|
|
libraryCommand.Add(mapCmd);
|
|
libraryCommand.Add(suggestCmd);
|
|
libraryCommand.Add(CreateBatchUpdate(dbOption));
|
|
libraryCommand.Add(CreateBatchMap(dbOption));
|
|
|
|
return libraryCommand;
|
|
}
|
|
|
|
private static Command CreateBatchUpdate(Option<string> dbOption)
|
|
{
|
|
var cmd = new Command("batch-update", "Bulk update library status");
|
|
var idsOpt = BatchFilters.IdsOption();
|
|
var statusOpt = BatchFilters.StatusOption();
|
|
var executeOpt = BatchFilters.ExecuteOption();
|
|
var setStatus = new Option<string>("--set-status") { Description = "New status to set", Required = true };
|
|
var setNotes = new Option<string?>("--set-notes") { Description = "Usage notes to set" };
|
|
|
|
cmd.Add(idsOpt);
|
|
cmd.Add(statusOpt);
|
|
cmd.Add(executeOpt);
|
|
cmd.Add(setStatus);
|
|
cmd.Add(setNotes);
|
|
|
|
cmd.SetAction(parseResult =>
|
|
{
|
|
var dbPath = parseResult.GetValue(dbOption)!;
|
|
var ids = parseResult.GetValue(idsOpt);
|
|
var status = parseResult.GetValue(statusOpt);
|
|
var execute = parseResult.GetValue(executeOpt);
|
|
var newStatus = parseResult.GetValue(setStatus)!;
|
|
var notes = parseResult.GetValue(setNotes);
|
|
|
|
if (string.IsNullOrWhiteSpace(ids) && string.IsNullOrWhiteSpace(status))
|
|
{
|
|
Console.WriteLine("Error: at least one filter (--ids, --status) is required.");
|
|
return;
|
|
}
|
|
|
|
using var db = new Database(dbPath);
|
|
var (whereClause, filterParams) = BatchFilters.BuildWhereClause(ids, null, status);
|
|
|
|
var setClauses = new List<string> { "status = @newStatus" };
|
|
var updateParams = new List<(string, object?)> { ("@newStatus", newStatus) };
|
|
if (notes is not null)
|
|
{
|
|
setClauses.Add("dotnet_usage_notes = @newNotes");
|
|
updateParams.Add(("@newNotes", notes));
|
|
}
|
|
|
|
BatchFilters.PreviewOrExecute(db, "library_mappings",
|
|
"id, go_import_path, status, dotnet_usage_notes",
|
|
string.Join(", ", setClauses), updateParams,
|
|
whereClause, filterParams, execute);
|
|
});
|
|
|
|
return cmd;
|
|
}
|
|
|
|
private static Command CreateBatchMap(Option<string> dbOption)
|
|
{
|
|
var cmd = new Command("batch-map", "Bulk map libraries to .NET packages");
|
|
var idsOpt = BatchFilters.IdsOption();
|
|
var statusOpt = BatchFilters.StatusOption();
|
|
var executeOpt = BatchFilters.ExecuteOption();
|
|
var setPackage = new Option<string?>("--set-package") { Description = ".NET NuGet package" };
|
|
var setNamespace = new Option<string?>("--set-namespace") { Description = ".NET namespace" };
|
|
var setNotes = new Option<string?>("--set-notes") { Description = "Usage notes" };
|
|
|
|
cmd.Add(idsOpt);
|
|
cmd.Add(statusOpt);
|
|
cmd.Add(executeOpt);
|
|
cmd.Add(setPackage);
|
|
cmd.Add(setNamespace);
|
|
cmd.Add(setNotes);
|
|
|
|
cmd.SetAction(parseResult =>
|
|
{
|
|
var dbPath = parseResult.GetValue(dbOption)!;
|
|
var ids = parseResult.GetValue(idsOpt);
|
|
var status = parseResult.GetValue(statusOpt);
|
|
var execute = parseResult.GetValue(executeOpt);
|
|
var package = parseResult.GetValue(setPackage);
|
|
var ns = parseResult.GetValue(setNamespace);
|
|
var notes = parseResult.GetValue(setNotes);
|
|
|
|
if (string.IsNullOrWhiteSpace(ids) && string.IsNullOrWhiteSpace(status))
|
|
{
|
|
Console.WriteLine("Error: at least one filter (--ids, --status) is required.");
|
|
return;
|
|
}
|
|
if (package is null && ns is null && notes is null)
|
|
{
|
|
Console.WriteLine("Error: at least one of --set-package, --set-namespace, --set-notes is required.");
|
|
return;
|
|
}
|
|
|
|
using var db = new Database(dbPath);
|
|
var (whereClause, filterParams) = BatchFilters.BuildWhereClause(ids, null, status);
|
|
|
|
var setClauses = new List<string>();
|
|
var updateParams = new List<(string, object?)>();
|
|
if (package is not null) { setClauses.Add("dotnet_package = @setPackage"); updateParams.Add(("@setPackage", package)); }
|
|
if (ns is not null) { setClauses.Add("dotnet_namespace = @setNamespace"); updateParams.Add(("@setNamespace", ns)); }
|
|
if (notes is not null) { setClauses.Add("dotnet_usage_notes = @setNotes"); updateParams.Add(("@setNotes", notes)); }
|
|
|
|
BatchFilters.PreviewOrExecute(db, "library_mappings",
|
|
"id, go_import_path, status, dotnet_package, dotnet_namespace",
|
|
string.Join(", ", setClauses), updateParams,
|
|
whereClause, filterParams, execute);
|
|
});
|
|
|
|
return cmd;
|
|
}
|
|
|
|
private static string Truncate(string? s, int maxLen)
|
|
{
|
|
if (s is null) return "";
|
|
return s.Length <= maxLen ? s : s[..(maxLen - 2)] + "..";
|
|
}
|
|
}
|