feat(porttracker): add all remaining commands (feature, test, library, dependency, report, phase)
This commit is contained in:
146
tools/NatsNet.PortTracker/Commands/DependencyCommands.cs
Normal file
146
tools/NatsNet.PortTracker/Commands/DependencyCommands.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using System.CommandLine;
|
||||
using NatsNet.PortTracker.Data;
|
||||
|
||||
namespace NatsNet.PortTracker.Commands;
|
||||
|
||||
public static class DependencyCommands
|
||||
{
|
||||
public static Command Create(Option<string> dbOption, Option<string> schemaOption)
|
||||
{
|
||||
var depCommand = new Command("dependency", "Manage dependencies");
|
||||
|
||||
// show
|
||||
var showType = new Argument<string>("type") { Description = "Item type (module, feature, unit_test)" };
|
||||
var showId = new Argument<int>("id") { Description = "Item ID" };
|
||||
var showCmd = new Command("show", "Show dependencies for an item");
|
||||
showCmd.Add(showType);
|
||||
showCmd.Add(showId);
|
||||
showCmd.SetAction(parseResult =>
|
||||
{
|
||||
var dbPath = parseResult.GetValue(dbOption)!;
|
||||
var type = parseResult.GetValue(showType)!;
|
||||
var id = parseResult.GetValue(showId);
|
||||
using var db = new Database(dbPath);
|
||||
|
||||
var deps = db.Query(
|
||||
"SELECT target_type, target_id, dependency_kind FROM dependencies WHERE source_type = @type AND source_id = @id",
|
||||
("@type", type), ("@id", id));
|
||||
Console.WriteLine($"Dependencies of {type} #{id} ({deps.Count}):");
|
||||
foreach (var d in deps)
|
||||
Console.WriteLine($" -> {d["target_type"]} #{d["target_id"]} [{d["dependency_kind"]}]");
|
||||
|
||||
var rdeps = db.Query(
|
||||
"SELECT source_type, source_id, dependency_kind FROM dependencies WHERE target_type = @type AND target_id = @id",
|
||||
("@type", type), ("@id", id));
|
||||
Console.WriteLine($"\nReverse dependencies (depends on {type} #{id}) ({rdeps.Count}):");
|
||||
foreach (var d in rdeps)
|
||||
Console.WriteLine($" <- {d["source_type"]} #{d["source_id"]} [{d["dependency_kind"]}]");
|
||||
});
|
||||
|
||||
// blocked
|
||||
var blockedCmd = new Command("blocked", "Show items blocked by unported dependencies");
|
||||
blockedCmd.SetAction(parseResult =>
|
||||
{
|
||||
var dbPath = parseResult.GetValue(dbOption)!;
|
||||
using var db = new Database(dbPath);
|
||||
|
||||
var sql = @"
|
||||
SELECT 'module' as item_type, m.id, m.name, m.status, d.target_type, d.target_id, d.dependency_kind
|
||||
FROM modules m
|
||||
JOIN dependencies d ON d.source_type = 'module' AND d.source_id = m.id
|
||||
WHERE m.status NOT IN ('complete', 'verified', 'n_a')
|
||||
AND (
|
||||
(d.target_type = 'module' AND d.target_id IN (SELECT id FROM modules WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
OR (d.target_type = 'feature' AND d.target_id IN (SELECT id FROM features WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
OR (d.target_type = 'unit_test' AND d.target_id IN (SELECT id FROM unit_tests WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
)
|
||||
UNION ALL
|
||||
SELECT 'feature' as item_type, f.id, f.name, f.status, d.target_type, d.target_id, d.dependency_kind
|
||||
FROM features f
|
||||
JOIN dependencies d ON d.source_type = 'feature' AND d.source_id = f.id
|
||||
WHERE f.status NOT IN ('complete', 'verified', 'n_a')
|
||||
AND (
|
||||
(d.target_type = 'module' AND d.target_id IN (SELECT id FROM modules WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
OR (d.target_type = 'feature' AND d.target_id IN (SELECT id FROM features WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
OR (d.target_type = 'unit_test' AND d.target_id IN (SELECT id FROM unit_tests WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
)
|
||||
ORDER BY 1, 2";
|
||||
|
||||
var rows = db.Query(sql);
|
||||
if (rows.Count == 0)
|
||||
{
|
||||
Console.WriteLine("No blocked items found.");
|
||||
return;
|
||||
}
|
||||
Console.WriteLine($"{"Type",-10} {"ID",-5} {"Name",-30} {"Status",-15} {"Blocked By",-15} {"Dep ID",-8} {"Kind",-10}");
|
||||
Console.WriteLine(new string('-', 93));
|
||||
foreach (var row in rows)
|
||||
{
|
||||
Console.WriteLine($"{row["item_type"],-10} {row["id"],-5} {Truncate(row["name"]?.ToString(), 29),-30} {row["status"],-15} {row["target_type"],-15} {row["target_id"],-8} {row["dependency_kind"],-10}");
|
||||
}
|
||||
Console.WriteLine($"\n{rows.Count} blocking relationships found.");
|
||||
});
|
||||
|
||||
// ready
|
||||
var readyCmd = new Command("ready", "Show items ready to port (no unported dependencies)");
|
||||
readyCmd.SetAction(parseResult =>
|
||||
{
|
||||
var dbPath = parseResult.GetValue(dbOption)!;
|
||||
using var db = new Database(dbPath);
|
||||
|
||||
var sql = @"
|
||||
SELECT 'module' as item_type, m.id, m.name, m.status
|
||||
FROM modules m
|
||||
WHERE m.status IN ('not_started', 'stub')
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM dependencies d
|
||||
WHERE d.source_type = 'module' AND d.source_id = m.id
|
||||
AND (
|
||||
(d.target_type = 'module' AND d.target_id IN (SELECT id FROM modules WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
OR (d.target_type = 'feature' AND d.target_id IN (SELECT id FROM features WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
OR (d.target_type = 'unit_test' AND d.target_id IN (SELECT id FROM unit_tests WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
)
|
||||
)
|
||||
UNION ALL
|
||||
SELECT 'feature' as item_type, f.id, f.name, f.status
|
||||
FROM features f
|
||||
WHERE f.status IN ('not_started', 'stub')
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM dependencies d
|
||||
WHERE d.source_type = 'feature' AND d.source_id = f.id
|
||||
AND (
|
||||
(d.target_type = 'module' AND d.target_id IN (SELECT id FROM modules WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
OR (d.target_type = 'feature' AND d.target_id IN (SELECT id FROM features WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
OR (d.target_type = 'unit_test' AND d.target_id IN (SELECT id FROM unit_tests WHERE status NOT IN ('complete', 'verified', 'n_a')))
|
||||
)
|
||||
)
|
||||
ORDER BY 1, 2";
|
||||
|
||||
var rows = db.Query(sql);
|
||||
if (rows.Count == 0)
|
||||
{
|
||||
Console.WriteLine("No items are ready to port (all items either have unported deps or are already done).");
|
||||
return;
|
||||
}
|
||||
Console.WriteLine($"{"Type",-10} {"ID",-5} {"Name",-40} {"Status",-15}");
|
||||
Console.WriteLine(new string('-', 70));
|
||||
foreach (var row in rows)
|
||||
{
|
||||
Console.WriteLine($"{row["item_type"],-10} {row["id"],-5} {Truncate(row["name"]?.ToString(), 39),-40} {row["status"],-15}");
|
||||
}
|
||||
Console.WriteLine($"\n{rows.Count} items ready to port.");
|
||||
});
|
||||
|
||||
depCommand.Add(showCmd);
|
||||
depCommand.Add(blockedCmd);
|
||||
depCommand.Add(readyCmd);
|
||||
|
||||
return depCommand;
|
||||
}
|
||||
|
||||
private static string Truncate(string? s, int maxLen)
|
||||
{
|
||||
if (s is null) return "";
|
||||
return s.Length <= maxLen ? s : s[..(maxLen - 2)] + "..";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user