Seeding reorg
This commit is contained in:
@@ -25,15 +25,16 @@ public static class Program
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (opts.SkipCards && opts.SkipGlobals)
|
||||
if (opts.SkipReference && opts.SkipCards && opts.SkipGlobals)
|
||||
{
|
||||
Console.Error.WriteLine("Both --skip-cards and --skip-globals set; nothing to do.");
|
||||
Console.Error.WriteLine("All --skip-* flags set; nothing to do.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Console.WriteLine($"[Bootstrap] Connection: {RedactPassword(opts.ConnectionString)}");
|
||||
Console.WriteLine($"[Bootstrap] Cards file: {opts.CardsFile}");
|
||||
Console.WriteLine($"[Bootstrap] Captures: {opts.CapturesDir}");
|
||||
Console.WriteLine($"[Bootstrap] Connection: {RedactPassword(opts.ConnectionString)}");
|
||||
Console.WriteLine($"[Bootstrap] Reference CSVs: {opts.ReferenceDataDir}");
|
||||
Console.WriteLine($"[Bootstrap] Cards file: {opts.CardsFile}");
|
||||
Console.WriteLine($"[Bootstrap] Captures: {opts.CapturesDir}");
|
||||
|
||||
var dbOptions = new DbContextOptionsBuilder<SVSimDbContext>()
|
||||
.UseNpgsql(opts.ConnectionString)
|
||||
@@ -41,18 +42,35 @@ public static class Program
|
||||
|
||||
await using var context = new SVSimDbContext(NullLogger<SVSimDbContext>.Instance, dbOptions);
|
||||
|
||||
// Bootstrap applies pending migrations first so it can be the very first thing run after
|
||||
// `dotnet ef migrations add` — no need to start the server too.
|
||||
// Bootstrap applies pending migrations first — migrations are now DDL-only, all data
|
||||
// (reference tables, cards, card cosmetic rewards, prod-captured globals, game config)
|
||||
// is loaded by importers below. This means a freshly migrated DB is structure-only;
|
||||
// every importer is idempotent so re-running is safe.
|
||||
Console.WriteLine("[Bootstrap] Applying pending migrations...");
|
||||
await context.Database.MigrateAsync();
|
||||
|
||||
// GameConfigSection rows for every [ConfigSection] type — runtime seed (HasData doesn't
|
||||
// play well with OwnsOne+ToJson). Always run; tiers only insert missing sections.
|
||||
await context.EnsureSeedDataAsync();
|
||||
|
||||
if (!opts.SkipReference)
|
||||
{
|
||||
await new ReferenceDataImporter().ImportAllAsync(context, opts.ReferenceDataDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("[Bootstrap] --skip-reference set; skipping reference data import.");
|
||||
}
|
||||
|
||||
if (!opts.SkipCards)
|
||||
{
|
||||
await new CardImporter().ImportAsync(context, opts.CardsFile);
|
||||
// Card cosmetic rewards FK to Cards; piggy-back on --skip-cards.
|
||||
await new CardCosmeticRewardImporter().ImportAsync(context, opts.ReferenceDataDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("[Bootstrap] --skip-cards set; skipping card import.");
|
||||
Console.WriteLine("[Bootstrap] --skip-cards set; skipping card + cosmetic-reward import.");
|
||||
}
|
||||
|
||||
if (!opts.SkipGlobals)
|
||||
@@ -73,7 +91,9 @@ public static class Program
|
||||
string? dataDir = null;
|
||||
string? cards = null;
|
||||
string? captures = null;
|
||||
string? referenceDataDir = null;
|
||||
string? connection = null;
|
||||
bool skipReference = false;
|
||||
bool skipCards = false;
|
||||
bool skipGlobals = false;
|
||||
string? positionalCards = null;
|
||||
@@ -86,7 +106,9 @@ public static class Program
|
||||
case "--data-dir": dataDir = NextArg(args, ref i); break;
|
||||
case "--cards": cards = NextArg(args, ref i); break;
|
||||
case "--captures": captures = NextArg(args, ref i); break;
|
||||
case "--reference-data-dir": referenceDataDir = NextArg(args, ref i); break;
|
||||
case "--connection-string": connection = NextArg(args, ref i); break;
|
||||
case "--skip-reference": skipReference = true; break;
|
||||
case "--skip-cards": skipCards = true; break;
|
||||
case "--skip-globals": skipGlobals = true; break;
|
||||
default:
|
||||
@@ -100,9 +122,11 @@ public static class Program
|
||||
|
||||
// Resolution order:
|
||||
// --cards beats --data-dir/cards.json beats legacy positional;
|
||||
// --captures beats --data-dir/prod-captures beats Bootstrap/Data/prod-captures (shipped default).
|
||||
// --captures beats --data-dir/prod-captures beats Bootstrap/Data/prod-captures (shipped default);
|
||||
// --reference-data-dir beats shipped Bootstrap/Data (the CSVs always ship next to the binary).
|
||||
string baseDir = AppContext.BaseDirectory;
|
||||
string shippedCaptures = Path.Combine(baseDir, "Data", "prod-captures");
|
||||
string shippedDataDir = Path.Combine(baseDir, "Data");
|
||||
string shippedCaptures = Path.Combine(shippedDataDir, "prod-captures");
|
||||
|
||||
string cardsFile = cards
|
||||
?? (dataDir is not null ? Path.Combine(dataDir, "cards.json") : null)
|
||||
@@ -118,11 +142,14 @@ public static class Program
|
||||
? capturesCandidate
|
||||
: shippedCaptures;
|
||||
|
||||
string refDir = referenceDataDir ?? shippedDataDir;
|
||||
|
||||
string connStr = connection
|
||||
?? Environment.GetEnvironmentVariable("NPGSQL_CONNECTION")
|
||||
?? DefaultConnectionString;
|
||||
|
||||
return new BootstrapOptions(cardsFile, capturesDir, connStr, skipCards, skipGlobals);
|
||||
return new BootstrapOptions(
|
||||
cardsFile, capturesDir, refDir, connStr, skipReference, skipCards, skipGlobals);
|
||||
}
|
||||
|
||||
private static string NextArg(string[] args, ref int i)
|
||||
@@ -139,15 +166,18 @@ public static class Program
|
||||
Console.Error.WriteLine(
|
||||
"Usage: svsim-bootstrap [options]\n" +
|
||||
"\n" +
|
||||
" --data-dir <path> Directory containing cards.json and prod-captures/\n" +
|
||||
" (default: ./data_dumps relative to working dir)\n" +
|
||||
" --cards <file> Override path to cards.json\n" +
|
||||
" --captures <dir> Override path to prod-captures directory\n" +
|
||||
" (default: shipped Data/prod-captures next to the binary)\n" +
|
||||
" --connection-string <conn> Postgres connection (or NPGSQL_CONNECTION env var,\n" +
|
||||
$" then \"{DefaultConnectionString}\")\n" +
|
||||
" --skip-cards Skip card import (re-run globals only)\n" +
|
||||
" --skip-globals Skip globals import (cards only — legacy behavior)\n" +
|
||||
" --data-dir <path> Directory containing cards.json and prod-captures/\n" +
|
||||
" (default: ./data_dumps relative to working dir)\n" +
|
||||
" --cards <file> Override path to cards.json\n" +
|
||||
" --captures <dir> Override path to prod-captures directory\n" +
|
||||
" (default: shipped Data/prod-captures next to the binary)\n" +
|
||||
" --reference-data-dir <dir> Override reference CSV directory\n" +
|
||||
" (default: shipped Data/ next to the binary)\n" +
|
||||
" --connection-string <conn> Postgres connection (or NPGSQL_CONNECTION env var,\n" +
|
||||
$" then \"{DefaultConnectionString}\")\n" +
|
||||
" --skip-reference Skip reference-data import (classes, sleeves, ranks, ...)\n" +
|
||||
" --skip-cards Skip card + card-cosmetic-reward import\n" +
|
||||
" --skip-globals Skip prod-captured globals import\n" +
|
||||
"\n" +
|
||||
"Back-compat: `svsim-bootstrap <cards.json> [connection]` still works (positional).");
|
||||
}
|
||||
@@ -155,7 +185,9 @@ public static class Program
|
||||
private sealed record BootstrapOptions(
|
||||
string CardsFile,
|
||||
string CapturesDir,
|
||||
string ReferenceDataDir,
|
||||
string ConnectionString,
|
||||
bool SkipReference,
|
||||
bool SkipCards,
|
||||
bool SkipGlobals);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user