|
1 | 1 | <Project> |
| 2 | + |
| 3 | + <UsingTask TaskName="AcgGetTools" |
| 4 | + TaskFactory="RoslynCodeTaskFactory" |
| 5 | + AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"> |
| 6 | + <ParameterGroup> |
| 7 | + <NetRuntimes ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /> |
| 8 | + <AcgRuntimes ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /> |
| 9 | + <NswagRuntimes ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /> |
| 10 | + <AcgToolDir ParameterType="Microsoft.Build.Framework.ITaskItem" Output="true" /> |
| 11 | + <AcgNswagToolDir ParameterType="Microsoft.Build.Framework.ITaskItem" Output="true" /> |
| 12 | + </ParameterGroup> |
| 13 | + <Task> |
| 14 | + <Using Namespace="System" /> |
| 15 | + <Using Namespace="System.Linq" /> |
| 16 | + <Code Type="Fragment" Language="cs"> |
| 17 | + <!-- For develop and testing code, use test\ApiCodeGenerator.Core.Tests\MSBuild\SelectGeneratorRuntimeTaskTest.cs --> |
| 18 | +<![CDATA[var netRuntimeRegex = new System.Text.RegularExpressions.Regex(@"^Microsoft\.NETCore\.App\s(\S+)\s\[[^\]]+\]$"); |
| 19 | + Func<string, int> parseMajorVersion = delegate (string versionString) |
| 20 | + { |
| 21 | + Exception innerEx = null; |
| 22 | + try |
| 23 | + { |
| 24 | + if (char.IsDigit(versionString.FirstOrDefault())) |
| 25 | + { |
| 26 | + return int.Parse(versionString.Substring(0, versionString.IndexOf('.'))); |
| 27 | + } |
| 28 | +
|
| 29 | + if (versionString.StartsWith("net")) |
| 30 | + { |
| 31 | + var pos = versionString.IndexOf('.'); |
| 32 | + if (pos > 3) |
| 33 | + { |
| 34 | + return int.Parse(versionString.Substring(3, pos - 3)); |
| 35 | + } |
| 36 | + } |
| 37 | + else if (versionString.StartsWith("Net")) |
| 38 | + { |
| 39 | + return int.Parse(versionString.Substring(3)) / 10; |
| 40 | + } |
| 41 | + } |
| 42 | + catch (FormatException ex) |
| 43 | + { |
| 44 | + innerEx = ex; |
| 45 | + } |
| 46 | +
|
| 47 | + throw new FormatException("Unknown version format: '" + versionString + "'.", innerEx); |
| 48 | + }; |
| 49 | +
|
| 50 | + Func<string, int> parseNetRuntimeMajorVersion = delegate (string versionString) |
| 51 | + { |
| 52 | + var match = netRuntimeRegex.Match(versionString); |
| 53 | + if (match.Success) |
| 54 | + { |
| 55 | + return parseMajorVersion(match.Groups[1].Value); |
| 56 | + } |
| 57 | +
|
| 58 | + throw new FormatException( |
| 59 | + string.Format( |
| 60 | + "Invalid .NET runtime data format: '{0}'. Expected: 'Microsoft.NETCore.App 8.0.8 [/usr/share/dotnet/shared/Microsoft.NETCore.App]'", |
| 61 | + versionString)); |
| 62 | + }; |
| 63 | +
|
| 64 | + try |
| 65 | + { |
| 66 | + var runtimes = NetRuntimes |
| 67 | + .Select(r => parseNetRuntimeMajorVersion(r.ItemSpec)) |
| 68 | + .OrderByDescending(v => v) |
| 69 | + .ToArray(); |
| 70 | +
|
| 71 | + var map = AcgRuntimes |
| 72 | + .Join( |
| 73 | + NswagRuntimes, |
| 74 | + l => parseMajorVersion(l.ItemSpec), |
| 75 | + r => parseMajorVersion(r.ItemSpec), |
| 76 | + (l, r) => |
| 77 | + { |
| 78 | + var v = parseMajorVersion(l.ItemSpec); |
| 79 | + return new |
| 80 | + { |
| 81 | + Version = v, |
| 82 | + Acg = l, |
| 83 | + Nswag = r, |
| 84 | + Net = runtimes.Contains(v) ? v : runtimes.FirstOrDefault(r => r > v), |
| 85 | + }; |
| 86 | + }) |
| 87 | + .OrderByDescending(i => i.Version); |
| 88 | +
|
| 89 | + var selected = |
| 90 | + map.FirstOrDefault(i => i.Version == i.Net) |
| 91 | + ?? map.FirstOrDefault(i => i.Version < i.Net); |
| 92 | +
|
| 93 | + if (selected != null) |
| 94 | + { |
| 95 | + AcgToolDir = selected.Acg; |
| 96 | + AcgNswagToolDir = selected.Nswag; |
| 97 | +
|
| 98 | + return true; |
| 99 | + } |
| 100 | +
|
| 101 | + AcgToolDir = null; |
| 102 | + AcgNswagToolDir = null; |
| 103 | + Log.LogErrorFromException(new Exception("No compatible runtime version found."), false, false, null); |
| 104 | + return false; |
| 105 | + } |
| 106 | + catch (FormatException ex) |
| 107 | + { |
| 108 | + Log.LogErrorFromException(ex, false, false, null); |
| 109 | + Success = false; |
| 110 | + }]]> |
| 111 | + </Code> |
| 112 | + </Task> |
| 113 | + </UsingTask> |
| 114 | + |
2 | 115 | <!-- Запрашиваем список установленных сред выполнения .NET и выбираем поддерживаемую --> |
3 | 116 | <Target Name="SelectGeneratorRuntime" |
4 | 117 | BeforeTargets="_GetMetadataForOpenApiReferences"> |
|
11 | 124 | </Exec> |
12 | 125 |
|
13 | 126 | <ItemGroup> |
14 | | - <_AcgDotnetRuntimes> |
15 | | - <!-- ищем установленный рантайм приложений заменяя его префикс и берем первые 6 символов |
16 | | - чтоб получить например net6.0 --> |
17 | | - <Folder>$([System.String]::Copy('%(Identity)').Replace('Microsoft.NETCore.App ','net').Substring(0,6))</Folder> |
18 | | - <NswagFolder>$([System.String]::Copy('%(Identity)').Replace('Microsoft.NETCore.App ', 'Net').Substring(0,6).Replace('.', ''))</NswagFolder> |
19 | | - </_AcgDotnetRuntimes> |
20 | | - <ttt Include="@(_AcgDotnetRuntimes)"> |
21 | | - <t>$(__AcgToolsDir)%(_AcgDotnetRuntimes.Folder)</t> |
22 | | - </ttt> |
23 | | - <_AcgTools Include="$(__AcgToolsDir)%(_AcgDotnetRuntimes.Folder)" |
24 | | - Condition="Exists('$(__AcgToolsDir)%(_AcgDotnetRuntimes.Folder)') AND Exists('$(NSwagDir)../%(_AcgDotnetRuntimes.NswagFolder)')"> |
25 | | - <NswagToolDir>$(NSwagDir)../%(_AcgDotnetRuntimes.NswagFolder)</NswagToolDir> |
26 | | - </_AcgTools> |
27 | | - <!-- проставляем на все ссылки пути к инструментам --> |
| 127 | + <_AcgDotnetRuntimes Remove="@(_AcgDotnetRuntimes)" Condition="!$([System.String]::new('%(Identity)').StartsWith('Microsoft.NETCore.App '))" /> |
| 128 | + |
| 129 | + <_AcgRuntimes Include="$(__AcgToolsDir)**\ApiCodeGenerator.MSBuild.exe" /> |
| 130 | + <_AcgRuntimes Include="$([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName(%(_AcgRuntimes.Identity)))))"> |
| 131 | + <Path>$([System.IO.Path]::GetDirectoryName(%(_AcgRuntimes.Identity)))</Path> |
| 132 | + </_AcgRuntimes> |
| 133 | + <_AcgRuntimes Remove="$(__AcgToolsDir)**\ApiCodeGenerator.MSBuild.exe" /> |
| 134 | + |
| 135 | + <_AcgNswagRuntimes Include="$(NSwagDir)../**/dotnet-nswag.exe" /> |
| 136 | + <_AcgNswagRuntimes Include="$([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName(%(_AcgNswagRuntimes.Identity)))))"> |
| 137 | + <Path>$([System.IO.Path]::GetDirectoryName(%(_AcgNswagRuntimes.Identity)))</Path> |
| 138 | + </_AcgNswagRuntimes> |
| 139 | + <_AcgNswagRuntimes Remove="$(NSwagDir)../**/dotnet-nswag.exe" /> |
| 140 | + </ItemGroup> |
| 141 | + |
| 142 | + <AcgGetTools NetRuntimes="@(_AcgDotnetRuntimes)" AcgRuntimes="@(_AcgRuntimes)" NswagRuntimes="@(_AcgNswagRuntimes)"> |
| 143 | + <Output TaskParameter="AcgToolDir" ItemName="_AcgTargetToolDir" /> |
| 144 | + <Output TaskParameter="AcgNswagToolDir" ItemName="_AcgTargetNswagToolDir" /> |
| 145 | + </AcgGetTools> |
| 146 | + |
| 147 | + <ItemGroup> |
| 148 | + <!-- проставляем на все ссылки пути к инструментам. Установка сразу двух не срабатывает --> |
28 | 149 | <OpenApiReference> |
29 | | - <AcgToolDir>%(_AcgTools.Identity)</AcgToolDir> |
30 | | - <AcgNswagToolDir>%(_AcgTools.NswagToolDir)</AcgNswagToolDir> |
| 150 | + <AcgToolDir>%(_AcgTargetToolDir.Path)</AcgToolDir> |
| 151 | + </OpenApiReference> |
| 152 | + <OpenApiReference> |
| 153 | + <AcgNswagToolDir>%(_AcgTargetNswagToolDir.Path)</AcgNswagToolDir> |
31 | 154 | </OpenApiReference> |
32 | 155 | </ItemGroup> |
33 | | - |
34 | | - <Error Condition="!Exists('%(_AcgTools.NswagToolDir)')" |
35 | | - Text="Nswag tools not found (%(_AcgTools.NswagToolDir)). ApiCodeGenerator tool in %(_AcgTools.Identity)" /> |
36 | 156 | </Target> |
37 | 157 |
|
38 | 158 | <Target Name="GenerateAcg"> |
|
51 | 171 | <__acgExtAssemblies Include="@(__acgBiExtAssemblies)" Condition="Exists(%(__acgBiExtAssemblies.Identity))" /> |
52 | 172 | <__acgExtAssemblies Include="$(AcgExtensionAssemblies)" /> |
53 | 173 | <CurrentOpenApiReference> |
54 | | - <Command>dotnet %(AcgToolDir)/ApiCodeGenerator.MSBuild.dll "%(FullPath)" "%(Options)" "%(OutputPath)" -v "Namespace=%(Namespace),ClassName=%(ClassName)</Command> |
| 174 | + <Command>dotnet --roll-forward Major %(AcgToolDir)/ApiCodeGenerator.MSBuild.dll "%(FullPath)" "%(Options)" "%(OutputPath)" -v "Namespace=%(Namespace),ClassName=%(ClassName)</Command> |
55 | 175 | </CurrentOpenApiReference> |
56 | 176 | <CurrentOpenApiReference> |
57 | 177 | <Command Condition="'%(CurrentOpenApiReference.Variables)' != ''">%(Command),%(CurrentOpenApiReference.Variables)</Command> |
|
72 | 192 | <Warning Condition="'@(__acgNotExistsBiExtAssemblies)' != ''" Text="File '%(__acgNotExistsBiExtAssemblies.Identity)' not found." /> |
73 | 193 | <Exec Command="%(CurrentOpenApiReference.Command)" |
74 | 194 | LogStandardErrorAsError="true" |
75 | | - CustomWarningRegularExpression="^WARNING .*" /> |
| 195 | + CustomWarningRegularExpression="^WARNING .*" |
| 196 | + StdErrEncoding="utf-8" /> |
76 | 197 | </Target> |
77 | 198 | </Project> |
0 commit comments