Skip to content

Commit

Permalink
Implement publish-self-contained and add tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
nagilson committed Nov 2, 2022
1 parent da42e67 commit 35bdab7
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project TreatAsLocalProperty="SelfContained">
<PropertyGroup>
<SelfContained Condition=" '$(_IsPublishing)' == 'true' and '$(PublishSelfContained)' != '' and '$(PublishSelfContained)' != 'true'">false</SelfContained>
<SelfContained Condition=" '$(_IsPublishing)' == 'true' and '$(PublishSelfContained)' == 'true'">true</SelfContained>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ Copyright (c) .NET Foundation. All rights reserved.
'$(SelfContained)' == 'true' or
'$(PublishReadyToRun)' == 'true' or
'$(PublishSingleFile)' == 'true' or
'$(PublishAot)' == 'true'
'$(PublishAot)' == 'true' or
'$(PublishSelfContained)' == 'true'
)">true</UseCurrentRuntimeIdentifier>
</PropertyGroup>

Expand Down Expand Up @@ -169,6 +170,10 @@ Copyright (c) .NET Foundation. All rights reserved.
ResourceName="ImplicitRuntimeIdentifierResolutionForPublishPropertyFailed"
FormatArguments="SelfContained"/>

<NETSdkError Condition="'$(PublishSelfContained)' == 'true' and '$(RuntimeIdentifier)' == '' and '$(RuntimeIdentifiers)' == ''"
ResourceName="ImplicitRuntimeIdentifierResolutionForPublishPropertyFailed"
FormatArguments="PublishSelfContained"/>

<NETSdkError Condition="'$(PublishReadyToRun)' == 'true' and '$(RuntimeIdentifier)' == ''"
ResourceName="ImplicitRuntimeIdentifierResolutionForPublishPropertyFailed"
FormatArguments="PublishReadyToRun"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ Copyright (c) .NET Foundation. All rights reserved.

<PropertyGroup>
<_IsExecutable Condition="'$(OutputType)' == 'Exe' or '$(OutputType)'=='WinExe'">true</_IsExecutable>

</PropertyGroup>

<PropertyGroup Condition="'$(HasRuntimeOutput)' == ''">
Expand All @@ -35,6 +34,9 @@ Copyright (c) .NET Foundation. All rights reserved.
<!-- Set default intermediate and output paths -->
<Import Project="$(MSBuildThisFileDirectory)Microsoft.NET.DefaultOutputPaths.targets" Condition="'$(UsingNETSdkDefaults)' == 'true'"/>

<!-- Allow targets to edit SelfContained.-->
<Import Project="Microsoft.NET.ForceCommandLineSelfContainedToBeLocal.targets" Condition=" '$(PublishSelfContained)' != '' "/>

<!-- Before any additional SDK targets are imported, import the publish profile.
This allows the publish profile to set properties like RuntimeIdentifier and them be
respected by the SDK. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<PropertyGroup>
<Configurations Condition=" '$(Configurations)' == '' ">Debug;Release</Configurations>
<Platforms Condition=" '$(Platforms)' == '' ">AnyCPU</Platforms>
<Configuration Condition="'$(Configuration)' == '' ">Debug</Configuration>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,34 @@ public void It_can_publish_runtime_specific_apps_with_library_dependencies_self_
publishCommand.Execute(new [] {"-property:SelfContained=true", "-property:_CommandLineDefinedSelfContained=true", $"-property:RuntimeIdentifier={rid}", "-property:_CommandLineDefinedRuntimeIdentifier=true" }).Should().Pass().And.NotHaveStdOutContaining("warning");
}

