diff --git a/Directory.Packages.props b/Directory.Packages.props index f7aa56c1..f4782741 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -17,7 +17,9 @@ + + diff --git a/MSBuildSdks.sln b/MSBuildSdks.sln index 6c20869a..59336373 100644 --- a/MSBuildSdks.sln +++ b/MSBuildSdks.sln @@ -84,6 +84,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Build.CopyOnWrite EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Build.CopyOnWrite.UnitTests", "src\CopyOnWrite.UnitTests\Microsoft.Build.CopyOnWrite.UnitTests.csproj", "{AF9F2AFE-04D4-40B3-B17F-54ABD3DE7E4E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Build.Traversal.Templates", "src\Traversal\Templates\Microsoft.Build.Traversal.Templates.csproj", "{1AEE3631-B92A-4A7F-974F-BAB420CE3913}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Build.NoTargets.Templates", "src\NoTargets\Templates\Microsoft.Build.NoTargets.Templates.csproj", "{03A56E49-A35E-4F9D-AEAE-B0257BF6F919}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -146,6 +150,14 @@ Global {AF9F2AFE-04D4-40B3-B17F-54ABD3DE7E4E}.Debug|Any CPU.Build.0 = Debug|Any CPU {AF9F2AFE-04D4-40B3-B17F-54ABD3DE7E4E}.Release|Any CPU.ActiveCfg = Release|Any CPU {AF9F2AFE-04D4-40B3-B17F-54ABD3DE7E4E}.Release|Any CPU.Build.0 = Release|Any CPU + {1AEE3631-B92A-4A7F-974F-BAB420CE3913}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1AEE3631-B92A-4A7F-974F-BAB420CE3913}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1AEE3631-B92A-4A7F-974F-BAB420CE3913}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1AEE3631-B92A-4A7F-974F-BAB420CE3913}.Release|Any CPU.Build.0 = Release|Any CPU + {03A56E49-A35E-4F9D-AEAE-B0257BF6F919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {03A56E49-A35E-4F9D-AEAE-B0257BF6F919}.Debug|Any CPU.Build.0 = Debug|Any CPU + {03A56E49-A35E-4F9D-AEAE-B0257BF6F919}.Release|Any CPU.ActiveCfg = Release|Any CPU + {03A56E49-A35E-4F9D-AEAE-B0257BF6F919}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/NoTargets.UnitTests/Microsoft.Build.NoTargets.UnitTests.csproj b/src/NoTargets.UnitTests/Microsoft.Build.NoTargets.UnitTests.csproj index 6d719f6c..9554e354 100644 --- a/src/NoTargets.UnitTests/Microsoft.Build.NoTargets.UnitTests.csproj +++ b/src/NoTargets.UnitTests/Microsoft.Build.NoTargets.UnitTests.csproj @@ -4,8 +4,12 @@ + + @@ -20,5 +24,8 @@ + diff --git a/src/NoTargets.UnitTests/Snapshots/README.md b/src/NoTargets.UnitTests/Snapshots/README.md new file mode 100644 index 00000000..e59fcf69 --- /dev/null +++ b/src/NoTargets.UnitTests/Snapshots/README.md @@ -0,0 +1,3 @@ +This folder contains snapshots of the templates. These snapshots are used by the unit tests to validate template +instantiations. See https://github.com/dotnet/templating/blob/main/docs/authoring-tools/Templates-Testing-Tooling.md +for more information. \ No newline at end of file diff --git a/src/NoTargets.UnitTests/Snapshots/RespectsExplicitName.notargets.--name#asdf.verified/notargets/asdf.msbuildproj b/src/NoTargets.UnitTests/Snapshots/RespectsExplicitName.notargets.--name#asdf.verified/notargets/asdf.msbuildproj new file mode 100644 index 00000000..961cb559 --- /dev/null +++ b/src/NoTargets.UnitTests/Snapshots/RespectsExplicitName.notargets.--name#asdf.verified/notargets/asdf.msbuildproj @@ -0,0 +1,30 @@ + + + + + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + netstandard2.0 + + + + + + + diff --git a/src/NoTargets.UnitTests/Snapshots/UsesDirectoryAsDefaultName.notargets._.verified/notargets/notargets.msbuildproj b/src/NoTargets.UnitTests/Snapshots/UsesDirectoryAsDefaultName.notargets._.verified/notargets/notargets.msbuildproj new file mode 100644 index 00000000..961cb559 --- /dev/null +++ b/src/NoTargets.UnitTests/Snapshots/UsesDirectoryAsDefaultName.notargets._.verified/notargets/notargets.msbuildproj @@ -0,0 +1,30 @@ + + + + + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + netstandard2.0 + + + + + + + diff --git a/src/NoTargets.UnitTests/TemplateTests.cs b/src/NoTargets.UnitTests/TemplateTests.cs new file mode 100644 index 00000000..10905d4f --- /dev/null +++ b/src/NoTargets.UnitTests/TemplateTests.cs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Licensed under the MIT license. + +#if NET8_0_OR_GREATER +using Microsoft.Extensions.Logging; +using Microsoft.TemplateEngine.Authoring.TemplateVerifier; +using System.IO; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.Build.NoTargets.UnitTests +{ + public class TemplateTests + { + private static readonly string RootPath = Path.GetDirectoryName(typeof(TemplateTests).Assembly.Location); + private readonly ILoggerFactory _loggerFactory; + + public TemplateTests(ITestOutputHelper xunitOutputHelper) + { + _loggerFactory = LoggerFactory.Create(config => + { + config.AddXUnit(xunitOutputHelper); + }); + } + + [Fact] + public async Task UsesDirectoryAsDefaultName() + { + TemplateVerifierOptions options = new (templateName: "notargets") + { + TemplatePath = Path.Combine(RootPath, "Templates", "notargets"), + }; + + VerificationEngine engine = new (_loggerFactory); + await engine.Execute(options); + } + + [Fact] + public async Task RespectsExplicitName() + { + TemplateVerifierOptions options = new (templateName: "notargets") + { + TemplateSpecificArgs = new[] { "--name", "asdf" }, + TemplatePath = Path.Combine(RootPath, "Templates", "notargets"), + }; + + VerificationEngine engine = new (_loggerFactory); + await engine.Execute(options); + } + } +} +#endif diff --git a/src/NoTargets/README.md b/src/NoTargets/README.md index f772a68e..e49ad356 100644 --- a/src/NoTargets/README.md +++ b/src/NoTargets/README.md @@ -9,9 +9,8 @@ The `Microsoft.Build.NoTargets` MSBuild project SDK allows project tree owners t To have a project that just copies a file: ```xml - - net46 + netstandard2.0 @@ -40,7 +39,7 @@ Or a project that runs a tool: ```xml - net46 + netstandard2.0 mytool.exe diff --git a/src/NoTargets/Templates/Microsoft.Build.NoTargets.Templates.csproj b/src/NoTargets/Templates/Microsoft.Build.NoTargets.Templates.csproj new file mode 100644 index 00000000..91d2537e --- /dev/null +++ b/src/NoTargets/Templates/Microsoft.Build.NoTargets.Templates.csproj @@ -0,0 +1,32 @@ + + + + MSBuild NoTargets templates + Templates for common MSBuild NoTargets projects + MSBuild NoTargets project template + $(BaseArtifactsPath)$(MSBuildProjectName)\ + true + Template + net8.0 + true + false + content + $(NoWarn);NU5128 + true + README.md + + + + false + + + + + + + + + + + + diff --git a/src/NoTargets/Templates/README.md b/src/NoTargets/Templates/README.md new file mode 100644 index 00000000..cf75930b --- /dev/null +++ b/src/NoTargets/Templates/README.md @@ -0,0 +1,24 @@ +# Microsoft.Build.Traversal.Templates + +## Installing the templates + +The templates are available on [NuGet](https://www.nuget.org/packages/Microsoft.Build.NoTargets.Templates/). +To install the templates, run the following command: + +```bash +dotnet new -i Microsoft.Build.NoTargets.Templates +``` + +## Using the templates + +Creating a new project with the default name + +```bash +dotnet new notargets +``` + +Creating a new project "AdventureWorks" (`-n` or `--name`): + +```bash +dotnet new notargets -n "AdventureWorks" +``` diff --git a/src/NoTargets/Templates/notargets/.template.config/template.json b/src/NoTargets/Templates/notargets/.template.config/template.json new file mode 100644 index 00000000..93b12978 --- /dev/null +++ b/src/NoTargets/Templates/notargets/.template.config/template.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "Microsoft", + "classifications": [ + "MSBuild" + ], + "identity": "Microsoft.Build.NoTargets", + "name": "MSBuild NoTargets Project", + "description": "A starter project file for MSBuild NoTargets projects", + "shortName": "notargets", + "tags": { + "type": "project" + }, + "sourceName": "NoTargets.Template" +} \ No newline at end of file diff --git a/src/NoTargets/Templates/notargets/NoTargets.Template.msbuildproj b/src/NoTargets/Templates/notargets/NoTargets.Template.msbuildproj new file mode 100644 index 00000000..961cb559 --- /dev/null +++ b/src/NoTargets/Templates/notargets/NoTargets.Template.msbuildproj @@ -0,0 +1,30 @@ + + + + + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + netstandard2.0 + + + + + + + diff --git a/src/Traversal.UnitTests/Microsoft.Build.Traversal.UnitTests.csproj b/src/Traversal.UnitTests/Microsoft.Build.Traversal.UnitTests.csproj index b944801e..99e3281b 100644 --- a/src/Traversal.UnitTests/Microsoft.Build.Traversal.UnitTests.csproj +++ b/src/Traversal.UnitTests/Microsoft.Build.Traversal.UnitTests.csproj @@ -4,8 +4,12 @@ + + @@ -20,5 +24,8 @@ + diff --git a/src/Traversal.UnitTests/Snapshots/README.md b/src/Traversal.UnitTests/Snapshots/README.md new file mode 100644 index 00000000..e59fcf69 --- /dev/null +++ b/src/Traversal.UnitTests/Snapshots/README.md @@ -0,0 +1,3 @@ +This folder contains snapshots of the templates. These snapshots are used by the unit tests to validate template +instantiations. See https://github.com/dotnet/templating/blob/main/docs/authoring-tools/Templates-Testing-Tooling.md +for more information. \ No newline at end of file diff --git a/src/Traversal.UnitTests/Snapshots/RespectsExplicitName.traversal.--name#asdf.verified/traversal/asdf.proj b/src/Traversal.UnitTests/Snapshots/RespectsExplicitName.traversal.--name#asdf.verified/traversal/asdf.proj new file mode 100644 index 00000000..1b5f1ce4 --- /dev/null +++ b/src/Traversal.UnitTests/Snapshots/RespectsExplicitName.traversal.--name#asdf.verified/traversal/asdf.proj @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/src/Traversal.UnitTests/Snapshots/UsesDirsAsDefaultName.traversal.--name#.verified/traversal/dirs.proj b/src/Traversal.UnitTests/Snapshots/UsesDirsAsDefaultName.traversal.--name#.verified/traversal/dirs.proj new file mode 100644 index 00000000..1b5f1ce4 --- /dev/null +++ b/src/Traversal.UnitTests/Snapshots/UsesDirsAsDefaultName.traversal.--name#.verified/traversal/dirs.proj @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/src/Traversal.UnitTests/TemplateTests.cs b/src/Traversal.UnitTests/TemplateTests.cs new file mode 100644 index 00000000..fd6f37d1 --- /dev/null +++ b/src/Traversal.UnitTests/TemplateTests.cs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Licensed under the MIT license. + +#if NET8_0_OR_GREATER +using Microsoft.Extensions.Logging; +using Microsoft.TemplateEngine.Authoring.TemplateVerifier; +using System.IO; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.Build.Traversal.UnitTests +{ + public class TemplateTests + { + private static readonly string RootPath = Path.GetDirectoryName(typeof(TemplateTests).Assembly.Location); + private readonly ILoggerFactory _loggerFactory; + + public TemplateTests(ITestOutputHelper xunitOutputHelper) + { + _loggerFactory = LoggerFactory.Create(config => + { + config.AddXUnit(xunitOutputHelper); + }); + } + + [Fact] + public async Task UsesDirsAsDefaultName() + { + TemplateVerifierOptions options = new (templateName: "traversal") + { + TemplateSpecificArgs = new[] { "--name", string.Empty }, // BUG: Workaround for https://github.com/dotnet/templating/issues/7394 + TemplatePath = Path.Combine(RootPath, "Templates", "traversal"), + }; + + VerificationEngine engine = new (_loggerFactory); + await engine.Execute(options); + } + + [Fact] + public async Task RespectsExplicitName() + { + TemplateVerifierOptions options = new (templateName: "traversal") + { + TemplateSpecificArgs = new[] { "--name", "asdf" }, + TemplatePath = Path.Combine(RootPath, "Templates", "traversal"), + }; + + VerificationEngine engine = new (_loggerFactory); + await engine.Execute(options); + } + } +} +#endif diff --git a/src/Traversal/Templates/Microsoft.Build.Traversal.Templates.csproj b/src/Traversal/Templates/Microsoft.Build.Traversal.Templates.csproj new file mode 100644 index 00000000..fdb9c2d9 --- /dev/null +++ b/src/Traversal/Templates/Microsoft.Build.Traversal.Templates.csproj @@ -0,0 +1,32 @@ + + + + MSBuild Traversal templates + Templates for common MSBuild traversal projects + MSBuild traversal dirs template + $(BaseArtifactsPath)$(MSBuildProjectName)\ + true + Template + net8.0 + true + false + content + $(NoWarn);NU5128 + true + README.md + + + + false + + + + + + + + + + + + diff --git a/src/Traversal/Templates/README.md b/src/Traversal/Templates/README.md new file mode 100644 index 00000000..227c625b --- /dev/null +++ b/src/Traversal/Templates/README.md @@ -0,0 +1,24 @@ +# Microsoft.Build.Traversal.Templates + +## Installing the templates + +The templates are available on [NuGet](https://www.nuget.org/packages/Microsoft.Build.Traversal.Templates/). +To install the templates, run the following command: + +```bash +dotnet new -i Microsoft.Build.Traversal.Templates +``` + +## Using the templates + +Creating a new project with the default name "dirs.proj" + +```bash +dotnet new traversal +``` + +Creating a new project "AdventureWorks" (`-n` or `--name`): + +```bash +dotnet new travesal -n "AdventureWorks" +``` diff --git a/src/Traversal/Templates/traversal/.template.config/template.json b/src/Traversal/Templates/traversal/.template.config/template.json new file mode 100644 index 00000000..7b17f86a --- /dev/null +++ b/src/Traversal/Templates/traversal/.template.config/template.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "Microsoft", + "classifications": [ + "MSBuild" + ], + "identity": "Microsoft.Build.Traversal", + "name": "MSBuild Traversal Project", + "description": "A starter project file for MSBuild Traversal projects", + "shortName": "traversal", + "tags": { + "type": "item" + }, + "sourceName": "dirs", + "preferDefaultName": true, + "defaultName": "dirs" +} \ No newline at end of file diff --git a/src/Traversal/Templates/traversal/dirs.proj b/src/Traversal/Templates/traversal/dirs.proj new file mode 100644 index 00000000..1b5f1ce4 --- /dev/null +++ b/src/Traversal/Templates/traversal/dirs.proj @@ -0,0 +1,21 @@ + + + + + + + + + +