Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/MSBuild.UnitTests/ProjectSchemaValidationHandler_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Microsoft.Build.CommandLine;
using Microsoft.Build.Framework;
using Microsoft.Build.Shared;
using Shouldly;
using Xunit;

#nullable disable
Expand Down Expand Up @@ -275,6 +276,63 @@ public void VerifyInvalidImportNotCaughtBySchema()
}
}

/// <summary>
/// The Sdk element is a valid child of Project (it is translated into implicit imports),
/// so a project consisting of nothing but an Sdk element must validate against the schema.
/// </summary>
[Fact]
public void VerifyValidSdkElementSchema()
{
string[] msbuildTempXsdFilenames = Array.Empty<string>();
string projectFilename = CreateTempFileOnDisk(@"
<Project xmlns=`msbuildnamespace`>
<Sdk Name=`Microsoft.NET.Sdk` Version=`1.0.0` MinimumVersion=`1.0.0` />
<Sdk Name=`Some.Other.Sdk` />
</Project>
");

try
{
Comment thread
ViktorHofer marked this conversation as resolved.
Resolved
// Create schema files in the temp folder
msbuildTempXsdFilenames = PrepareSchemaFiles();

Should.NotThrow(() => ProjectSchemaValidationHandler.VerifyProjectSchema(projectFilename, msbuildTempXsdFilenames[0], Path.GetTempPath()));
}
finally
{
File.Delete(projectFilename);
CleanupSchemaFiles(msbuildTempXsdFilenames);
}
}

/// <summary>
/// The Name attribute is required on the Sdk element, so omitting it must be
/// caught by the schema.
/// </summary>
[Fact]
public void VerifyInvalidSdkElementSchema()
{
string[] msbuildTempXsdFilenames = Array.Empty<string>();
string projectFilename = CreateTempFileOnDisk(@"
<Project xmlns=`msbuildnamespace`>
<Sdk Version=`1.0.0` />
</Project>
");

try
{
// Create schema files in the temp folder
msbuildTempXsdFilenames = PrepareSchemaFiles();

Should.Throw<InitializationException>(() => ProjectSchemaValidationHandler.VerifyProjectSchema(projectFilename, msbuildTempXsdFilenames[0], Path.GetTempPath()));
}
finally
{
File.Delete(projectFilename);
CleanupSchemaFiles(msbuildTempXsdFilenames);
}
}

#pragma warning disable format // region formatting is different in net7.0 and net472, and cannot be fixed for both
#region Helper Functions

Expand Down
23 changes: 23 additions & 0 deletions src/MSBuild/MSBuild/Microsoft.Build.Core.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
<xs:element name="Target" type="msb:TargetType"/>
<xs:element name="Import" type="msb:ImportType"/>
<xs:element name="ImportGroup" type="msb:ImportGroupType"/>
<xs:element name="Sdk" type="msb:SdkType"/>
<xs:element name="ProjectExtensions" type="msb:ProjectExtensionsType"/>
</xs:choice>
</xs:group>
Expand All @@ -65,6 +66,7 @@
<xs:element name="Target" type="msb:TargetType"/>
<xs:element name="Import" type="msb:ImportType"/>
<xs:element name="ImportGroup" type="msb:ImportGroupType"/>
<xs:element name="Sdk" type="msb:SdkType"/>
</xs:choice>
</xs:group>
<!-- ======================================================================================= -->
Expand Down Expand Up @@ -404,6 +406,27 @@
</xs:attribute>
</xs:complexType>
<!-- ======================================================================================= -->
<xs:complexType name="SdkType">
<xs:annotation>
<xs:documentation><!-- _locID_text="SdkType" _locComment="" -->Declares that the project should be built with the specified MSBuild SDK, by implicitly importing its Sdk.props at the top and its Sdk.targets at the bottom of the project</xs:documentation>
</xs:annotation>
<xs:attribute name="Name" type="msb:non_empty_string" use="required">
<xs:annotation>
<xs:documentation><!-- _locID_text="SdkType_Name" _locComment="" -->Name of the SDK this project should be built with</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Version" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation><!-- _locID_text="SdkType_Version" _locComment="" -->Optional expression used to specify the version of the SDK referenced by this element</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="MinimumVersion" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation><!-- _locID_text="SdkType_MinimumVersion" _locComment="" -->Optional expression used to specify the minimum SDK version required by this element</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<!-- ======================================================================================= -->
<xs:complexType name="ProjectExtensionsType" mixed="true">
<xs:annotation>
<xs:documentation><!-- _locID_text="ProjectExtensionsType" _locComment="" -->Optional section used by MSBuild hosts, that may contain arbitrary XML content that is ignored by MSBuild itself</xs:documentation>
Expand Down