diff --git a/src/Scaffolding/VS.Web.CG.Design/Program.cs b/src/Scaffolding/VS.Web.CG.Design/Program.cs index 0c86309b9..35c6ba2c2 100644 --- a/src/Scaffolding/VS.Web.CG.Design/Program.cs +++ b/src/Scaffolding/VS.Web.CG.Design/Program.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using Microsoft.DotNet.Scaffolding.Shared; +using Microsoft.DotNet.Scaffolding.Shared.ProjectModel; using Microsoft.Extensions.CommandLineUtils; namespace Microsoft.VisualStudio.Web.CodeGeneration.Design @@ -71,7 +72,9 @@ private static void Execute(string[] args, ConsoleLogger logger) { var messageOrchestrator = new MessageOrchestrator(client, logger); var projectInformation = messageOrchestrator.GetProjectInformation(); - + string projectAssetsFile = ProjectModelHelper.GetProjectAssetsFile(projectInformation); + //fix package dependencies sent from VS + projectInformation = projectInformation.AddPackageDependencies(projectAssetsFile); var codeGenArgs = ToolCommandLineHelper.FilterExecutorArguments(args); var isSimulationMode = ToolCommandLineHelper.IsSimulationMode(args); CodeGenCommandExecutor executor = new CodeGenCommandExecutor(projectInformation, diff --git a/src/Scaffolding/VS.Web.CG.Msbuild/ProjectContextWriter.cs b/src/Scaffolding/VS.Web.CG.Msbuild/ProjectContextWriter.cs index 5394883fb..56ffee2e6 100644 --- a/src/Scaffolding/VS.Web.CG.Msbuild/ProjectContextWriter.cs +++ b/src/Scaffolding/VS.Web.CG.Msbuild/ProjectContextWriter.cs @@ -15,6 +15,9 @@ namespace Microsoft.VisualStudio.Web.CodeGeneration.Msbuild { public class ProjectContextWriter : Build.Utilities.Task { + private const string EntityFrameworkCore = "Microsoft.EntityFrameworkCore"; + private const string AspNetCoreIdentity = "Microsoft.AspNetCore.Identity"; + private const string TargetsProperty = "targets"; private const string PackageFoldersProperty = "packageFolders"; private const string DependencyProperty = "dependencies"; @@ -89,7 +92,7 @@ public override bool Execute() AssemblyName = string.IsNullOrEmpty(this.AssemblyName) ? Path.GetFileName(this.AssemblyFullPath) : this.AssemblyName, CompilationAssemblies = GetCompilationAssemblies(this.ResolvedReferences), CompilationItems = this.CompilationItems.Select(i => i.ItemSpec), - PackageDependencies = GetPackageDependencies(this.ProjectAssetsFile), + PackageDependencies = GetPackageDependencies(this.ProjectAssetsFile, this.TargetFramework, this.TargetFrameworkMoniker), Config = this.AssemblyFullPath + ".config", Configuration = this.Configuration, DepsFile = this.ProjectDepsFileName, @@ -119,14 +122,20 @@ public override bool Execute() return true; } - private IEnumerable GetPackageDependencies(string projectAssetsFile) + internal static IEnumerable GetPackageDependencies(string projectAssetsFile, string tfm, string tfmMoniker) { IList packageDependencies = new List(); - if (!string.IsNullOrEmpty(projectAssetsFile) && File.Exists(projectAssetsFile) && !string.IsNullOrEmpty(TargetFramework)) + if (!string.IsNullOrEmpty(projectAssetsFile) && File.Exists(projectAssetsFile) && !string.IsNullOrEmpty(tfm)) { //target framework moniker for the current project. We use this to get all targets for said moniker. - var targetFramework = TargetFramework; - var targetFrameworkMoniker = TargetFrameworkMoniker; + var targetFramework = tfm; + var targetFrameworkMoniker = tfmMoniker; + if (string.IsNullOrEmpty(targetFrameworkMoniker)) + { + //if targetFrameworkMoniker is null, targetFramework is the TargetFrameworkMoniker (issue w/ IProjectContext sent from VS) + targetFrameworkMoniker = tfm; + targetFramework = ProjectModelHelper.GetShortTfm(tfm); + } string json = File.ReadAllText(projectAssetsFile); if (!string.IsNullOrEmpty(json) && !string.IsNullOrEmpty(targetFrameworkMoniker)) { @@ -159,7 +168,29 @@ private IEnumerable GetPackageDependencies(string project return packageDependencies; } - private IList DeserializePackages(JsonElement packages, JsonElement packageFolderPath, string targetFrameworkMoniker) + internal static IEnumerable GetScaffoldingAssemblies(IEnumerable dependencies) + { + var compilationAssemblies = new List(); + foreach (var item in dependencies) + { + //only add Microsoft.EntityFrameworkCore.* or Microsoft.AspNetCore.Identity.* assemblies. Any others might be duplicates which cause in-memory compilation errors and those are the assemblies we care about. + if (item.Name.Contains(EntityFrameworkCore, StringComparison.OrdinalIgnoreCase) || item.Name.Contains(AspNetCoreIdentity, StringComparison.OrdinalIgnoreCase)) + { + var name = $"{item.Name}.dll"; + //costly search but we're only doing it a handful of times. + var file = Directory.GetFiles(item.Path, name, SearchOption.AllDirectories).FirstOrDefault(); + if (file != null) + { + var resolvedPath = file.ToString(); + var reference = new ResolvedReference(name, resolvedPath); + compilationAssemblies.Add(reference); + } + } + } + return compilationAssemblies; + } + + private static IList DeserializePackages(JsonElement packages, JsonElement packageFolderPath, string targetFrameworkMoniker) { IList packageDependencies = new List(); var packagesEnumerator = packages.EnumerateObject(); @@ -172,7 +203,7 @@ private IList DeserializePackages(JsonElement packages, J if (!string.IsNullOrEmpty(fullName) && !string.IsNullOrEmpty(path) && package.Value.TryGetProperty(TypeProperty, out var type)) { //fullName is in the format {Package Name}/{Version} for example "System.Text.MoreText/2.1.1" Split into tuple. - Tuple nameAndVersion = GetName(fullName); + Tuple nameAndVersion = ProjectContextWriter.GetName(fullName); if (nameAndVersion != null) { var dependencyTypeValue = type.ToString(); @@ -182,7 +213,7 @@ private IList DeserializePackages(JsonElement packages, J DependencyTypeEnum = (DependencyType)dependencyType; } - string packagePath = GetPath(path, nameAndVersion); + string packagePath = ProjectContextWriter.GetPath(path, nameAndVersion); DependencyDescription dependency = new DependencyDescription(nameAndVersion.Item1, nameAndVersion.Item2, Directory.Exists(packagePath) ? packagePath : string.Empty, @@ -210,7 +241,7 @@ private IList DeserializePackages(JsonElement packages, J return packageDependencies; } - internal string GetPath(string nugetPath, Tuple nameAndVersion) + internal static string GetPath(string nugetPath, Tuple nameAndVersion) { string path = string.Empty; if (!string.IsNullOrEmpty(nugetPath) && !string.IsNullOrEmpty(nameAndVersion.Item1) && !string.IsNullOrEmpty(nameAndVersion.Item2)) @@ -222,7 +253,7 @@ internal string GetPath(string nugetPath, Tuple nameAndVersion) return path; } - private Tuple GetName(string fullName) + private static Tuple GetName(string fullName) { Tuple nameAndVersion = null; if (!string.IsNullOrEmpty(fullName)) diff --git a/src/Scaffolding/VS.Web.CG.Mvc/Common/EFValidationUtil.cs b/src/Scaffolding/VS.Web.CG.Mvc/Common/EFValidationUtil.cs index 66f2f48de..1fce22d67 100644 --- a/src/Scaffolding/VS.Web.CG.Mvc/Common/EFValidationUtil.cs +++ b/src/Scaffolding/VS.Web.CG.Mvc/Common/EFValidationUtil.cs @@ -12,21 +12,27 @@ internal static class EFValidationUtil { const string EfDesignPackageName = "Microsoft.EntityFrameworkCore.Design"; const string SqlServerPackageName = "Microsoft.EntityFrameworkCore.SqlServer"; + const string SqlitePackageName = "Microsoft.EntityFrameworkCore.Sqlite"; - internal static void ValidateEFDependencies(IEnumerable dependencies, bool useSqlite, bool calledFromCommandline) + internal static void ValidateEFDependencies(IEnumerable dependencies, bool useSqlite) { var isEFDesignPackagePresent = dependencies .Any(package => package.Name.Equals(EfDesignPackageName, StringComparison.OrdinalIgnoreCase)); - if (!isEFDesignPackagePresent && calledFromCommandline) + if (!isEFDesignPackagePresent) { - throw new InvalidOperationException( + throw new InvalidOperationException( string.Format(MessageStrings.InstallEfPackages, $"{EfDesignPackageName}")); } - if (!useSqlite) + if (useSqlite) + { + ValidateSqliteDependency(dependencies); + } + else { ValidateSqlServerDependency(dependencies); - } + } + } internal static void ValidateSqlServerDependency(IEnumerable dependencies) @@ -40,5 +46,17 @@ internal static void ValidateSqlServerDependency(IEnumerable dependencies) + { + var isSqlServerPackagePresent = dependencies + .Any(package => package.Name.Equals(SqlitePackageName, StringComparison.OrdinalIgnoreCase)); + + if (!isSqlServerPackagePresent) + { + throw new InvalidOperationException( + string.Format(MessageStrings.InstallSqlPackage, $"{SqlitePackageName}.")); + } + } } } diff --git a/src/Scaffolding/VS.Web.CG.Mvc/Controller/ControllerWithContextGenerator.cs b/src/Scaffolding/VS.Web.CG.Mvc/Controller/ControllerWithContextGenerator.cs index d749bf7a1..b3a634b93 100644 --- a/src/Scaffolding/VS.Web.CG.Mvc/Controller/ControllerWithContextGenerator.cs +++ b/src/Scaffolding/VS.Web.CG.Mvc/Controller/ControllerWithContextGenerator.cs @@ -59,7 +59,12 @@ public override async Task Generate(CommandLineGeneratorModel controllerGenerato { Contract.Assert(!String.IsNullOrEmpty(controllerGeneratorModel.ModelClass)); ValidateNameSpaceName(controllerGeneratorModel); - EFValidationUtil.ValidateEFDependencies(ProjectContext.PackageDependencies, controllerGeneratorModel.UseSqlite, CalledFromCommandline); + + if (!CalledFromCommandline) + { + EFValidationUtil.ValidateEFDependencies(ProjectContext.PackageDependencies, controllerGeneratorModel.UseSqlite); + } + string outputPath = ValidateAndGetOutputPath(controllerGeneratorModel); _areaName = GetAreaName(ApplicationInfo.ApplicationBasePath, outputPath); diff --git a/src/Scaffolding/VS.Web.CG.Mvc/RazorPage/EFModelBasedRazorPageScaffolder.cs b/src/Scaffolding/VS.Web.CG.Mvc/RazorPage/EFModelBasedRazorPageScaffolder.cs index 95fce32dd..081cc6d6a 100644 --- a/src/Scaffolding/VS.Web.CG.Mvc/RazorPage/EFModelBasedRazorPageScaffolder.cs +++ b/src/Scaffolding/VS.Web.CG.Mvc/RazorPage/EFModelBasedRazorPageScaffolder.cs @@ -79,7 +79,10 @@ public override async Task GenerateCode(RazorPageGeneratorModel razorGeneratorMo var outputPath = ValidateAndGetOutputPath(razorGeneratorModel, outputFileName: razorGeneratorModel.RazorPageName + Constants.ViewExtension); - EFValidationUtil.ValidateEFDependencies(_projectContext.PackageDependencies, razorGeneratorModel.UseSqlite, CalledFromCommandline); + if (!CalledFromCommandline) + { + EFValidationUtil.ValidateEFDependencies(_projectContext.PackageDependencies, razorGeneratorModel.UseSqlite); + } ModelTypeAndContextModel modelTypeAndContextModel = await ModelMetadataUtilities.ValidateModelAndGetEFMetadata( razorGeneratorModel, @@ -134,8 +137,11 @@ internal async Task GenerateViews(RazorPageGeneratorModel razorPageGeneratorMode ModelTypeAndContextModel modelTypeAndContextModel = null; string outputPath = ValidateAndGetOutputPath(razorPageGeneratorModel, string.Empty); - EFValidationUtil.ValidateEFDependencies(_projectContext.PackageDependencies, razorPageGeneratorModel.UseSqlite, CalledFromCommandline); - + if (!CalledFromCommandline) + { + EFValidationUtil.ValidateEFDependencies(_projectContext.PackageDependencies, razorPageGeneratorModel.UseSqlite); + } + modelTypeAndContextModel = await ModelMetadataUtilities.ValidateModelAndGetEFMetadata( razorPageGeneratorModel, _entityFrameworkService, diff --git a/src/Scaffolding/VS.Web.CG.Mvc/View/EFModelBasedViewScaffolder.cs b/src/Scaffolding/VS.Web.CG.Mvc/View/EFModelBasedViewScaffolder.cs index 9e10963da..80831327b 100644 --- a/src/Scaffolding/VS.Web.CG.Mvc/View/EFModelBasedViewScaffolder.cs +++ b/src/Scaffolding/VS.Web.CG.Mvc/View/EFModelBasedViewScaffolder.cs @@ -63,7 +63,11 @@ public override async Task GenerateCode(ViewGeneratorModel viewGeneratorModel) ModelTypeAndContextModel modelTypeAndContextModel = null; var outputPath = ValidateAndGetOutputPath(viewGeneratorModel, outputFileName: viewGeneratorModel.ViewName + Constants.ViewExtension); - EFValidationUtil.ValidateEFDependencies(_projectContext.PackageDependencies, viewGeneratorModel.UseSqlite, !string.IsNullOrEmpty(_projectContext.TargetFrameworkMoniker)); + if (!string.IsNullOrEmpty(_projectContext.TargetFrameworkMoniker)) + { + EFValidationUtil.ValidateEFDependencies(_projectContext.PackageDependencies, viewGeneratorModel.UseSqlite); + } + modelTypeAndContextModel = await ModelMetadataUtilities.ValidateModelAndGetEFMetadata( viewGeneratorModel, diff --git a/src/Scaffolding/VS.Web.CG.Utils/ProjectContextExtensions.cs b/src/Scaffolding/VS.Web.CG.Utils/ProjectContextExtensions.cs deleted file mode 100644 index f43c6f9d2..000000000 --- a/src/Scaffolding/VS.Web.CG.Utils/ProjectContextExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Linq; -using System.Collections.Generic; -using Microsoft.DotNet.Scaffolding.Shared.ProjectModel; - -namespace Microsoft.VisualStudio.Web.CodeGeneration.Utils -{ - public static class ProjectContextExtensions - { - public static DependencyDescription GetPackage(this IProjectContext context, string name) - { - Requires.NotNullOrEmpty(name, nameof(name)); - Requires.NotNull(context, nameof(context)); - - return context.PackageDependencies.FirstOrDefault(package => package.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); - } - - public static IEnumerable GetReferencingPackages(this IProjectContext context, string name) - { - Requires.NotNullOrEmpty(name, nameof(name)); - Requires.NotNull(context, nameof(context)); - - return context - .PackageDependencies - .Where(package => package - .Dependencies - .Any(dep => dep.Name.Equals(name, StringComparison.OrdinalIgnoreCase))); - } - } -} diff --git a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Microsoft.DotNet.Scaffolding.Shared.csproj b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Microsoft.DotNet.Scaffolding.Shared.csproj index 68b729134..be4b404f2 100644 --- a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Microsoft.DotNet.Scaffolding.Shared.csproj +++ b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Microsoft.DotNet.Scaffolding.Shared.csproj @@ -24,6 +24,7 @@ + @@ -34,6 +35,12 @@ True MessageStrings.resx + + Scaffolding\%(RecursiveDir)%(FileName) + + + Scaffolding\%(RecursiveDir)%(FileName) + diff --git a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/ProjectModel/ProjectContextExtensions.cs b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/ProjectModel/ProjectContextExtensions.cs new file mode 100644 index 000000000..d5daf2ddf --- /dev/null +++ b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/ProjectModel/ProjectContextExtensions.cs @@ -0,0 +1,67 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using System.Collections.Generic; +using Microsoft.VisualStudio.Web.CodeGeneration.Msbuild; +using Microsoft.VisualStudio.Web.CodeGeneration.Utils; + +namespace Microsoft.DotNet.Scaffolding.Shared.ProjectModel +{ + public static class ProjectContextExtensions + { + public static DependencyDescription GetPackage(this IProjectContext context, string name) + { + Requires.NotNullOrEmpty(name, nameof(name)); + Requires.NotNull(context, nameof(context)); + + return context.PackageDependencies.FirstOrDefault(package => package.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + } + + public static IEnumerable GetReferencingPackages(this IProjectContext context, string name) + { + Requires.NotNullOrEmpty(name, nameof(name)); + Requires.NotNull(context, nameof(context)); + + return context + .PackageDependencies + .Where(package => package + .Dependencies + .Any(dep => dep.Name.Equals(name, StringComparison.OrdinalIgnoreCase))); + } + public static IProjectContext AddPackageDependencies(this IProjectContext projectInformation, string projectAssetsFile) + { + //get project assets file + var packageDependencies = ProjectContextWriter.GetPackageDependencies(projectAssetsFile, projectInformation.TargetFramework, projectInformation.TargetFrameworkMoniker); + var additionalCompilation = ProjectContextWriter.GetScaffoldingAssemblies(packageDependencies).ToList(); + var compilationList = projectInformation.CompilationAssemblies.ToList(); + compilationList.AddRange(additionalCompilation); + var newProjectContext = new CommonProjectContext() + { + AssemblyFullPath = projectInformation.AssemblyFullPath, + AssemblyName = projectInformation.AssemblyName, + CompilationAssemblies = compilationList, + CompilationItems = projectInformation.CompilationItems, + PackageDependencies = packageDependencies, + Config = projectInformation.Config, + Configuration = projectInformation.Configuration, + DepsFile = projectInformation.DepsFile, + EmbededItems = projectInformation.EmbededItems, + IsClassLibrary = projectInformation.IsClassLibrary, + Platform = projectInformation.Platform, + ProjectFullPath = projectInformation.ProjectFullPath, + ProjectName = projectInformation.ProjectName, + ProjectReferences = projectInformation.ProjectReferences, + RootNamespace = projectInformation.RootNamespace, + RuntimeConfig = projectInformation.RuntimeConfig, + TargetDirectory = projectInformation.TargetDirectory, + TargetFramework = projectInformation.TargetFramework, + TargetFrameworkMoniker = projectInformation.TargetFrameworkMoniker, + GeneratedImplicitNamespaceImportFile = projectInformation.GeneratedImplicitNamespaceImportFile + }; + return newProjectContext; + } + + } +} diff --git a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/ProjectModel/ProjectModelHelper.cs b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/ProjectModel/ProjectModelHelper.cs new file mode 100644 index 000000000..47824e352 --- /dev/null +++ b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/ProjectModel/ProjectModelHelper.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.IO; + +namespace Microsoft.DotNet.Scaffolding.Shared.ProjectModel +{ + internal static class ProjectModelHelper + { + public static string GetShortTfm(string tfmMoniker) + { + string shortTfm = string.Empty; + if (!string.IsNullOrEmpty(tfmMoniker)) + { + tfmMoniker = tfmMoniker.Replace(" ", ""); + //NuGet.Frameworks.NuGetFramework.GetShortFolderName() is giving invalid results on .NET tfms. Will use a dictionary for now + ShortTfmDictionary.TryGetValue(tfmMoniker, out shortTfm); + } + return shortTfm; + } + + public static string GetProjectAssetsFile(IProjectContext projectInformation) + { + string projectFolder = Path.GetDirectoryName(projectInformation.ProjectFullPath); + if (!string.IsNullOrEmpty(projectFolder)) + { + return Path.Combine(projectFolder, "obj", "project.assets.json"); + } + return string.Empty; + } + + private static Dictionary ShortTfmDictionary = new Dictionary() + { + { ".NETCoreApp,Version=v3.1", "netcoreapp3.1" }, + { ".NETCoreApp,Version=v5.0", "net5.0" }, + { ".NETCoreApp,Version=v6.0", "net6.0" }, + { ".NETCoreApp,Version=v2.1", "netcoreapp2.1" } + }; + } +} diff --git a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Properties/AssemblyInfo.cs b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Properties/AssemblyInfo.cs index 81be51d2b..afb2e055c 100644 --- a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Properties/AssemblyInfo.cs +++ b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Properties/AssemblyInfo.cs @@ -10,6 +10,7 @@ [assembly:InternalsVisibleTo("Microsoft.VisualStudio.Web.CodeGeneration.Msbuild, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly:InternalsVisibleTo("Microsoft.VisualStudio.Web.CodeGeneration.EntityFrameworkCore, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly:InternalsVisibleTo("Microsoft.VisualStudio.Web.CodeGenerators.Mvc, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] +[assembly:InternalsVisibleTo("dotnet-aspnet-codegenerator-design, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] //test [assembly: InternalsVisibleTo("Microsoft.VisualStudio.Web.CodeGeneration.Core.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.Web.CodeGeneration.EntityFrameworkCore.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/test/Scaffolding/VS.Web.CG.MSBuild.Test/ProjectContextWriterTests.cs b/test/Scaffolding/VS.Web.CG.MSBuild.Test/ProjectContextWriterTests.cs index 3b529e44c..d7d12e482 100644 --- a/test/Scaffolding/VS.Web.CG.MSBuild.Test/ProjectContextWriterTests.cs +++ b/test/Scaffolding/VS.Web.CG.MSBuild.Test/ProjectContextWriterTests.cs @@ -54,8 +54,7 @@ public void GetPathTestWindows(string nugetPath, string packageName, string vers using (var fileProvider = new TemporaryFileProvider()) { Tuple nameAndVersion = new Tuple(packageName, version); - ProjectContextWriter writer = new ProjectContextWriter(); - Assert.Equal(expectedPath, writer.GetPath(nugetPath, nameAndVersion)); + Assert.Equal(expectedPath, ProjectContextWriter.GetPath(nugetPath, nameAndVersion)); } } @@ -72,8 +71,7 @@ public void GetPathTestOSX(string nugetPath, string packageName, string version, using (var fileProvider = new TemporaryFileProvider()) { Tuple nameAndVersion = new Tuple(packageName, version); - ProjectContextWriter writer = new ProjectContextWriter(); - Assert.Equal(expectedPath, writer.GetPath(nugetPath, nameAndVersion)); + Assert.Equal(expectedPath, ProjectContextWriter.GetPath(nugetPath, nameAndVersion)); } } } diff --git a/test/Shared/Microsoft.DotNet.Scaffolding.Shared.Tests/ProjectModelHelperTests.cs b/test/Shared/Microsoft.DotNet.Scaffolding.Shared.Tests/ProjectModelHelperTests.cs new file mode 100644 index 000000000..5a6e5199e --- /dev/null +++ b/test/Shared/Microsoft.DotNet.Scaffolding.Shared.Tests/ProjectModelHelperTests.cs @@ -0,0 +1,28 @@ +using Microsoft.DotNet.Scaffolding.Shared.ProjectModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Microsoft.DotNet.Scaffolding.Shared.Tests +{ + public class ProjectModelHelperTests + { + [Theory] + [InlineData(new object[] { + new string[] { ".NETCoreApp,Version=v3.1", ".NETCoreApp,Version=v5.0", ".NETCoreApp,Version=v6.0", ".NETCoreApp, Version = v2.1" }, + new string[] { "netcoreapp3.1", "net5.0", "net6.0", "netcoreapp2.1" } + })] + public void GetShortTfmTests(string[] tfmMonikers, string[] shortTfms) + { + for (int i = 0; i < tfmMonikers.Length; i++) + { + string tfmMoniker = tfmMonikers[i]; + string shortTfm = ProjectModelHelper.GetShortTfm(tfmMoniker); + Assert.Equal(shortTfm, shortTfms[i]); + } + } + } +}