[Theory]
[InlineData("net7.0")]
public void It_does_not_build_SelfContained_due_to_PublishSelfContained_being_true(string targetFramework)
{
var runtimeIdentifier = EnvironmentInfo.GetCompatibleRid(targetFramework);
var testAsset = _testAssetsManager
.CopyTestAsset("HelloWorld", identifier: targetFramework)
.WithSource()
.WithTargetFramework(targetFramework)
.WithProjectChanges(project =>
{
var ns = project.Root.Name.Namespace;
var propertyGroup = project.Root.Elements(ns + "PropertyGroup").First();
propertyGroup.Add(new XElement(ns + "RuntimeIdentifier", runtimeIdentifier));
propertyGroup.Add(new XElement(ns + "PublishSelfContained", "true"));
});

var buildCommand = new BuildCommand(testAsset);

buildCommand
.Execute("-p:SelfContained=false")
.Should()
.Pass();

var outputDirectory = buildCommand.GetOutputDirectory(targetFramework, runtimeIdentifier: runtimeIdentifier);
outputDirectory.Should().NotHaveFile("hostfxr.dll");
}

[Theory]
[InlineData("net7.0")]
public void It_builds_a_runnable_output_with_Prefer32Bit(string targetFramework)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

using System;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
using FluentAssertions;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools;
Expand Down Expand Up @@ -137,6 +139,85 @@ public void ItPublishesSelfContainedWithRid(string args)
.And.HaveStdOutContaining("Hello World");
}

[Fact]
public void ItPublishesSelfContainedWithPublishSelfContainedTrue()
{
var testAppName = "MSBuildTestApp";
var rid = EnvironmentInfo.GetCompatibleRid();
var outputDirectory = PublishApp(testAppName, rid, "-p:PublishSelfContained=true");

var outputProgram = Path.Combine(outputDirectory.FullName, $"{testAppName}{Constants.ExeSuffix}");

outputDirectory.Should().HaveFiles(new[] {
"System.dll", // File that should only exist if self contained
});

new RunExeCommand(Log, outputProgram)
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
}

[Theory]
[InlineData("net7.0")]
public void ItPublishesSelfContainedWithPublishSelfContainedProperty(string targetFramework)
{
var rid = EnvironmentInfo.GetCompatibleRid(targetFramework);
var testAsset = _testAssetsManager
.CopyTestAsset("HelloWorld", identifier: targetFramework)
.WithSource()
.WithTargetFramework(targetFramework)
.WithProjectChanges(project =>
{
var ns = project.Root.Name.Namespace;
var propertyGroup = project.Root.Elements(ns + "PropertyGroup").First();
propertyGroup.Add(new XElement(ns + "PublishSelfContained", "true"));
});

var publishCommand = new PublishCommand(testAsset);
var publishResult = publishCommand.Execute($"/p:RuntimeIdentifier={rid}");

publishResult.Should().Pass();

var publishDirectory = publishCommand.GetOutputDirectory(
targetFramework: targetFramework,
runtimeIdentifier: rid);
publishDirectory.Should().HaveFiles(new[] {
"HelloWorld.dll",
"System.dll"
});
}

[RequiresMSBuildVersionTheory("17.5.0.0")] // This needs _IsPublishing to be set in MSBuild to pass.
[InlineData("net7.0")]
public void PublishSelfContainedPropertyOverridesSelfContainProperty(string targetFramework)
{
var rid = EnvironmentInfo.GetCompatibleRid(targetFramework);

var testAsset = _testAssetsManager
.CopyTestAsset("HelloWorld")
.WithSource()
.WithProjectChanges(project =>
{
var ns = project.Root.Name.Namespace;
var propertyGroup = project.Root.Elements(ns + "PropertyGroup").First();
propertyGroup.Add(new XElement(ns + "PublishSelfContained", "true"));
});

var publishCommand = new PublishCommand(testAsset);
var publishResult = publishCommand.Execute( $"/p:RuntimeIdentifier={rid}", "/p:SelfContained=false");

publishResult.Should().Pass();

var publishDirectory = publishCommand.GetOutputDirectory(
targetFramework: targetFramework,
runtimeIdentifier: rid);
publishDirectory.Should().HaveFiles(new[] {
"HelloWorld.dll",
"System.dll" // File that should only exist if self contained
});
}

[Theory]
[InlineData("--sc=false")]
[InlineData("--self-contained=false")]
Expand Down

0 comments on commit 35bdab7

Please sign in to comment.