Add net8.0 support to all existing runtimes and toolchains (#2192)
* add support for net8.0 * add support for NativeAOT .NET 8 * add support for MonoVM .NET 8 * add support for Mono AOT .NET 8 * add support for WASM .NET 8 * moniker name does not start with a dot * disable the CA1825 warning for samples and test projects
This commit is contained in:
Родитель
36f9e73096
Коммит
761590eb1a
|
@ -11,5 +11,6 @@
|
|||
<!-- reuquired to run Mono AOT benchmarks -->
|
||||
<add key="dotnet6" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json" />
|
||||
<add key="dotnet7" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json" />
|
||||
<add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<GenerateDocumentationFile>false</GenerateDocumentationFile>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<NoWarn>$(NoWarn);CA1018;CA5351</NoWarn>
|
||||
<NoWarn>$(NoWarn);CA1018;CA5351;CA1825</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' ">
|
||||
<Reference Include="System.Reflection" />
|
||||
|
|
|
@ -100,6 +100,11 @@ namespace BenchmarkDotNet.Jobs
|
|||
/// </summary>
|
||||
Net70,
|
||||
|
||||
/// <summary>
|
||||
/// .NET 8.0
|
||||
/// </summary>
|
||||
Net80,
|
||||
|
||||
/// <summary>
|
||||
/// NativeAOT compiled as net6.0
|
||||
/// </summary>
|
||||
|
@ -110,41 +115,56 @@ namespace BenchmarkDotNet.Jobs
|
|||
/// </summary>
|
||||
NativeAot70,
|
||||
|
||||
/// <summary>
|
||||
/// NativeAOT compiled as net8.0
|
||||
/// </summary>
|
||||
NativeAot80,
|
||||
|
||||
/// <summary>
|
||||
/// WebAssembly with default .Net version
|
||||
/// </summary>
|
||||
Wasm,
|
||||
|
||||
/// <summary>
|
||||
/// WebAssembly with .net5.0
|
||||
/// WebAssembly with net5.0
|
||||
/// </summary>
|
||||
WasmNet50,
|
||||
|
||||
/// <summary>
|
||||
/// WebAssembly with .net6.0
|
||||
/// WebAssembly with net6.0
|
||||
/// </summary>
|
||||
WasmNet60,
|
||||
|
||||
/// <summary>
|
||||
/// WebAssembly with .net7.0
|
||||
/// WebAssembly with net7.0
|
||||
/// </summary>
|
||||
WasmNet70,
|
||||
|
||||
/// <summary>
|
||||
/// WebAssembly with net8.0
|
||||
/// </summary>
|
||||
WasmNet80,
|
||||
|
||||
/// <summary>
|
||||
/// Mono with the Ahead of Time LLVM Compiler backend
|
||||
/// </summary>
|
||||
MonoAOTLLVM,
|
||||
|
||||
/// <summary>
|
||||
/// Mono with the Ahead of Time LLVM Compiler backend and .net6.0
|
||||
/// Mono with the Ahead of Time LLVM Compiler backend and net6.0
|
||||
/// </summary>
|
||||
MonoAOTLLVMNet60,
|
||||
|
||||
/// <summary>
|
||||
/// Mono with the Ahead of Time LLVM Compiler backend and .net7.0
|
||||
/// Mono with the Ahead of Time LLVM Compiler backend and net7.0
|
||||
/// </summary>
|
||||
MonoAOTLLVMNet70,
|
||||
|
||||
/// <summary>
|
||||
/// Mono with the Ahead of Time LLVM Compiler backend and net8.0
|
||||
/// </summary>
|
||||
MonoAOTLLVMNet80,
|
||||
|
||||
/// <summary>
|
||||
/// .NET 6 using MonoVM (not CLR which is the default)
|
||||
/// </summary>
|
||||
|
@ -154,5 +174,10 @@ namespace BenchmarkDotNet.Jobs
|
|||
/// .NET 7 using MonoVM (not CLR which is the default)
|
||||
/// </summary>
|
||||
Mono70,
|
||||
|
||||
/// <summary>
|
||||
/// .NET 8 using MonoVM (not CLR which is the default)
|
||||
/// </summary>
|
||||
Mono80,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -394,6 +394,7 @@ namespace BenchmarkDotNet.ConsoleArguments
|
|||
case RuntimeMoniker.Net50:
|
||||
case RuntimeMoniker.Net60:
|
||||
case RuntimeMoniker.Net70:
|
||||
case RuntimeMoniker.Net80:
|
||||
return baseJob
|
||||
.WithRuntime(runtimeMoniker.GetRuntime())
|
||||
.WithToolchain(CsProjCoreToolchain.From(new NetCoreAppSettings(runtimeId, null, runtimeId, options.CliPath?.FullName, options.RestorePath?.FullName)));
|
||||
|
@ -407,6 +408,9 @@ namespace BenchmarkDotNet.ConsoleArguments
|
|||
case RuntimeMoniker.NativeAot70:
|
||||
return CreateAotJob(baseJob, options, runtimeMoniker, "", "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json");
|
||||
|
||||
case RuntimeMoniker.NativeAot80:
|
||||
return CreateAotJob(baseJob, options, runtimeMoniker, "", "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json");
|
||||
|
||||
case RuntimeMoniker.Wasm:
|
||||
return MakeWasmJob(baseJob, options, RuntimeInformation.IsNetCore ? CoreRuntime.GetCurrentVersion().MsBuildMoniker : "net5.0", runtimeMoniker);
|
||||
|
||||
|
@ -419,6 +423,9 @@ namespace BenchmarkDotNet.ConsoleArguments
|
|||
case RuntimeMoniker.WasmNet70:
|
||||
return MakeWasmJob(baseJob, options, "net7.0", runtimeMoniker);
|
||||
|
||||
case RuntimeMoniker.WasmNet80:
|
||||
return MakeWasmJob(baseJob, options, "net8.0", runtimeMoniker);
|
||||
|
||||
case RuntimeMoniker.MonoAOTLLVM:
|
||||
return MakeMonoAOTLLVMJob(baseJob, options, RuntimeInformation.IsNetCore ? CoreRuntime.GetCurrentVersion().MsBuildMoniker : "net6.0");
|
||||
|
||||
|
@ -428,12 +435,18 @@ namespace BenchmarkDotNet.ConsoleArguments
|
|||
case RuntimeMoniker.MonoAOTLLVMNet70:
|
||||
return MakeMonoAOTLLVMJob(baseJob, options, "net7.0");
|
||||
|
||||
case RuntimeMoniker.MonoAOTLLVMNet80:
|
||||
return MakeMonoAOTLLVMJob(baseJob, options, "net8.0");
|
||||
|
||||
case RuntimeMoniker.Mono60:
|
||||
return MakeMonoJob(baseJob, options, MonoRuntime.Mono60);
|
||||
|
||||
case RuntimeMoniker.Mono70:
|
||||
return MakeMonoJob(baseJob, options, MonoRuntime.Mono70);
|
||||
|
||||
case RuntimeMoniker.Mono80:
|
||||
return MakeMonoJob(baseJob, options, MonoRuntime.Mono80);
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Runtime {runtimeId} is not supported");
|
||||
}
|
||||
|
|
|
@ -11,16 +11,17 @@ namespace BenchmarkDotNet.Environments
|
|||
{
|
||||
public class CoreRuntime : Runtime
|
||||
{
|
||||
public static readonly CoreRuntime Core20 = new CoreRuntime(RuntimeMoniker.NetCoreApp20, "netcoreapp2.0", ".NET Core 2.0");
|
||||
public static readonly CoreRuntime Core21 = new CoreRuntime(RuntimeMoniker.NetCoreApp21, "netcoreapp2.1", ".NET Core 2.1");
|
||||
public static readonly CoreRuntime Core22 = new CoreRuntime(RuntimeMoniker.NetCoreApp22, "netcoreapp2.2", ".NET Core 2.2");
|
||||
public static readonly CoreRuntime Core30 = new CoreRuntime(RuntimeMoniker.NetCoreApp30, "netcoreapp3.0", ".NET Core 3.0");
|
||||
public static readonly CoreRuntime Core31 = new CoreRuntime(RuntimeMoniker.NetCoreApp31, "netcoreapp3.1", ".NET Core 3.1");
|
||||
public static readonly CoreRuntime Core50 = new CoreRuntime(RuntimeMoniker.Net50, "net5.0", ".NET 5.0");
|
||||
public static readonly CoreRuntime Core60 = new CoreRuntime(RuntimeMoniker.Net60, "net6.0", ".NET 6.0");
|
||||
public static readonly CoreRuntime Core70 = new CoreRuntime(RuntimeMoniker.Net70, "net7.0", ".NET 7.0");
|
||||
public static readonly CoreRuntime Core20 = new (RuntimeMoniker.NetCoreApp20, "netcoreapp2.0", ".NET Core 2.0");
|
||||
public static readonly CoreRuntime Core21 = new (RuntimeMoniker.NetCoreApp21, "netcoreapp2.1", ".NET Core 2.1");
|
||||
public static readonly CoreRuntime Core22 = new (RuntimeMoniker.NetCoreApp22, "netcoreapp2.2", ".NET Core 2.2");
|
||||
public static readonly CoreRuntime Core30 = new (RuntimeMoniker.NetCoreApp30, "netcoreapp3.0", ".NET Core 3.0");
|
||||
public static readonly CoreRuntime Core31 = new (RuntimeMoniker.NetCoreApp31, "netcoreapp3.1", ".NET Core 3.1");
|
||||
public static readonly CoreRuntime Core50 = new (RuntimeMoniker.Net50, "net5.0", ".NET 5.0");
|
||||
public static readonly CoreRuntime Core60 = new (RuntimeMoniker.Net60, "net6.0", ".NET 6.0");
|
||||
public static readonly CoreRuntime Core70 = new (RuntimeMoniker.Net70, "net7.0", ".NET 7.0");
|
||||
public static readonly CoreRuntime Core80 = new (RuntimeMoniker.Net80, "net8.0", ".NET 8.0");
|
||||
|
||||
public static CoreRuntime Latest => Core70; // when dotnet/runtime branches for 8.0, this will need to get updated
|
||||
public static CoreRuntime Latest => Core80; // when dotnet/runtime branches for 9.0, this will need to get updated
|
||||
|
||||
private CoreRuntime(RuntimeMoniker runtimeMoniker, string msBuildMoniker, string displayName)
|
||||
: base(runtimeMoniker, msBuildMoniker, displayName)
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace BenchmarkDotNet.Environments
|
|||
public static readonly MonoRuntime Default = new MonoRuntime("Mono");
|
||||
public static readonly MonoRuntime Mono60 = new MonoRuntime("Mono with .NET 6.0", RuntimeMoniker.Mono60, "net6.0", isDotNetBuiltIn: true);
|
||||
public static readonly MonoRuntime Mono70 = new MonoRuntime("Mono with .NET 7.0", RuntimeMoniker.Mono70, "net7.0", isDotNetBuiltIn: true);
|
||||
public static readonly MonoRuntime Mono80 = new MonoRuntime("Mono with .NET 8.0", RuntimeMoniker.Mono80, "net8.0", isDotNetBuiltIn: true);
|
||||
|
||||
public string CustomPath { get; }
|
||||
|
||||
|
|
|
@ -14,6 +14,10 @@ namespace BenchmarkDotNet.Environments
|
|||
/// NativeAOT compiled as net7.0
|
||||
/// </summary>
|
||||
public static readonly NativeAotRuntime Net70 = new NativeAotRuntime(RuntimeMoniker.NativeAot70, "net7.0", "NativeAOT 7.0");
|
||||
/// <summary>
|
||||
/// NativeAOT compiled as net8.0
|
||||
/// </summary>
|
||||
public static readonly NativeAotRuntime Net80 = new NativeAotRuntime(RuntimeMoniker.NativeAot80, "net8.0", "NativeAOT 8.0");
|
||||
|
||||
public override bool IsAOT => true;
|
||||
|
||||
|
|
|
@ -43,12 +43,16 @@ namespace BenchmarkDotNet.Extensions
|
|||
return CoreRuntime.Core60;
|
||||
case RuntimeMoniker.Net70:
|
||||
return CoreRuntime.Core70;
|
||||
case RuntimeMoniker.Net80:
|
||||
return CoreRuntime.Core80;
|
||||
case RuntimeMoniker.Mono:
|
||||
return MonoRuntime.Default;
|
||||
case RuntimeMoniker.NativeAot60:
|
||||
return NativeAotRuntime.Net60;
|
||||
case RuntimeMoniker.NativeAot70:
|
||||
return NativeAotRuntime.Net70;
|
||||
case RuntimeMoniker.NativeAot80:
|
||||
return NativeAotRuntime.Net80;
|
||||
case RuntimeMoniker.Mono60:
|
||||
return MonoRuntime.Mono60;
|
||||
case RuntimeMoniker.Mono70:
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace BenchmarkDotNet.Toolchains.CsProj
|
|||
[PublicAPI] public static readonly IToolchain NetCoreApp50 = From(NetCoreAppSettings.NetCoreApp50);
|
||||
[PublicAPI] public static readonly IToolchain NetCoreApp60 = From(NetCoreAppSettings.NetCoreApp60);
|
||||
[PublicAPI] public static readonly IToolchain NetCoreApp70 = From(NetCoreAppSettings.NetCoreApp70);
|
||||
[PublicAPI] public static readonly IToolchain NetCoreApp80 = From(NetCoreAppSettings.NetCoreApp80);
|
||||
|
||||
internal CsProjCoreToolchain(string name, IGenerator generator, IBuilder builder, IExecutor executor, string customDotNetCliPath)
|
||||
: base(name, generator, builder, executor)
|
||||
|
|
|
@ -9,14 +9,15 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli
|
|||
[PublicAPI]
|
||||
public class NetCoreAppSettings
|
||||
{
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp20 = new NetCoreAppSettings("netcoreapp2.0", null, ".NET Core 2.0");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp21 = new NetCoreAppSettings("netcoreapp2.1", null, ".NET Core 2.1");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp22 = new NetCoreAppSettings("netcoreapp2.2", null, ".NET Core 2.2");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp30 = new NetCoreAppSettings("netcoreapp3.0", null, ".NET Core 3.0");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp31 = new NetCoreAppSettings("netcoreapp3.1", null, ".NET Core 3.1");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp50 = new NetCoreAppSettings("net5.0", null, ".NET 5.0");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp60 = new NetCoreAppSettings("net6.0", null, ".NET 6.0");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp70 = new NetCoreAppSettings("net7.0", null, ".NET 7.0");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp20 = new ("netcoreapp2.0", null, ".NET Core 2.0");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp21 = new ("netcoreapp2.1", null, ".NET Core 2.1");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp22 = new ("netcoreapp2.2", null, ".NET Core 2.2");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp30 = new ("netcoreapp3.0", null, ".NET Core 3.0");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp31 = new ("netcoreapp3.1", null, ".NET Core 3.1");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp50 = new ("net5.0", null, ".NET 5.0");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp60 = new ("net6.0", null, ".NET 6.0");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp70 = new ("net7.0", null, ".NET 7.0");
|
||||
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp80 = new ("net8.0", null, ".NET 8.0");
|
||||
|
||||
/// <summary>
|
||||
/// <param name="targetFrameworkMoniker">
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace BenchmarkDotNet.Toolchains.Mono
|
|||
{
|
||||
[PublicAPI] public static readonly IToolchain Mono60 = From(new NetCoreAppSettings("net6.0", null, "mono60"));
|
||||
[PublicAPI] public static readonly IToolchain Mono70 = From(new NetCoreAppSettings("net7.0", null, "mono70"));
|
||||
[PublicAPI] public static readonly IToolchain Mono80 = From(new NetCoreAppSettings("net8.0", null, "mono80"));
|
||||
|
||||
private MonoToolchain(string name, IGenerator generator, IBuilder builder, IExecutor executor, string customDotNetCliPath)
|
||||
: base(name, generator, builder, executor, customDotNetCliPath)
|
||||
|
|
|
@ -21,6 +21,14 @@ namespace BenchmarkDotNet.Toolchains.NativeAot
|
|||
.TargetFrameworkMoniker("net7.0")
|
||||
.ToToolchain();
|
||||
|
||||
/// <summary>
|
||||
/// compiled as net8.0, targets latest NativeAOT build from the .NET 8 feed: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json
|
||||
/// </summary>
|
||||
public static readonly IToolchain Net80 = CreateBuilder()
|
||||
.UseNuGet("", "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json")
|
||||
.TargetFrameworkMoniker("net8.0")
|
||||
.ToToolchain();
|
||||
|
||||
internal NativeAotToolchain(string displayName,
|
||||
string ilCompilerVersion,
|
||||
string runtimeFrameworkVersion, string targetFrameworkMoniker, string runtimeIdentifier,
|
||||
|
|
|
@ -125,18 +125,27 @@ namespace BenchmarkDotNet.Toolchains
|
|||
case RuntimeMoniker.Net70:
|
||||
return CsProjCoreToolchain.NetCoreApp70;
|
||||
|
||||
case RuntimeMoniker.Net80:
|
||||
return CsProjCoreToolchain.NetCoreApp80;
|
||||
|
||||
case RuntimeMoniker.NativeAot60:
|
||||
return NativeAotToolchain.Net60;
|
||||
|
||||
case RuntimeMoniker.NativeAot70:
|
||||
return NativeAotToolchain.Net70;
|
||||
|
||||
case RuntimeMoniker.NativeAot80:
|
||||
return NativeAotToolchain.Net80;
|
||||
|
||||
case RuntimeMoniker.Mono60:
|
||||
return MonoToolchain.Mono60;
|
||||
|
||||
case RuntimeMoniker.Mono70:
|
||||
return MonoToolchain.Mono70;
|
||||
|
||||
case RuntimeMoniker.Mono80:
|
||||
return MonoToolchain.Mono80;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, "RuntimeMoniker not supported");
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<GenerateDocumentationFile>false</GenerateDocumentationFile>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<NoWarn>$(NoWarn);CA2007</NoWarn>
|
||||
<NoWarn>$(NoWarn);CA2007;CA1825</NoWarn>
|
||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<PackageId>BenchmarkDotNet.Tests</PackageId>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<GenerateDocumentationFile>false</GenerateDocumentationFile>
|
||||
<NoWarn>$(NoWarn);NU1701;1701;CA1018;CA2007</NoWarn>
|
||||
<NoWarn>$(NoWarn);NU1701;1701;CA1018;CA2007;CA1825</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="xunit.runner.json">
|
||||
|
|
|
@ -373,6 +373,7 @@ namespace BenchmarkDotNet.Tests
|
|||
[InlineData("net50")]
|
||||
[InlineData("net60")]
|
||||
[InlineData("net70")]
|
||||
[InlineData("net80")]
|
||||
public void NetMonikersAreRecognizedAsNetCoreMonikers(string tfm)
|
||||
{
|
||||
var config = ConfigParser.Parse(new[] { "-r", tfm }, new OutputLogger(Output)).config;
|
||||
|
@ -399,7 +400,7 @@ namespace BenchmarkDotNet.Tests
|
|||
[Fact]
|
||||
public void CanCompareFewDifferentRuntimes()
|
||||
{
|
||||
var config = ConfigParser.Parse(new[] { "--runtimes", "net462", "MONO", "netcoreapp3.0", "nativeaot6.0", "nativeAOT7.0"}, new OutputLogger(Output)).config;
|
||||
var config = ConfigParser.Parse(new[] { "--runtimes", "net462", "MONO", "netcoreapp3.0", "nativeaot6.0", "nativeAOT7.0", "nativeAOT8.0" }, new OutputLogger(Output)).config;
|
||||
|
||||
Assert.True(config.GetJobs().First().Meta.Baseline); // when the user provides multiple runtimes the first one should be marked as baseline
|
||||
Assert.Single(config.GetJobs().Where(job => job.Environment.Runtime is ClrRuntime clrRuntime && clrRuntime.MsBuildMoniker == "net462"));
|
||||
|
@ -407,6 +408,7 @@ namespace BenchmarkDotNet.Tests
|
|||
Assert.Single(config.GetJobs().Where(job => job.Environment.Runtime is CoreRuntime coreRuntime && coreRuntime.MsBuildMoniker == "netcoreapp3.0" && coreRuntime.RuntimeMoniker == RuntimeMoniker.NetCoreApp30));
|
||||
Assert.Single(config.GetJobs().Where(job => job.Environment.Runtime is NativeAotRuntime nativeAot && nativeAot.MsBuildMoniker == "net6.0" && nativeAot.RuntimeMoniker == RuntimeMoniker.NativeAot60));
|
||||
Assert.Single(config.GetJobs().Where(job => job.Environment.Runtime is NativeAotRuntime nativeAot && nativeAot.MsBuildMoniker == "net7.0" && nativeAot.RuntimeMoniker == RuntimeMoniker.NativeAot70));
|
||||
Assert.Single(config.GetJobs().Where(job => job.Environment.Runtime is NativeAotRuntime nativeAot && nativeAot.MsBuildMoniker == "net8.0" && nativeAot.RuntimeMoniker == RuntimeMoniker.NativeAot80));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
Загрузка…
Ссылка в новой задаче