-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDotPythonBuildCommand.cs
More file actions
138 lines (123 loc) · 4.59 KB
/
Copy pathDotPythonBuildCommand.cs
File metadata and controls
138 lines (123 loc) · 4.59 KB
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
using DotPython.Contracts;
using DotPython.Language;
namespace DotPython.Build.Tasks;
internal static class DotPythonBuildCommand
{
internal static int Run(IReadOnlyList<string> arguments)
{
try
{
var options = Parse(arguments);
return DotPythonModuleBuilder.Build(options) ? 0 : 1;
}
catch (BuildUsageException exception)
{
Console.Error.WriteLine($"error DPY7001: {exception.Message}");
return 1;
}
catch (IOException exception)
{
Console.Error.WriteLine($"error DPY7005: {exception.Message}");
return 1;
}
catch (UnauthorizedAccessException exception)
{
Console.Error.WriteLine($"error DPY7005: {exception.Message}");
return 1;
}
catch (InvalidOperationException exception)
{
Console.Error.WriteLine($"error DPY7005: {exception.Message}");
return 1;
}
catch (ArgumentException exception)
{
Console.Error.WriteLine($"error DPY7005: {exception.Message}");
return 1;
}
}
private static DotPythonModuleBuildOptions Parse(IReadOnlyList<string> arguments)
{
var values = new Dictionary<string, string>(StringComparer.Ordinal);
for (var index = 0; index < arguments.Count; index += 2)
{
if (
index + 1 >= arguments.Count
|| !arguments[index].StartsWith("--", StringComparison.Ordinal)
)
{
throw new BuildUsageException("Build-tool arguments must be '--name value' pairs.");
}
if (!values.TryAdd(arguments[index], arguments[index + 1]))
{
throw new BuildUsageException($"Duplicate build-tool option '{arguments[index]}'.");
}
}
var statePolicy = GetOptional(values, "--state-policy") ?? "PerRuntime";
if (
!Enum.TryParse<PythonModuleStatePolicy>(
statePolicy,
ignoreCase: false,
out var parsedPolicy
)
)
{
throw new BuildUsageException($"Unknown module state policy '{statePolicy}'.");
}
var languageVersion = ParseLanguageVersion(GetOptional(values, "--language-version"));
return new DotPythonModuleBuildOptions(
GetRequired(values, "--source"),
GetRequired(values, "--contract"),
GetRequired(values, "--module-name"),
GetRequired(values, "--clr-namespace"),
GetRequired(values, "--clr-type-name"),
parsedPolicy,
GetRequired(values, "--artifact-output"),
GetRequired(values, "--contract-output"),
GetRequired(values, "--facade-output"),
GetRequired(values, "--artifact-resource-name"),
languageVersion
);
}
private static Version ParseLanguageVersion(string? value)
{
if (value is null)
{
return PythonLanguageVersion.Current;
}
if (!Version.TryParse(value, out var parsed))
{
throw new BuildUsageException($"Invalid Python language version '{value}'.");
}
if (!PythonLanguageVersion.IsSupportedArtifactVersion(parsed))
{
var supportedVersions = string.Join(
", ",
PythonLanguageVersion.SupportedArtifactVersions.Select(version =>
version.ToString(2)
)
);
throw new BuildUsageException(
$"Python language version '{value}' is not supported. "
+ $"Supported artifact versions: {supportedVersions}."
);
}
return new Version(parsed.Major, parsed.Minor);
}
private static string GetRequired(IReadOnlyDictionary<string, string> values, string name) =>
GetOptional(values, name) is { Length: > 0 } value
? value
: throw new BuildUsageException(
$"Required build-tool option '{name}' was not supplied."
);
private static string? GetOptional(IReadOnlyDictionary<string, string> values, string name) =>
values.TryGetValue(name, out var value) ? value : null;
private sealed class BuildUsageException : Exception
{
public BuildUsageException() { }
public BuildUsageException(string message)
: base(message) { }
public BuildUsageException(string message, Exception innerException)
: base(message, innerException) { }
}
}