forked from encse/adventofcode
-
Notifications
You must be signed in to change notification settings - Fork 1
/
App.cs
127 lines (103 loc) · 4.23 KB
/
App.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
#nullable enable
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using AdventOfCode;
using Cocona;
CoconaLiteApp.Run<Commands>(args);
#if !LIBRARY
[DebuggerStepThrough]
#endif
internal class Commands
{
private static readonly IReadOnlyList<Type> _tsolvers = Assembly.GetEntryAssembly()!.GetTypes()
.Where(static t => t.GetTypeInfo().IsClass && typeof(ISolver).IsAssignableFrom(t))
.OrderBy(static t => t.FullName)
.ToImmutableList();
[DoesNotReturn]
private static void ThrowAoC(AocCommuncationException ex)
=> throw new CommandExitedException(ex.Message, 1);
[Command]
public static Task Update(DayParameters day, [Option("no-git")] bool no_git)
{
if (!day.IsValid)
ThrowAoC(AocCommuncationException.WrongDate());
return no_git ? Updater.Update(day.Year, day.Day) : Updater.UpdateWithGit(day.Year, day.Day);
}
[Command]
public static void Run(DayParameters day)
{
if (!day.IsValid)
ThrowAoC(AocCommuncationException.WrongDate());
var tsolver = _tsolvers.First(tsolver =>
SolverExtensions.Year(tsolver) == day.Year &&
SolverExtensions.Day(tsolver) == day.Day);
Runner.RunSolver(GetSolver(tsolver));
}
[Command]
public static Task Upload(DayParameters day, [Option("no-git")] bool no_git, [Option("no-benchmark")] bool no_benchmark)
{
if (!day.IsValid)
ThrowAoC(AocCommuncationException.WrongDate());
var tsolver = _tsolvers.First(tsolver =>
SolverExtensions.Year(tsolver) == day.Year &&
SolverExtensions.Day(tsolver) == day.Day);
return Updater.Upload(GetSolver(tsolver), !no_git, !no_benchmark);
}
[Command]
public static void Display(DayParameters day)
{
if (!day.IsValid)
ThrowAoC(AocCommuncationException.WrongDate());
var tsolver = _tsolvers.First(tsolver =>
SolverExtensions.Year(tsolver) == day.Year &&
SolverExtensions.Day(tsolver) == day.Day);
Runner.DisplaySolver(GetDisplay(tsolver));
}
[Command]
public static void Benchmark(DayParameters day)
{
if (!day.IsValid)
ThrowAoC(AocCommuncationException.WrongDate());
var tsolver = _tsolvers.First(tsolver =>
SolverExtensions.Year(tsolver) == day.Year &&
SolverExtensions.Day(tsolver) == day.Day);
Runner.RunBenchmark(tsolver);
}
[Command]
public static void Init([Option("git-repo", ['g'])] string git_repo, [Option("ssl-salt", ['s'])] string sslSalt, [Option("ssl-password", ['p'])] string? sslPassword, [Option(['u', 'n'])] string username, [Option('y')] int? year)
{
year ??= TimeProvider.System.GetLocalNow().Year;
if (sslPassword is string password)
new AdventOfCode.Model.Project(git_repo, sslSalt, password, year.Value) { UserName = username }.Init();
else
new AdventOfCode.Model.Project(git_repo, sslSalt, "", year.Value) { UserName = username }.Init();
}
private static ISolver? GetSolver(Type tsolver)
=> (ISolver?)Activator.CreateInstance(tsolver);
private static IDisplay? GetDisplay(Type tdisplay)
=> (IDisplay?)Activator.CreateInstance(tdisplay);
}
internal record class DayParameters([Argument] string date = "today") : ICommandParameterSet
{
public static DateTime Today { get; } = TimeProvider.System.GetUtcNow().AddHours(-5).DateTime;
public static DateTime StartDateThisYear { get; } = new(Today.Year, 12, 1);
public static DateTime LastValidDate { get; } = Today >= StartDateThisYear ? Today : new(Today.Year - 1, 12, 25);
public int Year { get; } = ParseYear(date);
public int Day { get; } = ParseDay(date);
public bool IsValid
=> Year <= LastValidDate.Year && Day <= LastValidDate.Day;
private static int ParseYear(string day)
{
if (day is "today")
return Today.Year;
return int.Parse(day.AsSpan(0, 4));
}
private static int ParseDay(string day)
{
if (day is "today")
return Today.Day;
if (day.Contains("day", StringComparison.InvariantCultureIgnoreCase))
return int.Parse(day.AsSpan(8));
return int.Parse(day.AsSpan(5));
}
}