diff --git a/NuGet.Config b/NuGet.Config index baa008de9..559db7b79 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -3,6 +3,7 @@ + diff --git a/build/Microsoft.DotNet.Cli.BundledTemplates.proj b/build/Microsoft.DotNet.Cli.BundledTemplates.proj new file mode 100644 index 000000000..0efbc908d --- /dev/null +++ b/build/Microsoft.DotNet.Cli.BundledTemplates.proj @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + $(NuGetPackagesDir)/$(TemplatePackageName.ToLower())/$(TemplatePackageVersion.ToLower()) + + + diff --git a/build/Microsoft.DotNet.Cli.BundledTemplates.props b/build/Microsoft.DotNet.Cli.BundledTemplates.props new file mode 100644 index 000000000..9280486a0 --- /dev/null +++ b/build/Microsoft.DotNet.Cli.BundledTemplates.props @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/build/Microsoft.DotNet.Cli.Compile.targets b/build/Microsoft.DotNet.Cli.Compile.targets index 47c7e74d8..908d2ae94 100644 --- a/build/Microsoft.DotNet.Cli.Compile.targets +++ b/build/Microsoft.DotNet.Cli.Compile.targets @@ -18,6 +18,7 @@ SetupStage; CompileStage; PublishSdks; + PublishTemplates; BuildProjectsForNuGetPackages; GetNuGetPackagesArchive;" /> @@ -263,4 +264,25 @@ Projects="@(SdksToBundle)"> + + + + + + CLIBuildDll=$(CLIBuildDll); + NuGetPackagesDir=$(NuGetPackagesDir); + TemplateLayoutDirectory=$(SdkOutputDirectory)/Templates; + TemplatePackageName=%(BundledTemplate.Identity); + TemplatePackageVersion=%(BundledTemplate.Version); + Stage0Directory=$(Stage0Directory) + + + + + + + \ No newline at end of file diff --git a/build/Microsoft.DotNet.Cli.DependencyVersions.props b/build/Microsoft.DotNet.Cli.DependencyVersions.props index d4e750424..2e4f35ab1 100644 --- a/build/Microsoft.DotNet.Cli.DependencyVersions.props +++ b/build/Microsoft.DotNet.Cli.DependencyVersions.props @@ -4,7 +4,8 @@ 15.1.0-preview-000503-01 2.0.0-rc3-61212-03 1.0.0-alpha-20170105-1 - 1.0.0-alpha-20170104-1-189 + 1.0.0-alpha-20170106-1-203 15.0.0-preview-20161227-02 + 1.0.0-beta1-20170106-79 diff --git a/build/Microsoft.DotNet.Cli.Prepare.targets b/build/Microsoft.DotNet.Cli.Prepare.targets index 4e53dbc2c..b7b34b8a3 100644 --- a/build/Microsoft.DotNet.Cli.Prepare.targets +++ b/build/Microsoft.DotNet.Cli.Prepare.targets @@ -3,6 +3,7 @@ + + + + + Library + netcoreapp1.0 + false + + + + + $(TemplatePackageVersion) + + + + + diff --git a/src/dotnet/Program.cs b/src/dotnet/Program.cs index 526209659..a28b0bc37 100644 --- a/src/dotnet/Program.cs +++ b/src/dotnet/Program.cs @@ -16,6 +16,7 @@ using Microsoft.DotNet.Tools.List; using Microsoft.DotNet.Tools.Migrate; using Microsoft.DotNet.Tools.MSBuild; using Microsoft.DotNet.Tools.New; +using Microsoft.DotNet.Tools.New3; using Microsoft.DotNet.Tools.NuGet; using Microsoft.DotNet.Tools.Pack; using Microsoft.DotNet.Tools.Publish; @@ -42,6 +43,7 @@ namespace Microsoft.DotNet.Cli ["migrate"] = MigrateCommand.Run, ["msbuild"] = MSBuildCommand.Run, ["new"] = NewCommand.Run, + ["new3"] = New3CommandShim.Run, ["nuget"] = NuGetCommand.Run, ["pack"] = PackCommand.Run, ["publish"] = PublishCommand.Run, diff --git a/src/dotnet/commands/dotnet-new3/New3CommandShim.cs b/src/dotnet/commands/dotnet-new3/New3CommandShim.cs new file mode 100644 index 000000000..490417643 --- /dev/null +++ b/src/dotnet/commands/dotnet-new3/New3CommandShim.cs @@ -0,0 +1,71 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using Microsoft.TemplateEngine.Abstractions; +using Microsoft.TemplateEngine.Cli; +using Microsoft.TemplateEngine.Edge; +using Microsoft.TemplateEngine.Orchestrator.RunnableProjects; +using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Config; +using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Macros; +using Microsoft.TemplateEngine.Utils; + +namespace Microsoft.DotNet.Tools.New3 +{ + internal class New3CommandShim + { + private const string HostIdentifier = "dotnetcli"; + private const string HostVersion = "1.0.0"; + private const string CommandName = "new3"; + + public static int Run(string[] args) + { + return New3Command.Run(CommandName, CreateHost(), FirstRun, args); + } + + private static ITemplateEngineHost CreateHost() + { + var builtIns = new Dictionary> + { + { new Guid("0C434DF7-E2CB-4DEE-B216-D7C58C8EB4B3"), () => typeof(RunnableProjectGenerator) }, + { new Guid("3147965A-08E5-4523-B869-02C8E9A8AAA1"), () => typeof(BalancedNestingConfig) }, + { new Guid("3E8BCBF0-D631-45BA-A12D-FBF1DE03AA38"), () => typeof(ConditionalConfig) }, + { new Guid("A1E27A4B-9608-47F1-B3B8-F70DF62DC521"), () => typeof(FlagsConfig) }, + { new Guid("3FAE1942-7257-4247-B44D-2DDE07CB4A4A"), () => typeof(IncludeConfig) }, + { new Guid("3D33B3BF-F40E-43EB-A14D-F40516F880CD"), () => typeof(RegionConfig) }, + { new Guid("62DB7F1F-A10E-46F0-953F-A28A03A81CD1"), () => typeof(ReplacementConfig) }, + { new Guid("370996FE-2943-4AED-B2F6-EC03F0B75B4A"), () => typeof(ConstantMacro) }, + { new Guid("BB625F71-6404-4550-98AF-B2E546F46C5F"), () => typeof(EvaluateMacro) }, + { new Guid("10919008-4E13-4FA8-825C-3B4DA855578E"), () => typeof(GuidMacro) }, + { new Guid("F2B423D7-3C23-4489-816A-41D8D2A98596"), () => typeof(NowMacro) }, + { new Guid("011E8DC1-8544-4360-9B40-65FD916049B7"), () => typeof(RandomMacro) }, + { new Guid("8A4D4937-E23F-426D-8398-3BDBD1873ADB"), () => typeof(RegexMacro) }, + { new Guid("B57D64E0-9B4F-4ABE-9366-711170FD5294"), () => typeof(SwitchMacro) }, + { new Guid("10919118-4E13-4FA9-825C-3B4DA855578E"), () => typeof(CaseChangeMacro) } + }.ToList(); + + var preferences = new Dictionary + { + { "prefs:language", "C#" } + }; + + return new DefaultTemplateEngineHost(HostIdentifier, HostVersion, CultureInfo.CurrentCulture.Name, preferences, builtIns); + } + + private static void FirstRun(ITemplateEngineHost host, IInstaller installer) + { + var templatesDir = Path.Combine(Paths.Global.BaseDir, "Templates"); + + if (templatesDir.Exists()) + { + var layoutIncludedPackages = host.FileSystem.EnumerateFiles(templatesDir, "*.nupkg", SearchOption.TopDirectoryOnly); + installer.InstallPackages(layoutIncludedPackages); + } + } + } +} diff --git a/src/dotnet/dotnet.csproj b/src/dotnet/dotnet.csproj index 6e3650ff9..a975f3448 100755 --- a/src/dotnet/dotnet.csproj +++ b/src/dotnet/dotnet.csproj @@ -71,6 +71,8 @@ 1.0.1-beta-000933 + + diff --git a/test/dotnet-new.Tests/GivenThatIWantANewApp.cs b/test/dotnet-new.Tests/GivenThatIWantANewApp.cs index 21ba80b21..2d38f2c53 100644 --- a/test/dotnet-new.Tests/GivenThatIWantANewApp.cs +++ b/test/dotnet-new.Tests/GivenThatIWantANewApp.cs @@ -2,12 +2,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Collections.Generic; using System.IO; -using Microsoft.Build.Construction; using Microsoft.DotNet.Tools.Test.Utilities; -using Xunit; using FluentAssertions; +using Xunit; namespace Microsoft.DotNet.New.Tests { diff --git a/test/dotnet-new.Tests/New3/GivenThatIWantANewApp.cs b/test/dotnet-new.Tests/New3/GivenThatIWantANewApp.cs new file mode 100644 index 000000000..97666f864 --- /dev/null +++ b/test/dotnet-new.Tests/New3/GivenThatIWantANewApp.cs @@ -0,0 +1,68 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.DotNet.Tools.Test.Utilities; +using System; +using System.IO; +using FluentAssertions; +using Xunit; + +namespace Microsoft.DotNet.New3.Tests +{ + public class GivenThatIWantANewApp : New3TestBase + { + [Fact] + public void When_dotnet_new_is_invoked_mupliple_times_it_should_fail() + { + var rootPath = TestAssetsManager.CreateTestDirectory(identifier: "new3").Path; + + new TestCommand("dotnet") { WorkingDirectory = rootPath } + .Execute($"new3 console"); + + DateTime expectedState = Directory.GetLastWriteTime(rootPath); + + var result = new TestCommand("dotnet") { WorkingDirectory = rootPath } + .ExecuteWithCapturedOutput($"new3 console"); + + DateTime actualState = Directory.GetLastWriteTime(rootPath); + + Assert.Equal(expectedState, actualState); + + result.Should().Fail(); + } + + [Fact] + public void RestoreDoesNotUseAnyCliProducedPackagesOnItsTemplates() + { + string[] cSharpTemplates = new[] { "console", "classlib", "mstest", "xunit", "web", "mvc", "webapi" }; + + var rootPath = TestAssetsManager.CreateTestDirectory(identifier: "new3").Path; + var packagesDirectory = Path.Combine(rootPath, "packages"); + + foreach (string cSharpTemplate in cSharpTemplates) + { + var projectFolder = Path.Combine(rootPath, cSharpTemplate + "1"); + Directory.CreateDirectory(projectFolder); + CreateAndRestoreNewProject(cSharpTemplate, projectFolder, packagesDirectory); + } + + Directory.EnumerateFiles(packagesDirectory, $"*.nupkg", SearchOption.AllDirectories) + .Should().NotContain(p => p.Contains("Microsoft.DotNet.Cli.Utils")); + } + + private void CreateAndRestoreNewProject( + string projectType, + string projectFolder, + string packagesDirectory) + { + new TestCommand("dotnet") { WorkingDirectory = projectFolder } + .Execute($"new3 {projectType}") + .Should().Pass(); + + new RestoreCommand() + .WithWorkingDirectory(projectFolder) + .Execute($"--packages {packagesDirectory} /p:SkipInvalidConfigurations=true") + .Should().Pass(); + } + } +} diff --git a/test/dotnet-new.Tests/New3/GivenThatIWantANewAppWithSpecifiedType.cs b/test/dotnet-new.Tests/New3/GivenThatIWantANewAppWithSpecifiedType.cs new file mode 100644 index 000000000..3fbe1aef0 --- /dev/null +++ b/test/dotnet-new.Tests/New3/GivenThatIWantANewAppWithSpecifiedType.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Microsoft.DotNet.TestFramework; +using Microsoft.DotNet.Tools.Test.Utilities; +using Xunit; +using FluentAssertions; + +namespace Microsoft.DotNet.New3.Tests +{ + public class GivenThatIWantANewAppWithSpecifiedType : New3TestBase + { + [Theory] + [InlineData("C#", "console", false)] + [InlineData("C#", "classlib", false)] + [InlineData("C#", "mstest", false)] + [InlineData("C#", "xunit", false)] + [InlineData("C#", "web", true)] + [InlineData("C#", "mvc", true)] + [InlineData("C#", "webapi", true)] + [InlineData("F#", "console", false)] + [InlineData("F#", "classlib", false)] + [InlineData("F#", "mstest", false)] + [InlineData("F#", "xunit", false)] + [InlineData("F#", "mvc", true)] + public void TemplateRestoresAndBuildsWithoutWarnings( + string language, + string projectType, + bool useNuGetConfigForAspNet) + { + string rootPath = TestAssetsManager.CreateTestDirectory(identifier: $"new3_{language}_{projectType}").Path; + + new TestCommand("dotnet") { WorkingDirectory = rootPath } + .Execute($"new3 {projectType} -lang {language}") + .Should().Pass(); + + if (useNuGetConfigForAspNet) + { + File.Copy("NuGet.tempaspnetpatch.config", Path.Combine(rootPath, "NuGet.Config")); + } + + new TestCommand("dotnet") + .WithWorkingDirectory(rootPath) + .Execute($"restore") + .Should().Pass(); + + var buildResult = new TestCommand("dotnet") + .WithWorkingDirectory(rootPath) + .ExecuteWithCapturedOutput("build") + .Should().Pass() + .And.NotHaveStdErr(); + } + } +} diff --git a/test/dotnet-new.Tests/New3/New3TestBase.cs b/test/dotnet-new.Tests/New3/New3TestBase.cs new file mode 100644 index 000000000..8d1c4ac71 --- /dev/null +++ b/test/dotnet-new.Tests/New3/New3TestBase.cs @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.DotNet.Tools.Test.Utilities; +using Xunit; + +[assembly: CollectionBehavior(DisableTestParallelization = true)] + +namespace Microsoft.DotNet.New3.Tests +{ + public class New3TestBase : TestBase + { + private static readonly object InitializationSync = new object(); + private static bool _isInitialized; + + protected New3TestBase() + { + if (_isInitialized) + { + return; + } + + lock (InitializationSync) + { + if (_isInitialized) + { + return; + } + + //Force any previously computed configuration to be cleared + new TestCommand("dotnet").Execute("new3 --debug:reinit"); + _isInitialized = true; + } + } + } +} diff --git a/test/dotnet-new.Tests/dotnet-new.Tests.csproj b/test/dotnet-new.Tests/dotnet-new.Tests.csproj index 62d5752d2..30e772e67 100644 --- a/test/dotnet-new.Tests/dotnet-new.Tests.csproj +++ b/test/dotnet-new.Tests/dotnet-new.Tests.csproj @@ -1,6 +1,6 @@  - + netcoreapp1.0 true