From 5218b06f7aad146f1cafd6d4e5d21683eae43749 Mon Sep 17 00:00:00 2001 From: Paulo Morgado <470455+paulomorgado@users.noreply.github.com> Date: Fri, 30 Aug 2024 09:49:14 +0100 Subject: [PATCH 1/2] Summary of the changes - Refactor MSBuild integration to remove the need for EntityFrameworkCore.targets and GetEFProjectMetadata target. Fixes #23853 --- src/dotnet-ef/Project.cs | 90 +++++++------------ .../Resources/EntityFrameworkCore.targets | 28 ------ src/dotnet-ef/dotnet-ef.csproj | 4 - 3 files changed, 32 insertions(+), 90 deletions(-) delete mode 100644 src/dotnet-ef/Resources/EntityFrameworkCore.targets diff --git a/src/dotnet-ef/Project.cs b/src/dotnet-ef/Project.cs index 2d2fc218d66..9a15e8e320d 100644 --- a/src/dotnet-ef/Project.cs +++ b/src/dotnet-ef/Project.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Text; +using System.Text.Json; using Microsoft.EntityFrameworkCore.Tools.Properties; namespace Microsoft.EntityFrameworkCore.Tools; @@ -53,83 +55,55 @@ public static Project FromFile( Directory.CreateDirectory(buildExtensionsDir); - byte[] efTargets; - using (var input = typeof(Resources).Assembly.GetManifestResourceStream( - "Microsoft.EntityFrameworkCore.Tools.Resources.EntityFrameworkCore.targets")!) - { - efTargets = new byte[input.Length]; - input.ReadExactly(efTargets); - } - - var efTargetsPath = Path.Combine( - buildExtensionsDir, - Path.GetFileName(file) + ".EntityFrameworkCore.targets"); - - bool FileMatches() - { - try - { - return File.ReadAllBytes(efTargetsPath).SequenceEqual(efTargets); - } - catch - { - return false; - } - } - - // Avoid touching the targets file, if it matches what we need, to enable incremental builds - if (!File.Exists(efTargetsPath) || !FileMatches()) - { - Reporter.WriteVerbose(Resources.WritingFile(efTargetsPath)); - File.WriteAllBytes(efTargetsPath, efTargets); - } - IDictionary metadata; var metadataFile = Path.GetTempFileName(); try { - var propertyArg = "/property:EFProjectMetadataFile=" + metadataFile; + var args = new List + { + "msbuild", + }; + if (framework != null) { - propertyArg += ";TargetFramework=" + framework; + args.Add($"/property:TargetFramework={framework}"); } if (configuration != null) { - propertyArg += ";Configuration=" + configuration; + args.Add($"/property:Configuration={configuration}"); } if (runtime != null) { - propertyArg += ";RuntimeIdentifier=" + runtime; + args.Add($"/property:RuntimeIdentifier={runtime}"); } - var args = new List + foreach (var property in typeof(Project).GetProperties()) { - "msbuild", - "/target:GetEFProjectMetadata", - propertyArg, - "/verbosity:quiet", - "/nologo" - }; + args.Add($"/getProperty:{property.Name}"); + } + + args.Add("/getProperty:Platform"); args.Add(file); - var exitCode = Exe.Run("dotnet", args); + var output = new StringBuilder(); + + var exitCode = Exe.Run("dotnet", args, handleOutput: line => output.AppendLine(line)); if (exitCode != 0) { throw new CommandException(Resources.GetMetadataFailed); } - metadata = File.ReadLines(metadataFile).Select(l => l.Split([':'], 2)) - .ToDictionary(s => s[0], s => s[1].TrimStart()); + metadata = JsonSerializer.Deserialize>>(output.ToString())!["Properties"]; } finally { File.Delete(metadataFile); } - var platformTarget = metadata["PlatformTarget"]; + var platformTarget = metadata[nameof(PlatformTarget)]; if (platformTarget.Length == 0) { platformTarget = metadata["Platform"]; @@ -137,19 +111,19 @@ bool FileMatches() return new Project(file, framework, configuration, runtime) { - AssemblyName = metadata["AssemblyName"], - Language = metadata["Language"], - OutputPath = metadata["OutputPath"], + AssemblyName = metadata[nameof(AssemblyName)], + Language = metadata[nameof(Language)], + OutputPath = metadata[nameof(OutputPath)], PlatformTarget = platformTarget, - ProjectAssetsFile = metadata["ProjectAssetsFile"], - ProjectDir = metadata["ProjectDir"], - RootNamespace = metadata["RootNamespace"], - RuntimeFrameworkVersion = metadata["RuntimeFrameworkVersion"], - TargetFileName = metadata["TargetFileName"], - TargetFrameworkMoniker = metadata["TargetFrameworkMoniker"], - Nullable = metadata["Nullable"], - TargetFramework = metadata["TargetFramework"], - TargetPlatformIdentifier = metadata["TargetPlatformIdentifier"] + ProjectAssetsFile = metadata[nameof(ProjectAssetsFile)], + ProjectDir = metadata[nameof(ProjectDir)], + RootNamespace = metadata[nameof(RootNamespace)], + RuntimeFrameworkVersion = metadata[nameof(RuntimeFrameworkVersion)], + TargetFileName = metadata[nameof(TargetFileName)], + TargetFrameworkMoniker = metadata[nameof(TargetFrameworkMoniker)], + Nullable = metadata[nameof(Nullable)], + TargetFramework = metadata[nameof(TargetFramework)], + TargetPlatformIdentifier = metadata[nameof(TargetPlatformIdentifier)] }; } diff --git a/src/dotnet-ef/Resources/EntityFrameworkCore.targets b/src/dotnet-ef/Resources/EntityFrameworkCore.targets deleted file mode 100644 index 7d6485dcc7c..00000000000 --- a/src/dotnet-ef/Resources/EntityFrameworkCore.targets +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/dotnet-ef/dotnet-ef.csproj b/src/dotnet-ef/dotnet-ef.csproj index c4bd4eeb604..dd896deb182 100644 --- a/src/dotnet-ef/dotnet-ef.csproj +++ b/src/dotnet-ef/dotnet-ef.csproj @@ -50,10 +50,6 @@ dotnet ef database update - - - - TextTemplatingFileGenerator From 7b6211d1eef76f988903b63d6e90d97015eeaa1d Mon Sep 17 00:00:00 2001 From: Paulo Morgado <470455+paulomorgado@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:07:33 +0100 Subject: [PATCH 2/2] Remove msbuildprojectextensionspath --- src/dotnet-ef/Project.cs | 5 ----- src/dotnet-ef/ProjectOptions.cs | 2 -- src/dotnet-ef/Properties/Resources.Designer.cs | 4 ++-- src/dotnet-ef/Properties/Resources.resx | 4 ++-- src/dotnet-ef/RootCommand.cs | 5 +---- 5 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/dotnet-ef/Project.cs b/src/dotnet-ef/Project.cs index 9a15e8e320d..93e2fe7404a 100644 --- a/src/dotnet-ef/Project.cs +++ b/src/dotnet-ef/Project.cs @@ -44,17 +44,12 @@ public Project(string file, string? framework, string? configuration, string? ru public static Project FromFile( string file, - string? buildExtensionsDir, string? framework = null, string? configuration = null, string? runtime = null) { Debug.Assert(!string.IsNullOrEmpty(file), "file is null or empty."); - buildExtensionsDir ??= Path.Combine(Path.GetDirectoryName(file)!, "obj"); - - Directory.CreateDirectory(buildExtensionsDir); - IDictionary metadata; var metadataFile = Path.GetTempFileName(); try diff --git a/src/dotnet-ef/ProjectOptions.cs b/src/dotnet-ef/ProjectOptions.cs index 1acfcd19973..890c8d4f970 100644 --- a/src/dotnet-ef/ProjectOptions.cs +++ b/src/dotnet-ef/ProjectOptions.cs @@ -15,7 +15,6 @@ internal class ProjectOptions public CommandOption? Runtime { get; private set; } // ReSharper disable once InconsistentNaming - public CommandOption? MSBuildProjectExtensionsPath { get; private set; } public CommandOption? NoBuild { get; private set; } public void Configure(CommandLineApplication command) @@ -25,7 +24,6 @@ public void Configure(CommandLineApplication command) Framework = command.Option("--framework ", Resources.FrameworkDescription); Configuration = command.Option("--configuration ", Resources.ConfigurationDescription); Runtime = command.Option("--runtime ", Resources.RuntimeDescription); - MSBuildProjectExtensionsPath = command.Option("--msbuildprojectextensionspath ", Resources.ProjectExtensionsDescription); NoBuild = command.Option("--no-build", Resources.NoBuildDescription); } } diff --git a/src/dotnet-ef/Properties/Resources.Designer.cs b/src/dotnet-ef/Properties/Resources.Designer.cs index e181047a69b..406d06db3fd 100644 --- a/src/dotnet-ef/Properties/Resources.Designer.cs +++ b/src/dotnet-ef/Properties/Resources.Designer.cs @@ -176,7 +176,7 @@ public static string FrameworkDescription => GetString("FrameworkDescription"); /// - /// Unable to retrieve project metadata. Ensure it's an SDK-style project. If you're using a custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option. + /// Unable to retrieve project metadata. Ensure it's an SDK-style project. /// public static string GetMetadataFailed => GetString("GetMetadataFailed"); @@ -188,7 +188,7 @@ public static string IdempotentDescription => GetString("IdempotentDescription"); /// - /// Show JSON output. Use with --prefix-output to parse programatically. + /// Show JSON output. Use with --prefix-output to parse programmatically. /// public static string JsonDescription => GetString("JsonDescription"); diff --git a/src/dotnet-ef/Properties/Resources.resx b/src/dotnet-ef/Properties/Resources.resx index 69810354fcd..45c0a7bae0e 100644 --- a/src/dotnet-ef/Properties/Resources.resx +++ b/src/dotnet-ef/Properties/Resources.resx @@ -196,13 +196,13 @@ The target framework. Defaults to the first one in the project. - Unable to retrieve project metadata. Ensure it's an SDK-style project. If you're using a custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option. + Unable to retrieve project metadata. Ensure it's an SDK-style project. Generate a script that can be used on a database at any migration. - Show JSON output. Use with --prefix-output to parse programatically. + Show JSON output. Use with --prefix-output to parse programmatically. The target migration. If '0', all migrations will be reverted. Defaults to the last migration. diff --git a/src/dotnet-ef/RootCommand.cs b/src/dotnet-ef/RootCommand.cs index 9235279c9ed..ccaf9da43f2 100644 --- a/src/dotnet-ef/RootCommand.cs +++ b/src/dotnet-ef/RootCommand.cs @@ -19,7 +19,6 @@ internal class RootCommand : CommandBase private CommandOption? _framework; private CommandOption? _configuration; private CommandOption? _runtime; - private CommandOption? _msbuildprojectextensionspath; private CommandOption? _noBuild; private CommandOption? _help; private IList? _args; @@ -38,7 +37,6 @@ public override void Configure(CommandLineApplication command) _framework = options.Framework; _configuration = options.Configuration; _runtime = options.Runtime; - _msbuildprojectextensionspath = options.MSBuildProjectExtensionsPath; _noBuild = options.NoBuild; command.VersionOption("--version", GetVersion); @@ -68,10 +66,9 @@ protected override int Execute(string[] _) Reporter.WriteVerbose(Resources.UsingProject(projectFile)); Reporter.WriteVerbose(Resources.UsingStartupProject(startupProjectFile)); - var project = Project.FromFile(projectFile, _msbuildprojectextensionspath!.Value()); + var project = Project.FromFile(projectFile); var startupProject = Project.FromFile( startupProjectFile, - _msbuildprojectextensionspath.Value(), _framework!.Value(), _configuration!.Value(), _runtime!.Value());