-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
150 lines (121 loc) · 5.69 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using System.Reflection;
using System.Text.RegularExpressions;
using CliWrap;
using diffcalc_comparer.Utils;
using osu.Game.Rulesets;
using Spectre.Console;
namespace diffcalc_comparer;
public static class Program
{
private static string rulesetAUrl = null!;
private static string rulesetBUrl = null!;
private static string rulesetAPath = null!;
private static string rulesetBPath = null!;
public static void Main(string[] args)
{
loadEnv();
rulesetAUrl = Environment.GetEnvironmentVariable("RULESET_A") ?? throw new Exception("Environment variable \"RULESET_A\" must be defined.");
rulesetBUrl = Environment.GetEnvironmentVariable("RULESET_B") ?? throw new Exception("Environment variable \"RULESET_B\" must be defined.");
rulesetAPath = Path.Combine(Directory.GetCurrentDirectory(), "ruleset_a");
rulesetBPath = Path.Combine(Directory.GetCurrentDirectory(), "ruleset_b");
cloneRepos().Wait();
buildAndLoadRulesets().Wait();
var includeUrls = AnsiConsole.Confirm("embed url in beatmap name?", false);
var exportPath = AnsiConsole.Prompt(new TextPrompt<string?>("[[optional]] Export path?").AllowEmpty());
new DiffComparer(new DiffComparerOptions
{
ExportPath = exportPath,
IncludeUrl = includeUrls
}).Compare();
}
private static Task buildAndLoadRulesets()
{
return AnsiConsole.Status()
.StartAsync("Building rulesets", async ctx =>
{
var rulesetName = getRulesetName();
ctx.Status = $"Building {rulesetName} rulesets (variant A)";
ctx.Spinner(Spinner.Known.Circle);
Env.RulesetA = await buildAndLoadRuleset(rulesetAPath, "A");
ctx.Status = $"Building {rulesetName} rulesets (variant B)";
Env.RulesetB = await buildAndLoadRuleset(rulesetBPath, "B");
async Task<Ruleset> buildAndLoadRuleset(string rulesetPath, string variant)
{
await Cli.Wrap("dotnet")
.WithArguments(new[] { "build", rulesetName, "-c", "Release" }!)
.WithWorkingDirectory(rulesetPath)
.ExecuteWithLogging();
var buildPath = rulesetPath;
if (Directory.Exists(Path.Combine(buildPath, rulesetName)))
buildPath = Path.Combine(buildPath, rulesetName);
buildPath = Path.Combine(buildPath, "bin", "Release");
var netVersion = Directory.GetDirectories(buildPath)[0];
buildPath = Path.Combine(buildPath, netVersion);
var dllName = rulesetName + ".dll";
var rulesetAssembly = Assembly.LoadFile(Path.Combine(buildPath, dllName));
Ruleset rulesetClass;
try
{
var rulesetType = rulesetAssembly.GetTypes().First(t => t.IsPublic && t.IsSubclassOf(typeof(Ruleset)));
rulesetClass = Activator.CreateInstance(rulesetType) as Ruleset ?? throw new InvalidOperationException();
}
catch (Exception e)
{
throw new Exception($"Could not load ruleset {rulesetName} (variant {variant}).", e);
}
if (rulesetClass.RulesetAPIVersionSupported != Ruleset.CURRENT_RULESET_API_VERSION)
throw new Exception(
$"Ruleset version is out of date. ({rulesetName} (variant {variant}): {rulesetClass.RulesetAPIVersionSupported} | current: {Ruleset.CURRENT_RULESET_API_VERSION})");
return rulesetClass;
}
});
}
private static string getRulesetName()
{
string rulesetName = null!;
var rulesetPathRegex = new Regex(@"osu\.Game\.Rulesets\.\w{1,}");
foreach (var directory in Directory.GetDirectories(rulesetAPath))
{
var match = rulesetPathRegex.Match(directory);
if (!match.Success)
continue;
rulesetName = match.Value;
break;
}
if (!string.IsNullOrEmpty(rulesetName))
return rulesetName;
var rulesetFileRegex = new Regex(@"osu\.Game\.Rulesets\.\w{1,}(\.csproj|\.sln)");
foreach (var file in Directory.GetFiles(rulesetAPath))
{
var match = rulesetFileRegex.Match(file);
if (!match.Success)
continue;
rulesetName = match.Groups[1].Value;
break;
}
return rulesetName;
}
private static Task cloneRepos()
{
return AnsiConsole.Status()
.StartAsync($"Cloning \"{rulesetAUrl}\" -> {rulesetAPath}", async ctx =>
{
await Github.CloneRepo(rulesetAUrl!, rulesetAPath);
ctx.Status = $"Cloning \"{rulesetBUrl}\" -> {rulesetBPath}";
await Github.CloneRepo(rulesetBUrl!, rulesetBPath);
});
}
private static void loadEnv()
{
var filePath = Path.Combine(Directory.GetParent(Environment.CurrentDirectory)!.Parent!.Parent!.FullName, ".env");
if (!File.Exists(filePath))
throw new Exception($"Could not find a \".env\" file. Make sure to copy the \".env.example\" from the root directory to \"{filePath}\"");
foreach (var line in File.ReadAllLines(filePath))
{
var split = line.Split('=', StringSplitOptions.RemoveEmptyEntries);
if (split.Length != 2)
continue;
Environment.SetEnvironmentVariable(split[0], split[1]);
}
}
}