Browse Source

Fix resolution of TFM overrides for multi-tfm projects (#734)

* Fix generated project when multiple project groupds are present

* Fix resolution of TFM overrides for multi-tfm projects
pull/745/head
John Luo 6 years ago
committed by GitHub
parent
commit
2009bbeb58
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 180
      src/Microsoft.Tye.Core/ApplicationFactory.cs
  2. 4
      src/Microsoft.Tye.Core/StandardOptions.cs
  3. 4
      src/Microsoft.Tye.Hosting/ProcessRunner.cs
  4. 15
      src/tye/ApplicationBuilderExtensions.cs
  5. 82
      src/tye/ProjectEvaluation.targets
  6. 26
      test/E2ETest/ApplicationFactoryTests.cs
  7. 6
      test/E2ETest/TyeRunTests.cs

180
src/Microsoft.Tye.Core/ApplicationFactory.cs

@ -83,77 +83,55 @@ namespace Microsoft.Tye
var projectServices = services.Where(s => !string.IsNullOrEmpty(s.Project));
var projectMetadata = new Dictionary<string, string>();
using (var directory = TempDirectory.Create())
{
var projectPath = Path.Combine(directory.DirectoryPath, Path.GetRandomFileName() + ".proj");
var msbuildEvaluationResult = await EvaluateProjectsAsync(
projects: projectServices,
configRoot: config.Source.DirectoryName!,
output: output);
var msbuildEvaluationOutput = msbuildEvaluationResult
.StandardOutput
.Split(Environment.NewLine);
var sb = new StringBuilder();
sb.AppendLine("<Project>");
sb.AppendLine(" <ItemGroup>");
var multiTFMProjects = new List<ConfigService>();
foreach (var project in projectServices)
foreach (var line in msbuildEvaluationOutput)
{
var trimmed = line.Trim();
if (trimmed.StartsWith("Microsoft.Tye metadata: "))
{
var expandedProject = Environment.ExpandEnvironmentVariables(project.Project!);
project.ProjectFullPath = Path.Combine(config.Source.DirectoryName!, expandedProject);
if (!File.Exists(project.ProjectFullPath))
{
throw new CommandException($"Failed to locate project: '{project.ProjectFullPath}'.");
}
var values = line.Split(':', 3);
var projectName = values[1].Trim();
var metadataPath = values[2].Trim();
projectMetadata.Add(projectName, metadataPath);
sb.AppendLine($" <MicrosoftTye_ProjectServices " +
$"Include=\"{project.ProjectFullPath}\" " +
$"Name=\"{project.Name}\" " +
$"BuildProperties=\"" +
$"{(project.BuildProperties.Any() ? project.BuildProperties.Select(kvp => $"{kvp.Name}={kvp.Value}").Aggregate((a, b) => a + ";" + b) : string.Empty)}" +
$"{(string.IsNullOrEmpty(framework) ? string.Empty : $";TargetFramework={framework}")}" +
$"\" />");
output.WriteDebugLine($"Resolved metadata for service {projectName} at {metadataPath}");
}
sb.AppendLine(@" </ItemGroup>");
sb.AppendLine($@" <Target Name=""MicrosoftTye_EvaluateProjects"">");
sb.AppendLine($@" <MsBuild Projects=""@(MicrosoftTye_ProjectServices)"" "
+ $@"Properties=""%(BuildProperties);"
+ $@"MicrosoftTye_ProjectName=%(Name)"" "
+ $@"Targets=""MicrosoftTye_GetProjectMetadata"" BuildInParallel=""true"" />");
sb.AppendLine(" </Target>");
sb.AppendLine("</Project>");
File.WriteAllText(projectPath, sb.ToString());
output.WriteDebugLine("Restoring and evaluating projects");
var msbuildEvaluationResult = await ProcessUtil.RunAsync(
"dotnet",
$"build " +
$"\"{projectPath}\" " +
// CustomAfterMicrosoftCommonTargets is imported by non-crosstargeting (single TFM) projects
$"/p:CustomAfterMicrosoftCommonTargets={Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "ProjectEvaluation.targets")} " +
// CustomAfterMicrosoftCommonCrossTargetingTargets is imported by crosstargeting (multi-TFM) projects
// This ensures projects properties are evaluated correctly. However, multi-TFM projects must specify
// a specific TFM to build/run/publish and will otherwise throw an exception.
$"/p:CustomAfterMicrosoftCommonCrossTargetingTargets={Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "ProjectEvaluation.targets")} " +
$"/nologo",
throwOnError: false,
workingDirectory: directory.DirectoryPath);
// If the build fails, we're not really blocked from doing our work.
// For now we just log the output to debug. There are errors that occur during
// running these targets we don't really care as long as we get the data.
if (msbuildEvaluationResult.ExitCode != 0)
else if (trimmed.StartsWith("Microsoft.Tye cross-targeting project: "))
{
output.WriteDebugLine($"Evaluating project failed with exit code {msbuildEvaluationResult.ExitCode}:" +
$"{Environment.NewLine}Ouptut: {msbuildEvaluationResult.StandardOutput}" +
$"{Environment.NewLine}Error: {msbuildEvaluationResult.StandardError}");
var values = line.Split(':', 2);
var projectName = values[1].Trim();
var multiTFMConfigService = projectServices.First(p => string.Equals(p.Name, projectName, StringComparison.OrdinalIgnoreCase));
multiTFMConfigService.BuildProperties.Add(new BuildProperty { Name = "TargetFramework", Value = framework ?? string.Empty });
multiTFMProjects.Add(multiTFMConfigService);
}
}
if (multiTFMProjects.Any())
{
output.WriteDebugLine("Re-evaluating multi-targeted projects");
var msbuildEvaluationOutput = msbuildEvaluationResult
var multiTFMEvaluationResult = await EvaluateProjectsAsync(
projects: multiTFMProjects,
configRoot: config.Source.DirectoryName!,
output: output);
var multiTFMEvaluationOutput = multiTFMEvaluationResult
.StandardOutput
.Split(Environment.NewLine);
foreach (var line in msbuildEvaluationOutput)
foreach (var line in multiTFMEvaluationOutput)
{
if (line.Trim().StartsWith("Microsoft.Tye metadata: "))
var trimmed = line.Trim();
if (trimmed.StartsWith("Microsoft.Tye metadata: "))
{
var values = line.Split(':', 3);
var projectName = values[1].Trim();
@ -162,11 +140,17 @@ namespace Microsoft.Tye
output.WriteDebugLine($"Resolved metadata for service {projectName} at {metadataPath}");
}
else if (trimmed.StartsWith("Microsoft.Tye cross-targeting project: "))
{
var values = line.Split(':', 2);
var projectName = values[1].Trim();
throw new CommandException($"Unable to run {projectName}. Your project targets multiple frameworks. Specify which framework to run using '--framework' or a build property in tye.yaml.");
}
}
output.WriteDebugLine($"Restore and project evaluation took: {sw.Elapsed.TotalMilliseconds}ms");
}
output.WriteDebugLine($"Restore and project evaluation took: {sw.Elapsed.TotalMilliseconds}ms");
foreach (var configService in services)
{
ServiceBuilder service;
@ -191,7 +175,6 @@ namespace Microsoft.Tye
}
project.Replicas = configService.Replicas ?? 1;
project.Liveness = configService.Liveness != null ? GetProbeBuilder(configService.Liveness) : null;
project.Readiness = configService.Readiness != null ? GetProbeBuilder(configService.Readiness) : null;
@ -207,12 +190,6 @@ namespace Microsoft.Tye
ProjectReader.ReadProjectDetails(output, project, projectMetadata[configService.Name]);
if (framework != null && project.TargetFrameworks.Any())
{
// Only use the TargetFramework for the "--framework" if it's a multi-targeted project and an override is provided
project.BuildProperties["TargetFramework"] = framework;
}
// Do k8s by default.
project.ManifestInfo = new KubernetesManifestInfo();
}
@ -498,6 +475,73 @@ namespace Microsoft.Tye
return root;
}
private static async Task<ProcessResult> EvaluateProjectsAsync(IEnumerable<ConfigService> projects, string configRoot, OutputContext output)
{
using var directory = TempDirectory.Create();
var projectPath = Path.Combine(directory.DirectoryPath, Path.GetRandomFileName() + ".proj");
var sb = new StringBuilder();
sb.AppendLine("<Project>");
sb.AppendLine(" <ItemGroup>");
foreach (var project in projects)
{
var expandedProject = Environment.ExpandEnvironmentVariables(project.Project!);
project.ProjectFullPath = Path.Combine(configRoot, expandedProject);
if (!File.Exists(project.ProjectFullPath))
{
throw new CommandException($"Failed to locate project: '{project.ProjectFullPath}'.");
}
sb.AppendLine($" <MicrosoftTye_ProjectServices " +
$"Include=\"{project.ProjectFullPath}\" " +
$"Name=\"{project.Name}\" " +
$"BuildProperties=\"" +
$"{(project.BuildProperties.Any() ? project.BuildProperties.Select(kvp => $"{kvp.Name}={kvp.Value}").Aggregate((a, b) => a + ";" + b) : string.Empty)}" +
$"\" />");
}
sb.AppendLine(@" </ItemGroup>");
sb.AppendLine($@" <Target Name=""MicrosoftTye_EvaluateProjects"">");
sb.AppendLine($@" <MsBuild Projects=""@(MicrosoftTye_ProjectServices)"" "
+ $@"Properties=""%(BuildProperties);"
+ $@"MicrosoftTye_ProjectName=%(Name)"" "
+ $@"Targets=""MicrosoftTye_GetProjectMetadata"" BuildInParallel=""true"" />");
sb.AppendLine(" </Target>");
sb.AppendLine("</Project>");
File.WriteAllText(projectPath, sb.ToString());
output.WriteDebugLine("Restoring and evaluating projects");
var msbuildEvaluationResult = await ProcessUtil.RunAsync(
"dotnet",
$"build " +
$"\"{projectPath}\" " +
// CustomAfterMicrosoftCommonTargets is imported by non-crosstargeting (single TFM) projects
$"/p:CustomAfterMicrosoftCommonTargets={Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "ProjectEvaluation.targets")} " +
// CustomAfterMicrosoftCommonCrossTargetingTargets is imported by crosstargeting (multi-TFM) projects
// This ensures projects properties are evaluated correctly. However, multi-TFM projects must specify
// a specific TFM to build/run/publish and will otherwise throw an exception.
$"/p:CustomAfterMicrosoftCommonCrossTargetingTargets={Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "ProjectEvaluation.targets")} " +
$"/nologo",
throwOnError: false,
workingDirectory: directory.DirectoryPath);
// If the build fails, we're not really blocked from doing our work.
// For now we just log the output to debug. There are errors that occur during
// running these targets we don't really care as long as we get the data.
if (msbuildEvaluationResult.ExitCode != 0)
{
output.WriteDebugLine($"Evaluating project failed with exit code {msbuildEvaluationResult.ExitCode}:" +
$"{Environment.NewLine}Ouptut: {msbuildEvaluationResult.StandardOutput}" +
$"{Environment.NewLine}Error: {msbuildEvaluationResult.StandardError}");
}
return msbuildEvaluationResult;
}
private static string? GetDockerFileContext(FileInfo source, ConfigService configService)
{
if (configService.DockerFileContext == null)

4
src/Microsoft.Tye.Core/StandardOptions.cs

@ -49,9 +49,9 @@ namespace Microsoft.Tye
public static Option Framework =>
new Option(new string[] { "-f", "--framework" })
{
Description = "The target framework override to use for all cross-targeting projects with multiple TFMs. " +
Description = "The target framework hint to use for all cross-targeting projects with multiple TFMs. " +
"This value must be a valid target framework for each individual cross-targeting project. " +
"Non-crosstargeting projects will ignore this value. ",
"Non-crosstargeting projects will ignore this hint and the value TFM configured in tye.yaml will override this hint. ",
Argument = new Argument<string>("framework")
{
Arity = ArgumentArity.ExactlyOne

4
src/Microsoft.Tye.Hosting/ProcessRunner.cs

@ -121,11 +121,11 @@ namespace Microsoft.Tye.Hosting
var projectPath = Path.Combine(directory.DirectoryPath, Path.GetRandomFileName() + ".proj");
var sb = new StringBuilder();
sb.AppendLine(@"<Project DefaultTargets=""Build"">
<ItemGroup>");
sb.AppendLine(@"<Project DefaultTargets=""Build"">");
foreach (var group in projectGroups)
{
sb.AppendLine(@" <ItemGroup>");
foreach (var p in group.Value.Services)
{
sb.AppendLine($" <{group.Value.GroupName} Include=\"{p.Status.ProjectFilePath}\" />");

15
src/tye/ApplicationBuilderExtensions.cs

@ -121,21 +121,6 @@ namespace Microsoft.Tye
}
else if (service is DotnetProjectServiceBuilder project)
{
if (project.TargetFrameworks.Length > 1)
{
if (project.BuildProperties.TryGetValue("TargetFramework", out var targetFramework))
{
if (!project.TargetFrameworks.Contains(targetFramework))
{
throw new InvalidOperationException($"Unable to run {project.Name}. The specified TargetFramework is not one of the existing TargetFrameworks in the project.");
}
}
else
{
throw new InvalidOperationException($"Unable to run {project.Name}. Your project targets multiple frameworks. Specify which framework to run using '--framework'.");
}
}
if (project.RunCommand == null)
{
throw new InvalidOperationException($"Unable to run {project.Name}. The project does not have a run command");

82
src/tye/ProjectEvaluation.targets

@ -1,48 +1,50 @@
<Project>
<PropertyGroup>
<!-- Single TFM projects -->
<MicrosoftTye_GetProjectMetadata_DependsOn>Restore;ResolveReferences;ResolvePackageDependenciesDesignTime;PrepareResources;PrepareResources;GetAssemblyAttributes</MicrosoftTye_GetProjectMetadata_DependsOn>
<!-- Multi TFM projects -->
<MicrosoftTye_GetProjectMetadata_DependsOn Condition="'$(IsCrossTargetingBuild)' == 'true'">Restore</MicrosoftTye_GetProjectMetadata_DependsOn>
</PropertyGroup>
<Target Name="MicrosoftTye_GetProjectMetadata" DependsOnTargets="$(MicrosoftTye_GetProjectMetadata_DependsOn)" >
<PropertyGroup>
<!-- Single TFM projects -->
<MicrosoftTye_GetProjectMetadata_DependsOn>Restore;ResolveReferences;ResolvePackageDependenciesDesignTime;PrepareResources;PrepareResources;GetAssemblyAttributes</MicrosoftTye_GetProjectMetadata_DependsOn>
<!-- Multi TFM projects -->
<MicrosoftTye_GetProjectMetadata_DependsOn Condition="'$(IsCrossTargetingBuild)' == 'true'">Restore</MicrosoftTye_GetProjectMetadata_DependsOn>
<_MicrosoftTye_MetadataFile>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)MicrosoftTye.ProjectMetadata.txt'))</_MicrosoftTye_MetadataFile>
<_MicrosoftTye_ProjectFrameworkReference>@(FrameworkReference, '%3B')</_MicrosoftTye_ProjectFrameworkReference>
<_MicrosoftTye_ProjectFrameworks>$(TargetFrameworks.Replace(';', '%3B'))</_MicrosoftTye_ProjectFrameworks>
</PropertyGroup>
<Target Name="MicrosoftTye_GetProjectMetadata" DependsOnTargets="$(MicrosoftTye_GetProjectMetadata_DependsOn)" >
<PropertyGroup>
<_MicrosoftTye_MetadataFile>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)MicrosoftTye.ProjectMetadata.txt'))</_MicrosoftTye_MetadataFile>
<_MicrosoftTye_ProjectFrameworkReference>@(FrameworkReference, '%3B')</_MicrosoftTye_ProjectFrameworkReference>
<_MicrosoftTye_ProjectFrameworks>$(TargetFrameworks.Replace(';', '%3B'))</_MicrosoftTye_ProjectFrameworks>
</PropertyGroup>
<ItemGroup>
<_MicrosoftTye_ProjectMetadata Include="AssemblyInformationalVersion: $(AssemblyInformationalVersion)" />
<_MicrosoftTye_ProjectMetadata Include="InformationalVersion: $(InformationalVersion)" />
<_MicrosoftTye_ProjectMetadata Include="Version: $(Version)" />
<_MicrosoftTye_ProjectMetadata Include="TargetFrameworks: $(_MicrosoftTye_ProjectFrameworks)" />
<_MicrosoftTye_ProjectMetadata Include="RunCommand: $(RunCommand)" />
<_MicrosoftTye_ProjectMetadata Include="RunArguments: $(RunArguments)" />
<_MicrosoftTye_ProjectMetadata Include="TargetPath: $(TargetPath)" />
<_MicrosoftTye_ProjectMetadata Include="PublishDir: $(PublishDir)" />
<_MicrosoftTye_ProjectMetadata Include="AssemblyName: $(AssemblyName)" />
<_MicrosoftTye_ProjectMetadata Include="IntermediateOutputPath: $(IntermediateOutputPath)" />
<_MicrosoftTye_ProjectMetadata Include="TargetFramework: $(TargetFramework)" />
<_MicrosoftTye_ProjectMetadata Include="_ShortFrameworkIdentifier: $(_ShortFrameworkIdentifier)" />
<_MicrosoftTye_ProjectMetadata Include="_ShortFrameworkVersion: $(_ShortFrameworkVersion)" />
<_MicrosoftTye_ProjectMetadata Include="_TargetFrameworkVersionWithoutV: $(_TargetFrameworkVersionWithoutV)" />
<_MicrosoftTye_ProjectMetadata Include="FrameworkReference: $(_MicrosoftTye_ProjectFrameworkReference)" />
<_MicrosoftTye_ProjectMetadata Include="ContainerBaseImage: $(ContainerBaseImage)" />
<_MicrosoftTye_ProjectMetadata Include="ContainerBaseTag: $(ContainerBaseTag)" />
<_MicrosoftTye_ProjectMetadata Include="MicrosoftNETPlatformLibrary: $(MicrosoftNETPlatformLibrary)" />
<_MicrosoftTye_ProjectMetadata Include="_AspNetCoreAppSharedFxIsEnabled: $(_AspNetCoreAppSharedFxIsEnabled)" />
<_MicrosoftTye_ProjectMetadata Include="UsingMicrosoftNETSdkWeb: $(UsingMicrosoftNETSdkWeb)" />
</ItemGroup>
<ItemGroup>
<_MicrosoftTye_ProjectMetadata Include="AssemblyInformationalVersion: $(AssemblyInformationalVersion)" />
<_MicrosoftTye_ProjectMetadata Include="InformationalVersion: $(InformationalVersion)" />
<_MicrosoftTye_ProjectMetadata Include="Version: $(Version)" />
<_MicrosoftTye_ProjectMetadata Include="TargetFrameworks: $(_MicrosoftTye_ProjectFrameworks)" />
<_MicrosoftTye_ProjectMetadata Include="RunCommand: $(RunCommand)" />
<_MicrosoftTye_ProjectMetadata Include="RunArguments: $(RunArguments)" />
<_MicrosoftTye_ProjectMetadata Include="TargetPath: $(TargetPath)" />
<_MicrosoftTye_ProjectMetadata Include="PublishDir: $(PublishDir)" />
<_MicrosoftTye_ProjectMetadata Include="AssemblyName: $(AssemblyName)" />
<_MicrosoftTye_ProjectMetadata Include="IntermediateOutputPath: $(IntermediateOutputPath)" />
<_MicrosoftTye_ProjectMetadata Include="TargetFramework: $(TargetFramework)" />
<_MicrosoftTye_ProjectMetadata Include="_ShortFrameworkIdentifier: $(_ShortFrameworkIdentifier)" />
<_MicrosoftTye_ProjectMetadata Include="_ShortFrameworkVersion: $(_ShortFrameworkVersion)" />
<_MicrosoftTye_ProjectMetadata Include="_TargetFrameworkVersionWithoutV: $(_TargetFrameworkVersionWithoutV)" />
<_MicrosoftTye_ProjectMetadata Include="FrameworkReference: $(_MicrosoftTye_ProjectFrameworkReference)" />
<_MicrosoftTye_ProjectMetadata Include="ContainerBaseImage: $(ContainerBaseImage)" />
<_MicrosoftTye_ProjectMetadata Include="ContainerBaseTag: $(ContainerBaseTag)" />
<_MicrosoftTye_ProjectMetadata Include="MicrosoftNETPlatformLibrary: $(MicrosoftNETPlatformLibrary)" />
<_MicrosoftTye_ProjectMetadata Include="_AspNetCoreAppSharedFxIsEnabled: $(_AspNetCoreAppSharedFxIsEnabled)" />
<_MicrosoftTye_ProjectMetadata Include="UsingMicrosoftNETSdkWeb: $(UsingMicrosoftNETSdkWeb)" />
</ItemGroup>
<WriteLinesToFile
File="$(_MicrosoftTye_MetadataFile)"
Lines="@(_MicrosoftTye_ProjectMetadata)"
Overwrite="true"
WriteOnlyWhenDifferent="true"/>
<WriteLinesToFile
File="$(_MicrosoftTye_MetadataFile)"
Lines="@(_MicrosoftTye_ProjectMetadata)"
Overwrite="true"
WriteOnlyWhenDifferent="true"
Condition="'$(IsCrossTargetingBuild)' != 'true'"/>
<Message Text="Microsoft.Tye metadata: $(MicrosoftTye_ProjectName): $(_MicrosoftTye_MetadataFile)" Importance="High"/>
<Message Text="Microsoft.Tye cross-targeting project: $(MicrosoftTye_ProjectName)" Importance="High" Condition="'$(IsCrossTargetingBuild)' == 'true'" />
<Message Text="Microsoft.Tye metadata: $(MicrosoftTye_ProjectName): $(_MicrosoftTye_MetadataFile)" Importance="High" Condition="'$(IsCrossTargetingBuild)' != 'true'" />
</Target>
</Target>
</Project>

26
test/E2ETest/ApplicationFactoryTests.cs

@ -146,7 +146,7 @@ services:
}
[Fact]
public async Task TargetFrameworkFromCliArgsOverwriteYaml()
public async Task TargetFrameworkFromCliArgsDoesNotOverwriteYaml()
{
using var projectDirectory = TestHelpers.CopyTestProjectDirectory(Path.Combine("multi-targetframeworks"));
var yamlFile = Path.Combine(projectDirectory.DirectoryPath, "tye-with-netcoreapp21.yaml");
@ -161,7 +161,7 @@ services:
var containsTargetFramework = ((DotnetProjectServiceBuilder)service).BuildProperties.TryGetValue("TargetFramework", out var targetFramework);
Assert.True(containsTargetFramework);
Assert.Equal("netcoreapp3.1", targetFramework);
Assert.Equal("netcoreapp2.1", targetFramework);
}
[Fact]
@ -191,22 +191,28 @@ services:
// Debug targets can be null if not specified, so make sure calling host.Start does not throw.
var outputContext = new OutputContext(_sink, Verbosity.Debug);
var projectFile = new FileInfo(yamlFile);
var applicationBuilder = await ApplicationFactory.CreateAsync(outputContext, projectFile);
Assert.Single(applicationBuilder.Services);
var service = applicationBuilder.Services.Single(s => s.Name == "multi-targetframeworks");
await Assert.ThrowsAsync<CommandException>(async () => await ApplicationFactory.CreateAsync(outputContext, projectFile));
}
var containsTargetFramework = ((DotnetProjectServiceBuilder)service).BuildProperties.TryGetValue("TargetFramework", out var targetFramework);
Assert.False(containsTargetFramework);
[Fact]
public async Task ThrowIfSpecifyTargetFrameworkNotDefinedIsCsproj()
{
using var projectDirectory = TestHelpers.CopyTestProjectDirectory(Path.Combine("multi-targetframeworks"));
var yamlFile = Path.Combine(projectDirectory.DirectoryPath, "tye-no-buildproperties.yaml");
Assert.Throws<InvalidOperationException>(() => applicationBuilder.ToHostingApplication());
// Debug targets can be null if not specified, so make sure calling host.Start does not throw.
var outputContext = new OutputContext(_sink, Verbosity.Debug);
var projectFile = new FileInfo(yamlFile);
await Assert.ThrowsAsync<CommandException>(async () => await ApplicationFactory.CreateAsync(outputContext, projectFile, "net5.0"));
}
[Fact]
public async Task ThrowIfSpecifyTargetFrameworkNotDefinedIsCsproj()
public async Task ThrowIfSpecifyTargetFrameworkIsInvalid()
{
using var projectDirectory = TestHelpers.CopyTestProjectDirectory(Path.Combine("multi-targetframeworks"));
var yamlFile = Path.Combine(projectDirectory.DirectoryPath, "tye-with-netcoreapp21.yaml");
var yamlFile = Path.Combine(projectDirectory.DirectoryPath, "tye-no-buildproperties.yaml");
// Debug targets can be null if not specified, so make sure calling host.Start does not throw.
var outputContext = new OutputContext(_sink, Verbosity.Debug);

6
test/E2ETest/TyeRunTests.cs

@ -1005,13 +1005,13 @@ services:
[ConditionalFact]
[SkipIfDockerNotRunning]
public async Task RunCliArgOverrideYamlMultipleTargetFrameworksTest()
public async Task RunCliArgDoesNotOverrideYamlMultipleTargetFrameworksTest()
{
using var projectDirectory = CopyTestProjectDirectory("multi-targetframeworks");
var projectFile = new FileInfo(Path.Combine(projectDirectory.DirectoryPath, "tye-with-netcoreapp21.yaml"));
var projectFile = new FileInfo(Path.Combine(projectDirectory.DirectoryPath, "tye-with-netcoreapp31.yaml"));
var outputContext = new OutputContext(_sink, Verbosity.Debug);
var application = await ApplicationFactory.CreateAsync(outputContext, projectFile, "netcoreapp3.1");
var application = await ApplicationFactory.CreateAsync(outputContext, projectFile, "netcoreapp2.1");
var handler = new HttpClientHandler
{

Loading…
Cancel
Save