From 060d790362720596baf964486b814abed942277b Mon Sep 17 00:00:00 2001 From: Zach Halzel Date: Wed, 22 Dec 2021 16:04:30 -0800 Subject: [PATCH 1/8] Add blazor server, and some code refactors --- .../CodeFiles/Blazor/Server/CallWebApi.razor | 48 ++++ .../cm_dotnet_blazorserver.json | 15 ++ .../CodeModifierConfigs/cm_dotnet_webapi.json | 2 + .../CodeModifierConfigs/cm_dotnet_webapp.json | 2 + .../CodeReaderWriter/ProjectModifier.cs | 251 ++++++++---------- .../Properties/Resources.Designer.cs | 10 + .../Properties/Resources.resx | 3 + .../CodeChange/CodeChangeHelper.cs | 1 + .../Project/ProjectModifierHelper.cs | 37 ++- 9 files changed, 211 insertions(+), 158 deletions(-) create mode 100644 src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeFiles/Blazor/Server/CallWebApi.razor diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeFiles/Blazor/Server/CallWebApi.razor b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeFiles/Blazor/Server/CallWebApi.razor new file mode 100644 index 0000000000..b53277db93 --- /dev/null +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeFiles/Blazor/Server/CallWebApi.razor @@ -0,0 +1,48 @@ +@page "/callwebapi" + +@using Microsoft.Identity.Web + +@inject IDownstreamWebApi downstreamAPI +@inject MicrosoftIdentityConsentAndConditionalAccessHandler ConsentHandler + +

Call an API

+ +

This component demonstrates fetching data from a Web API.

+ +@if (apiResult == null) +{ +

Loading...

+} +else +{ +

API Result

+ @apiResult +} + +@code { + private HttpResponseMessage response; + private string apiResult; + + protected override async Task OnInitializedAsync() + { + try + { + response = await downstreamAPI.CallWebApiForUserAsync( + "DownstreamApi", + options => options.RelativePath = ""); + + if (response.StatusCode == System.Net.HttpStatusCode.OK) + { + apiResult = await response.Content.ReadAsStringAsync(); + } + else + { + apiResult = "Failed to call the web API"; + } + } + catch (Exception ex) + { + ConsentHandler.HandleException(ex); + } + } +} diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_blazorserver.json b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_blazorserver.json index 30828ed1d0..9af02dacca 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_blazorserver.json +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_blazorserver.json @@ -3,6 +3,7 @@ "Files": [ { "FileName": "Program.cs", + "Options": [ "MinimalApp" ], "Methods": { "Global": { "CodeChanges": [ @@ -153,6 +154,13 @@ "Options": [ "MicrosoftGraph" ] + }, + { + "Block": "\r\n \r\n
\r\n \r\n Call Web API\r\n \r\n
\r\n \r\n", + "ReplaceSnippet": "\r\n \r\n \r\n", + "Options": [ + "DownstreamApi" + ] } ] }, @@ -162,6 +170,13 @@ "Options": [ "MicrosoftGraph" ] + }, + { + "FileName": "CallWebApi.razor", + "AddFilePath": "Pages/CallWebApi.razor", + "Options": [ + "DownstreamApi" + ] } ] } diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_webapi.json b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_webapi.json index a41180045b..aca197f5f2 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_webapi.json +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_webapi.json @@ -3,6 +3,7 @@ "Files": [ { "FileName": "Startup.cs", + "Options": [ "NonMinimalApp" ], "Methods": { "Configure": { "Parameters": [ "IApplicationBuilder", "IWebHostEnvironment" ], @@ -36,6 +37,7 @@ }, { "FileName": "Program.cs", + "Options": [ "MinimalApp" ], "Methods": { "Global": { "CodeChanges": [ diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_webapp.json b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_webapp.json index a043d19875..0a2987d228 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_webapp.json +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/CodeModifierConfigs/cm_dotnet_webapp.json @@ -3,6 +3,7 @@ "Files": [ { "FileName": "Startup.cs", + "Options": [ "NonMinimalApp" ], "Methods": { "Configure": { "Parameters": [ "IApplicationBuilder", "IWebHostEnvironment" ], @@ -70,6 +71,7 @@ }, { "FileName": "Program.cs", + "Options": [ "MinimalApp" ], "Methods": { "Global": { "CodeChanges": [ diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs index c95bc1c12f..13b33c9f53 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs @@ -79,40 +79,17 @@ public async Task AddAuthCodeAsync() private async Task HandleCodeFileAsync(CodeFile file, CodeAnalysis.Project project, CodeChangeOptions options) { - if (string.IsNullOrEmpty(file.FileName)) + if (file.FileName.EndsWith(".cs")) { - return; + await ModifyCsFile(file, project, options); } - - if (!string.IsNullOrEmpty(file.AddFilePath)) + else if (file.FileName.EndsWith(".cshtml")) { - AddFile(file); - return; - } - - var fileName = file.FileName.Equals("Startup.cs", StringComparison.OrdinalIgnoreCase) - ? await ProjectModifierHelper.GetStartupClass(_toolOptions.ProjectPath, project) - : file.FileName; - - if (fileName.Equals("Program.cs")) - { - // only modify Program.cs file if it's a minimal hosting app (as we made changes to the Startup.cs file). - if (options.IsMinimalApp) - { - await ModifyProgramCs(file, project, options); - } + await ModifyCshtmlFile(file, project, options); } - else if (fileName.EndsWith(".cs")) + else if (file.FileName.EndsWith(".razor")) { - await ModifyCsFile(fileName, file, project, options); - } - else if (fileName.EndsWith(".cshtml")) - { - await ModifyCshtmlFile(fileName, file, project, options); - } - else if (fileName.EndsWith(".razor")) - { - await ModifyRazorFile(fileName, file, project, options); + await ModifyRazorFile(file, project, options); } } @@ -155,147 +132,143 @@ private void AddFile(CodeFile file) Directory.CreateDirectory(fileDir); File.WriteAllText(filePath, codeFileString); } + return; } - internal async Task ModifyRazorFile(string fileName, CodeFile file, CodeAnalysis.Project project, CodeChangeOptions toolOptions) + internal async Task ModifyCsFile(CodeFile file, CodeAnalysis.Project project, CodeChangeOptions options) { - var document = project.Documents.Where(d => d.Name.EndsWith(fileName)).FirstOrDefault(); - if (document is null) + if (file.FileName.Equals("Startup.cs")) + { + // Startup class file name may be different + file.FileName = await ProjectModifierHelper.GetStartupClass(project) ?? file.FileName; + } + + var fileDoc = project.Documents.Where(d => d.Name.Equals(file.FileName)).FirstOrDefault(); + if (fileDoc is null) { return; } - var razorChanges = file?.RazorChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, toolOptions)); - var editedDocument = await ProjectModifierHelper.ModifyDocumentText(document, razorChanges); - await ProjectModifierHelper.UpdateDocument(document, editedDocument, _consoleLogger); - } + //get the file document to get the document root for editing. + DocumentEditor documentEditor = await DocumentEditor.CreateAsync(fileDoc); + if (documentEditor is null) + { + return; + } - internal async Task ModifyCshtmlFile(string fileName, CodeFile cshtmlFile, CodeAnalysis.Project project, CodeChangeOptions options) - { - string? filePath = Directory.EnumerateFiles(_toolOptions.ProjectPath, fileName, SearchOption.AllDirectories).FirstOrDefault(); + DocumentBuilder documentBuilder = new DocumentBuilder(documentEditor, file, _consoleLogger); + var modifiedRoot = file.FileName.Equals("Program.cs") + ? ModifyProgramCsRoot(documentBuilder, options, file) + : ModifyRoot(documentBuilder, options, file); - if (!string.IsNullOrEmpty(filePath)) + if (documentEditor.OriginalRoot != null && modifiedRoot != null) { - var fileDoc = project.Documents.Where(d => d.Name.Equals(filePath)).FirstOrDefault(); - if (fileDoc != null) - { - //add code snippets/changes. - if (cshtmlFile.Methods != null && cshtmlFile.Methods.Any()) - { - var globalChanges = cshtmlFile.Methods.TryGetValue("Global", out var globalMethod); - if (globalMethod != null) - { - var filteredCodeFiles = globalMethod.CodeChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, options)); - var editedDocument = await ProjectModifierHelper.ModifyDocumentText(fileDoc, filteredCodeFiles); - //replace the document - await ProjectModifierHelper.UpdateDocument(fileDoc, editedDocument, _consoleLogger); - } - } - } + documentEditor.ReplaceNode(documentEditor.OriginalRoot, modifiedRoot); } + + await documentBuilder.WriteToClassFileAsync(fileDoc.FilePath); } - /// - /// Modify Program.cs file to add changes specified in the CodeFile. - /// - /// - /// - /// - internal async Task ModifyProgramCs(CodeFile programCsFile, CodeAnalysis.Project project, CodeChangeOptions toolOptions) + private static CompilationUnitSyntax? ModifyProgramCsRoot(DocumentBuilder documentBuilder, CodeChangeOptions options, CodeFile file) { - string? programCsFilePath = Directory.EnumerateFiles(_toolOptions.ProjectPath, "Program.cs", SearchOption.AllDirectories).FirstOrDefault(); - if (!string.IsNullOrEmpty(programCsFilePath)) + var newRoot = documentBuilder.AddUsings(options); + var variableDict = ProjectModifierHelper.GetBuilderVariableIdentifier(newRoot.Members); + var globalChanges = file.Methods.TryGetValue("Global", out var globalMethod); + if (globalMethod != null) { - var programDocument = project.Documents.Where(d => d.Name.Equals(programCsFilePath)).FirstOrDefault(); - DocumentEditor documentEditor = await DocumentEditor.CreateAsync(programDocument); - DocumentBuilder documentBuilder = new DocumentBuilder(documentEditor, programCsFile, _consoleLogger); - if (documentEditor.OriginalRoot is CompilationUnitSyntax docRoot && programDocument != null) + var filteredCodeChanges = globalMethod.CodeChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, options)); + foreach (var change in filteredCodeChanges) { - //get builder variable - var variableDict = ProjectModifierHelper.GetBuilderVariableIdentifier(docRoot.Members); - //add usings - var newRoot = documentBuilder.AddUsings(toolOptions); - //add code snippets/changes. - if (programCsFile.Methods != null && programCsFile.Methods.Any()) - { - var globalChanges = programCsFile.Methods.TryGetValue("Global", out var globalMethod); - if (globalMethod != null) - { - var filteredCodeFiles = globalMethod.CodeChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, toolOptions)); - foreach (var change in filteredCodeFiles) - { - //Modify CodeSnippet to have correct variable identifiers present. - var formattedChange = ProjectModifierHelper.FormatCodeSnippet(change, variableDict); - newRoot = DocumentBuilder.AddGlobalStatements(formattedChange, newRoot); - } - } - } - //replace root node with all the updates. - documentEditor.ReplaceNode(docRoot, newRoot); - //write to Program.cs file - await documentBuilder.WriteToClassFileAsync(programCsFilePath); + //Modify CodeSnippet to have correct variable identifiers present. + var formattedChange = ProjectModifierHelper.FormatCodeSnippet(change, variableDict); + newRoot = DocumentBuilder.AddGlobalStatements(formattedChange, newRoot); } } + + return newRoot; } - internal async Task ModifyCsFile(string fileName, CodeFile file, CodeAnalysis.Project project, CodeChangeOptions options) + private static CompilationUnitSyntax? ModifyRoot(DocumentBuilder documentBuilder, CodeChangeOptions options, CodeFile file) { - string className = ProjectModifierHelper.GetClassName(fileName); - string? filePath = Directory.EnumerateFiles(_toolOptions.ProjectPath, fileName, SearchOption.AllDirectories).FirstOrDefault(); - //get the file document to get the document root for editing. + var newRoot = documentBuilder.AddUsings(options); + var namespaceNode = newRoot?.Members.OfType()?.FirstOrDefault(); + FileScopedNamespaceDeclarationSyntax? fileScopedNamespace = null; + if (namespaceNode is null) + { + fileScopedNamespace = newRoot?.Members.OfType()?.FirstOrDefault(); + } - if (!string.IsNullOrEmpty(filePath)) + string className = ProjectModifierHelper.GetClassName(file.FileName); + //get classNode. All class changes are done on the ClassDeclarationSyntax and then that node is replaced using documentEditor. + var classNode = + namespaceNode?.DescendantNodes()?.Where(node => + node is ClassDeclarationSyntax cds && + cds.Identifier.ValueText.Contains(className)).FirstOrDefault() ?? + fileScopedNamespace?.DescendantNodes()?.Where(node => + node is ClassDeclarationSyntax cds && + cds.Identifier.ValueText.Contains(className)).FirstOrDefault(); + + if (classNode is ClassDeclarationSyntax classDeclarationSyntax) { - var fileDoc = project.Documents.Where(d => d.Name.Equals(filePath)).FirstOrDefault(); - DocumentEditor documentEditor = await DocumentEditor.CreateAsync(fileDoc); - DocumentBuilder documentBuilder = new DocumentBuilder(documentEditor, file, _consoleLogger); - var newRoot = documentBuilder.AddUsings(options); - //adding usings - var namespaceNode = newRoot?.Members.OfType()?.FirstOrDefault(); - FileScopedNamespaceDeclarationSyntax? fileScopedNamespace = null; - if (namespaceNode == null) - { - fileScopedNamespace = newRoot?.Members.OfType()?.FirstOrDefault(); - } + var modifiedClassDeclarationSyntax = classDeclarationSyntax; - //get classNode. All class changes are done on the ClassDeclarationSyntax and then that node is replaced using documentEditor. - var classNode = - namespaceNode?.DescendantNodes()?.Where(node => - node is ClassDeclarationSyntax cds && - cds.Identifier.ValueText.Contains(className)).FirstOrDefault() ?? - fileScopedNamespace?.DescendantNodes()?.Where(node => - node is ClassDeclarationSyntax cds && - cds.Identifier.ValueText.Contains(className)).FirstOrDefault(); + //add class properties + modifiedClassDeclarationSyntax = documentBuilder.AddProperties(modifiedClassDeclarationSyntax, options); + //add class attributes + modifiedClassDeclarationSyntax = documentBuilder.AddClassAttributes(modifiedClassDeclarationSyntax, options); - if (classNode is ClassDeclarationSyntax classDeclarationSyntax) + //add code snippets/changes. + if (file.Methods != null && file.Methods.Any()) { - var modifiedClassDeclarationSyntax = classDeclarationSyntax; - - //add class properties - modifiedClassDeclarationSyntax = documentBuilder.AddProperties(modifiedClassDeclarationSyntax, options); - //add class attributes - modifiedClassDeclarationSyntax = documentBuilder.AddClassAttributes(modifiedClassDeclarationSyntax, options); - - //add code snippets/changes. - if (file.Methods != null && file.Methods.Any()) - { - modifiedClassDeclarationSyntax = documentBuilder.AddCodeSnippets(modifiedClassDeclarationSyntax, options); - modifiedClassDeclarationSyntax = documentBuilder.EditMethodTypes(modifiedClassDeclarationSyntax, options); - modifiedClassDeclarationSyntax = documentBuilder.AddMethodParameters(modifiedClassDeclarationSyntax, options); - } - //replace class node with all the updates. + modifiedClassDeclarationSyntax = documentBuilder.AddCodeSnippets(modifiedClassDeclarationSyntax, options); + modifiedClassDeclarationSyntax = documentBuilder.EditMethodTypes(modifiedClassDeclarationSyntax, options); + modifiedClassDeclarationSyntax = documentBuilder.AddMethodParameters(modifiedClassDeclarationSyntax, options); + } + //replace class node with all the updates. #pragma warning disable CS8631 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match constraint type. - newRoot = newRoot.ReplaceNode(classDeclarationSyntax, modifiedClassDeclarationSyntax); + newRoot = newRoot.ReplaceNode(classDeclarationSyntax, modifiedClassDeclarationSyntax); #pragma warning restore CS8631 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match constraint type. - } + } - if (documentEditor.OriginalRoot is CompilationUnitSyntax docRoot && newRoot != null) - { - documentEditor.ReplaceNode(docRoot, newRoot); - } + return newRoot; + } + + internal async Task ModifyCshtmlFile(CodeFile file, CodeAnalysis.Project project, CodeChangeOptions options) + { + var fileDoc = project.Documents.Where(d => d.Name.Equals(file.FileName)).FirstOrDefault(); + if (fileDoc is null || file.Methods is null || !file.Methods.Any()) + { + return; + } + + //add code snippets/changes. + var globalChanges = file.Methods.TryGetValue("Global", out var globalMethod); + if (globalMethod != null) + { + var filteredCodeChanges = globalMethod.CodeChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, options)); + var editedDocument = await ProjectModifierHelper.ModifyDocumentText(fileDoc, filteredCodeChanges); + //replace the document + await ProjectModifierHelper.UpdateDocument(fileDoc, editedDocument, _consoleLogger); + } + } + + internal async Task ModifyRazorFile(CodeFile file, CodeAnalysis.Project project, CodeChangeOptions toolOptions) + { + if (!string.IsNullOrEmpty(file.AddFilePath)) + { + AddFile(file); + return; + } - await documentBuilder.WriteToClassFileAsync(filePath); + var document = project.Documents.Where(d => d.Name.EndsWith(file.FileName)).FirstOrDefault(); + if (document is null) + { + return; } + + var razorChanges = file?.RazorChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, toolOptions)); + var editedDocument = await ProjectModifierHelper.ModifyDocumentText(document, razorChanges); + await ProjectModifierHelper.UpdateDocument(document, editedDocument, _consoleLogger); } private CodeModifierConfig? GetCodeModifierConfig() diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/Properties/Resources.Designer.cs b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/Properties/Resources.Designer.cs index e3aa7e61b1..f4455befe8 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/Properties/Resources.Designer.cs +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/Properties/Resources.Designer.cs @@ -60,6 +60,16 @@ internal Resources() { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] add_CallWebApi_razor { + get { + object obj = ResourceManager.GetObject("add_CallWebApi_razor", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/Properties/Resources.resx b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/Properties/Resources.resx index d54cca5b78..1d42e80fef 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/Properties/Resources.resx +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/Properties/Resources.resx @@ -124,6 +124,9 @@ Adding package {0} . . . + + ..\CodeReaderWriter\CodeFiles\Blazor\Server\CallWebApi.razor;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\CodeReaderWriter\CodeFiles\Blazor\Server\ShowProfile.razor;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/CodeModifier/CodeChange/CodeChangeHelper.cs b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/CodeModifier/CodeChange/CodeChangeHelper.cs index 1b2f961b6b..3810a8c0fd 100644 --- a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/CodeModifier/CodeChange/CodeChangeHelper.cs +++ b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/CodeModifier/CodeChange/CodeChangeHelper.cs @@ -15,6 +15,7 @@ public class CodeChangeOptionStrings public const string DownstreamApi = nameof(DownstreamApi); public const string Skip = nameof(Skip); public const string NonMinimalApp = nameof(NonMinimalApp); + public const string MinimalApp = nameof(MinimalApp); } public class CodeChangeOptions diff --git a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs index 8d2c92b1e9..0876562c47 100644 --- a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs +++ b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs @@ -38,6 +38,7 @@ internal static async Task IsMinimalApp(IModelTypesLocator modelTypesLocat return startupType == null; } + // Returns true when there is no Startup.cs or equivalent internal static async Task IsMinimalApp(CodeAnalysis.Project project) { if (project != null) @@ -60,23 +61,14 @@ internal static async Task IsMinimalApp(CodeAnalysis.Project project) return false; } - //Get Startup class name from CreateHostBuilder in Program.cs. If Program.cs is not being used, method - //will bail out. - internal static async Task GetStartupClass(string projectPath, CodeAnalysis.Project project) + // Get Startup class name from CreateHostBuilder in Program.cs. If Program.cs is not being used, method + // will return null. + internal static async Task GetStartupClass(CodeAnalysis.Project project) { - var programFilePath = Directory.EnumerateFiles(projectPath, "Program.cs").FirstOrDefault(); - if (!string.IsNullOrEmpty(programFilePath)) - { - var programDoc = project.Documents.Where(d => d.Name.Equals(programFilePath)).FirstOrDefault(); - var startupClassName = await GetStartupClassName(programDoc); - string className = startupClassName; - var startupFilePath = string.Empty; - if (!string.IsNullOrEmpty(startupClassName)) - { - return string.Concat(startupClassName, ".cs"); - } - } - return string.Empty; + var programCsDocument = project.Documents.Where(d => d.Name.Equals("Program.cs")).FirstOrDefault(); + var startupClassName = await GetStartupClassName(programCsDocument); + + return string.IsNullOrEmpty(startupClassName) ? null : string.Concat(startupClassName, ".cs"); } internal static async Task GetStartupClassName(Document programDoc) @@ -110,6 +102,7 @@ node is MemberAccessExpressionSyntax maes && } } } + return string.Empty; } @@ -343,6 +336,11 @@ internal static bool FilterOptions(string[] options, CodeChangeOptions codeChang { return false; } + // for example, program.cs is only modified when codeChangeOptions.IsMinimalApp is true + if (options.Contains(CodeChangeOptionStrings.MinimalApp) && !codeChangeOptions.IsMinimalApp) + { + return false; + } //if its a minimal app and options have a "NonMinimalApp", don't add the CodeBlock if (options.Contains(CodeChangeOptionStrings.NonMinimalApp) && codeChangeOptions.IsMinimalApp) { @@ -375,6 +373,7 @@ internal static bool FilterOptions(string[] options, CodeChangeOptions codeChang return true; } } + return false; } @@ -420,14 +419,14 @@ internal static async Task ModifyDocumentText(Document fileDoc, IEnume return null; // TODO generate README } - var sourceTextToAdd = SourceText.From(sourceFileString); - return fileDoc.WithText(sourceTextToAdd); + var updatedSourceText = SourceText.From(sourceFileString); + return fileDoc.WithText(updatedSourceText); } internal static async Task UpdateDocument(Document fileDoc, Document editedDocument, IConsoleLogger consoleLogger) { var classFileTxt = await editedDocument.GetTextAsync(); - File.WriteAllText(fileDoc.Name, classFileTxt.ToString()); + File.WriteAllText(fileDoc.FilePath, classFileTxt.ToString()); consoleLogger.LogMessage($"Modified {fileDoc.Name}.\n"); } From 88ff3f9e749b8bba7a8a8e2e8803e6d28c0a769f Mon Sep 17 00:00:00 2001 From: Zach Halzel Date: Wed, 5 Jan 2022 11:27:32 -0800 Subject: [PATCH 2/8] Revert file --- .../CodeReaderWriter/ProjectModifier.cs | 251 ++++++++++-------- 1 file changed, 139 insertions(+), 112 deletions(-) diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs index 13b33c9f53..c95bc1c12f 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs @@ -79,17 +79,40 @@ public async Task AddAuthCodeAsync() private async Task HandleCodeFileAsync(CodeFile file, CodeAnalysis.Project project, CodeChangeOptions options) { - if (file.FileName.EndsWith(".cs")) + if (string.IsNullOrEmpty(file.FileName)) { - await ModifyCsFile(file, project, options); + return; } - else if (file.FileName.EndsWith(".cshtml")) + + if (!string.IsNullOrEmpty(file.AddFilePath)) { - await ModifyCshtmlFile(file, project, options); + AddFile(file); + return; + } + + var fileName = file.FileName.Equals("Startup.cs", StringComparison.OrdinalIgnoreCase) + ? await ProjectModifierHelper.GetStartupClass(_toolOptions.ProjectPath, project) + : file.FileName; + + if (fileName.Equals("Program.cs")) + { + // only modify Program.cs file if it's a minimal hosting app (as we made changes to the Startup.cs file). + if (options.IsMinimalApp) + { + await ModifyProgramCs(file, project, options); + } } - else if (file.FileName.EndsWith(".razor")) + else if (fileName.EndsWith(".cs")) { - await ModifyRazorFile(file, project, options); + await ModifyCsFile(fileName, file, project, options); + } + else if (fileName.EndsWith(".cshtml")) + { + await ModifyCshtmlFile(fileName, file, project, options); + } + else if (fileName.EndsWith(".razor")) + { + await ModifyRazorFile(fileName, file, project, options); } } @@ -132,143 +155,147 @@ private void AddFile(CodeFile file) Directory.CreateDirectory(fileDir); File.WriteAllText(filePath, codeFileString); } - return; } - internal async Task ModifyCsFile(CodeFile file, CodeAnalysis.Project project, CodeChangeOptions options) + internal async Task ModifyRazorFile(string fileName, CodeFile file, CodeAnalysis.Project project, CodeChangeOptions toolOptions) { - if (file.FileName.Equals("Startup.cs")) - { - // Startup class file name may be different - file.FileName = await ProjectModifierHelper.GetStartupClass(project) ?? file.FileName; - } - - var fileDoc = project.Documents.Where(d => d.Name.Equals(file.FileName)).FirstOrDefault(); - if (fileDoc is null) + var document = project.Documents.Where(d => d.Name.EndsWith(fileName)).FirstOrDefault(); + if (document is null) { return; } - //get the file document to get the document root for editing. - DocumentEditor documentEditor = await DocumentEditor.CreateAsync(fileDoc); - if (documentEditor is null) - { - return; - } + var razorChanges = file?.RazorChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, toolOptions)); + var editedDocument = await ProjectModifierHelper.ModifyDocumentText(document, razorChanges); + await ProjectModifierHelper.UpdateDocument(document, editedDocument, _consoleLogger); + } - DocumentBuilder documentBuilder = new DocumentBuilder(documentEditor, file, _consoleLogger); - var modifiedRoot = file.FileName.Equals("Program.cs") - ? ModifyProgramCsRoot(documentBuilder, options, file) - : ModifyRoot(documentBuilder, options, file); + internal async Task ModifyCshtmlFile(string fileName, CodeFile cshtmlFile, CodeAnalysis.Project project, CodeChangeOptions options) + { + string? filePath = Directory.EnumerateFiles(_toolOptions.ProjectPath, fileName, SearchOption.AllDirectories).FirstOrDefault(); - if (documentEditor.OriginalRoot != null && modifiedRoot != null) + if (!string.IsNullOrEmpty(filePath)) { - documentEditor.ReplaceNode(documentEditor.OriginalRoot, modifiedRoot); + var fileDoc = project.Documents.Where(d => d.Name.Equals(filePath)).FirstOrDefault(); + if (fileDoc != null) + { + //add code snippets/changes. + if (cshtmlFile.Methods != null && cshtmlFile.Methods.Any()) + { + var globalChanges = cshtmlFile.Methods.TryGetValue("Global", out var globalMethod); + if (globalMethod != null) + { + var filteredCodeFiles = globalMethod.CodeChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, options)); + var editedDocument = await ProjectModifierHelper.ModifyDocumentText(fileDoc, filteredCodeFiles); + //replace the document + await ProjectModifierHelper.UpdateDocument(fileDoc, editedDocument, _consoleLogger); + } + } + } } - - await documentBuilder.WriteToClassFileAsync(fileDoc.FilePath); } - private static CompilationUnitSyntax? ModifyProgramCsRoot(DocumentBuilder documentBuilder, CodeChangeOptions options, CodeFile file) + /// + /// Modify Program.cs file to add changes specified in the CodeFile. + /// + /// + /// + /// + internal async Task ModifyProgramCs(CodeFile programCsFile, CodeAnalysis.Project project, CodeChangeOptions toolOptions) { - var newRoot = documentBuilder.AddUsings(options); - var variableDict = ProjectModifierHelper.GetBuilderVariableIdentifier(newRoot.Members); - var globalChanges = file.Methods.TryGetValue("Global", out var globalMethod); - if (globalMethod != null) + string? programCsFilePath = Directory.EnumerateFiles(_toolOptions.ProjectPath, "Program.cs", SearchOption.AllDirectories).FirstOrDefault(); + if (!string.IsNullOrEmpty(programCsFilePath)) { - var filteredCodeChanges = globalMethod.CodeChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, options)); - foreach (var change in filteredCodeChanges) + var programDocument = project.Documents.Where(d => d.Name.Equals(programCsFilePath)).FirstOrDefault(); + DocumentEditor documentEditor = await DocumentEditor.CreateAsync(programDocument); + DocumentBuilder documentBuilder = new DocumentBuilder(documentEditor, programCsFile, _consoleLogger); + if (documentEditor.OriginalRoot is CompilationUnitSyntax docRoot && programDocument != null) { - //Modify CodeSnippet to have correct variable identifiers present. - var formattedChange = ProjectModifierHelper.FormatCodeSnippet(change, variableDict); - newRoot = DocumentBuilder.AddGlobalStatements(formattedChange, newRoot); + //get builder variable + var variableDict = ProjectModifierHelper.GetBuilderVariableIdentifier(docRoot.Members); + //add usings + var newRoot = documentBuilder.AddUsings(toolOptions); + //add code snippets/changes. + if (programCsFile.Methods != null && programCsFile.Methods.Any()) + { + var globalChanges = programCsFile.Methods.TryGetValue("Global", out var globalMethod); + if (globalMethod != null) + { + var filteredCodeFiles = globalMethod.CodeChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, toolOptions)); + foreach (var change in filteredCodeFiles) + { + //Modify CodeSnippet to have correct variable identifiers present. + var formattedChange = ProjectModifierHelper.FormatCodeSnippet(change, variableDict); + newRoot = DocumentBuilder.AddGlobalStatements(formattedChange, newRoot); + } + } + } + //replace root node with all the updates. + documentEditor.ReplaceNode(docRoot, newRoot); + //write to Program.cs file + await documentBuilder.WriteToClassFileAsync(programCsFilePath); } } - - return newRoot; } - private static CompilationUnitSyntax? ModifyRoot(DocumentBuilder documentBuilder, CodeChangeOptions options, CodeFile file) + internal async Task ModifyCsFile(string fileName, CodeFile file, CodeAnalysis.Project project, CodeChangeOptions options) { - var newRoot = documentBuilder.AddUsings(options); - var namespaceNode = newRoot?.Members.OfType()?.FirstOrDefault(); - FileScopedNamespaceDeclarationSyntax? fileScopedNamespace = null; - if (namespaceNode is null) - { - fileScopedNamespace = newRoot?.Members.OfType()?.FirstOrDefault(); - } + string className = ProjectModifierHelper.GetClassName(fileName); + string? filePath = Directory.EnumerateFiles(_toolOptions.ProjectPath, fileName, SearchOption.AllDirectories).FirstOrDefault(); + //get the file document to get the document root for editing. - string className = ProjectModifierHelper.GetClassName(file.FileName); - //get classNode. All class changes are done on the ClassDeclarationSyntax and then that node is replaced using documentEditor. - var classNode = - namespaceNode?.DescendantNodes()?.Where(node => - node is ClassDeclarationSyntax cds && - cds.Identifier.ValueText.Contains(className)).FirstOrDefault() ?? - fileScopedNamespace?.DescendantNodes()?.Where(node => - node is ClassDeclarationSyntax cds && - cds.Identifier.ValueText.Contains(className)).FirstOrDefault(); - - if (classNode is ClassDeclarationSyntax classDeclarationSyntax) + if (!string.IsNullOrEmpty(filePath)) { - var modifiedClassDeclarationSyntax = classDeclarationSyntax; - - //add class properties - modifiedClassDeclarationSyntax = documentBuilder.AddProperties(modifiedClassDeclarationSyntax, options); - //add class attributes - modifiedClassDeclarationSyntax = documentBuilder.AddClassAttributes(modifiedClassDeclarationSyntax, options); - - //add code snippets/changes. - if (file.Methods != null && file.Methods.Any()) + var fileDoc = project.Documents.Where(d => d.Name.Equals(filePath)).FirstOrDefault(); + DocumentEditor documentEditor = await DocumentEditor.CreateAsync(fileDoc); + DocumentBuilder documentBuilder = new DocumentBuilder(documentEditor, file, _consoleLogger); + var newRoot = documentBuilder.AddUsings(options); + //adding usings + var namespaceNode = newRoot?.Members.OfType()?.FirstOrDefault(); + FileScopedNamespaceDeclarationSyntax? fileScopedNamespace = null; + if (namespaceNode == null) { - modifiedClassDeclarationSyntax = documentBuilder.AddCodeSnippets(modifiedClassDeclarationSyntax, options); - modifiedClassDeclarationSyntax = documentBuilder.EditMethodTypes(modifiedClassDeclarationSyntax, options); - modifiedClassDeclarationSyntax = documentBuilder.AddMethodParameters(modifiedClassDeclarationSyntax, options); + fileScopedNamespace = newRoot?.Members.OfType()?.FirstOrDefault(); } - //replace class node with all the updates. -#pragma warning disable CS8631 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match constraint type. - newRoot = newRoot.ReplaceNode(classDeclarationSyntax, modifiedClassDeclarationSyntax); -#pragma warning restore CS8631 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match constraint type. - } - return newRoot; - } + //get classNode. All class changes are done on the ClassDeclarationSyntax and then that node is replaced using documentEditor. + var classNode = + namespaceNode?.DescendantNodes()?.Where(node => + node is ClassDeclarationSyntax cds && + cds.Identifier.ValueText.Contains(className)).FirstOrDefault() ?? + fileScopedNamespace?.DescendantNodes()?.Where(node => + node is ClassDeclarationSyntax cds && + cds.Identifier.ValueText.Contains(className)).FirstOrDefault(); - internal async Task ModifyCshtmlFile(CodeFile file, CodeAnalysis.Project project, CodeChangeOptions options) - { - var fileDoc = project.Documents.Where(d => d.Name.Equals(file.FileName)).FirstOrDefault(); - if (fileDoc is null || file.Methods is null || !file.Methods.Any()) - { - return; - } + if (classNode is ClassDeclarationSyntax classDeclarationSyntax) + { + var modifiedClassDeclarationSyntax = classDeclarationSyntax; - //add code snippets/changes. - var globalChanges = file.Methods.TryGetValue("Global", out var globalMethod); - if (globalMethod != null) - { - var filteredCodeChanges = globalMethod.CodeChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, options)); - var editedDocument = await ProjectModifierHelper.ModifyDocumentText(fileDoc, filteredCodeChanges); - //replace the document - await ProjectModifierHelper.UpdateDocument(fileDoc, editedDocument, _consoleLogger); - } - } + //add class properties + modifiedClassDeclarationSyntax = documentBuilder.AddProperties(modifiedClassDeclarationSyntax, options); + //add class attributes + modifiedClassDeclarationSyntax = documentBuilder.AddClassAttributes(modifiedClassDeclarationSyntax, options); - internal async Task ModifyRazorFile(CodeFile file, CodeAnalysis.Project project, CodeChangeOptions toolOptions) - { - if (!string.IsNullOrEmpty(file.AddFilePath)) - { - AddFile(file); - return; - } + //add code snippets/changes. + if (file.Methods != null && file.Methods.Any()) + { + modifiedClassDeclarationSyntax = documentBuilder.AddCodeSnippets(modifiedClassDeclarationSyntax, options); + modifiedClassDeclarationSyntax = documentBuilder.EditMethodTypes(modifiedClassDeclarationSyntax, options); + modifiedClassDeclarationSyntax = documentBuilder.AddMethodParameters(modifiedClassDeclarationSyntax, options); + } + //replace class node with all the updates. +#pragma warning disable CS8631 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match constraint type. + newRoot = newRoot.ReplaceNode(classDeclarationSyntax, modifiedClassDeclarationSyntax); +#pragma warning restore CS8631 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match constraint type. + } - var document = project.Documents.Where(d => d.Name.EndsWith(file.FileName)).FirstOrDefault(); - if (document is null) - { - return; - } + if (documentEditor.OriginalRoot is CompilationUnitSyntax docRoot && newRoot != null) + { + documentEditor.ReplaceNode(docRoot, newRoot); + } - var razorChanges = file?.RazorChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, toolOptions)); - var editedDocument = await ProjectModifierHelper.ModifyDocumentText(document, razorChanges); - await ProjectModifierHelper.UpdateDocument(document, editedDocument, _consoleLogger); + await documentBuilder.WriteToClassFileAsync(filePath); + } } private CodeModifierConfig? GetCodeModifierConfig() From 1f79b63b899d21a680bcc9abbe679374843493d7 Mon Sep 17 00:00:00 2001 From: Zach Halzel Date: Wed, 5 Jan 2022 12:27:15 -0800 Subject: [PATCH 3/8] Fix ProjectModifier --- .../CodeReaderWriter/ProjectModifier.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs index c95bc1c12f..487c38722c 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs @@ -91,7 +91,7 @@ private async Task HandleCodeFileAsync(CodeFile file, CodeAnalysis.Project proje } var fileName = file.FileName.Equals("Startup.cs", StringComparison.OrdinalIgnoreCase) - ? await ProjectModifierHelper.GetStartupClass(_toolOptions.ProjectPath, project) + ? await ProjectModifierHelper.GetStartupClass(project) : file.FileName; if (fileName.Equals("Program.cs")) From 63b7401897c216751b8b3d15d46d358a9d1e0258 Mon Sep 17 00:00:00 2001 From: Zach Halzel Date: Wed, 5 Jan 2022 12:42:48 -0800 Subject: [PATCH 4/8] Revert --- .../CodeReaderWriter/ProjectModifier.cs | 2 +- .../Project/ProjectModifierHelper.cs | 23 +++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs index 487c38722c..c95bc1c12f 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs @@ -91,7 +91,7 @@ private async Task HandleCodeFileAsync(CodeFile file, CodeAnalysis.Project proje } var fileName = file.FileName.Equals("Startup.cs", StringComparison.OrdinalIgnoreCase) - ? await ProjectModifierHelper.GetStartupClass(project) + ? await ProjectModifierHelper.GetStartupClass(_toolOptions.ProjectPath, project) : file.FileName; if (fileName.Equals("Program.cs")) diff --git a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs index 0876562c47..cec0d65311 100644 --- a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs +++ b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs @@ -61,14 +61,23 @@ internal static async Task IsMinimalApp(CodeAnalysis.Project project) return false; } - // Get Startup class name from CreateHostBuilder in Program.cs. If Program.cs is not being used, method - // will return null. - internal static async Task GetStartupClass(CodeAnalysis.Project project) + //Get Startup class name from CreateHostBuilder in Program.cs. If Program.cs is not being used, method + //will bail out. + internal static async Task GetStartupClass(string projectPath, CodeAnalysis.Project project) { - var programCsDocument = project.Documents.Where(d => d.Name.Equals("Program.cs")).FirstOrDefault(); - var startupClassName = await GetStartupClassName(programCsDocument); - - return string.IsNullOrEmpty(startupClassName) ? null : string.Concat(startupClassName, ".cs"); + var programFilePath = Directory.EnumerateFiles(projectPath, "Program.cs").FirstOrDefault(); + if (!string.IsNullOrEmpty(programFilePath)) + { + var programDoc = project.Documents.Where(d => d.Name.Equals(programFilePath)).FirstOrDefault(); + var startupClassName = await GetStartupClassName(programDoc); + string className = startupClassName; + var startupFilePath = string.Empty; + if (!string.IsNullOrEmpty(startupClassName)) + { + return string.Concat(startupClassName, ".cs"); + } + } + return string.Empty; } internal static async Task GetStartupClassName(Document programDoc) From cc934c46110a7ecde90f3f4634f6b0f60bbff9c4 Mon Sep 17 00:00:00 2001 From: Zach Halzel Date: Wed, 5 Jan 2022 14:09:56 -0800 Subject: [PATCH 5/8] Use document.Name instead of filepath --- .../CodeReaderWriter/ProjectModifier.cs | 4 ++-- .../Project/ProjectModifierHelper.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs index c95bc1c12f..be34f0d004 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs @@ -167,7 +167,7 @@ internal async Task ModifyRazorFile(string fileName, CodeFile file, CodeAnalysis var razorChanges = file?.RazorChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, toolOptions)); var editedDocument = await ProjectModifierHelper.ModifyDocumentText(document, razorChanges); - await ProjectModifierHelper.UpdateDocument(document, editedDocument, _consoleLogger); + await ProjectModifierHelper.UpdateDocument(editedDocument, fileName, _consoleLogger); } internal async Task ModifyCshtmlFile(string fileName, CodeFile cshtmlFile, CodeAnalysis.Project project, CodeChangeOptions options) @@ -188,7 +188,7 @@ internal async Task ModifyCshtmlFile(string fileName, CodeFile cshtmlFile, CodeA var filteredCodeFiles = globalMethod.CodeChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, options)); var editedDocument = await ProjectModifierHelper.ModifyDocumentText(fileDoc, filteredCodeFiles); //replace the document - await ProjectModifierHelper.UpdateDocument(fileDoc, editedDocument, _consoleLogger); + await ProjectModifierHelper.UpdateDocument(editedDocument, fileName, _consoleLogger); } } } diff --git a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs index cec0d65311..c4a18b5ba5 100644 --- a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs +++ b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs @@ -432,11 +432,11 @@ internal static async Task ModifyDocumentText(Document fileDoc, IEnume return fileDoc.WithText(updatedSourceText); } - internal static async Task UpdateDocument(Document fileDoc, Document editedDocument, IConsoleLogger consoleLogger) + internal static async Task UpdateDocument(Document editedDocument, string fileName, IConsoleLogger consoleLogger) { var classFileTxt = await editedDocument.GetTextAsync(); - File.WriteAllText(fileDoc.FilePath, classFileTxt.ToString()); - consoleLogger.LogMessage($"Modified {fileDoc.Name}.\n"); + File.WriteAllText(editedDocument.Name, classFileTxt.ToString()); + consoleLogger.LogMessage($"Modified {fileName}.\n"); } // Filter out CodeBlocks that are invalid using FilterOptions From 56fe7f452c140d951b46047c9fbe0eef36cfb533 Mon Sep 17 00:00:00 2001 From: Zach Halzel Date: Wed, 5 Jan 2022 14:12:43 -0800 Subject: [PATCH 6/8] Modify signature --- .../CodeReaderWriter/ProjectModifier.cs | 4 ++-- .../Project/ProjectModifierHelper.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs index be34f0d004..f041f7de7f 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs @@ -167,7 +167,7 @@ internal async Task ModifyRazorFile(string fileName, CodeFile file, CodeAnalysis var razorChanges = file?.RazorChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, toolOptions)); var editedDocument = await ProjectModifierHelper.ModifyDocumentText(document, razorChanges); - await ProjectModifierHelper.UpdateDocument(editedDocument, fileName, _consoleLogger); + await ProjectModifierHelper.UpdateDocument(fileName, editedDocument, _consoleLogger); } internal async Task ModifyCshtmlFile(string fileName, CodeFile cshtmlFile, CodeAnalysis.Project project, CodeChangeOptions options) @@ -188,7 +188,7 @@ internal async Task ModifyCshtmlFile(string fileName, CodeFile cshtmlFile, CodeA var filteredCodeFiles = globalMethod.CodeChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, options)); var editedDocument = await ProjectModifierHelper.ModifyDocumentText(fileDoc, filteredCodeFiles); //replace the document - await ProjectModifierHelper.UpdateDocument(editedDocument, fileName, _consoleLogger); + await ProjectModifierHelper.UpdateDocument(fileName, editedDocument, _consoleLogger); } } } diff --git a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs index c4a18b5ba5..c62da60738 100644 --- a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs +++ b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs @@ -432,7 +432,7 @@ internal static async Task ModifyDocumentText(Document fileDoc, IEnume return fileDoc.WithText(updatedSourceText); } - internal static async Task UpdateDocument(Document editedDocument, string fileName, IConsoleLogger consoleLogger) + internal static async Task UpdateDocument(string fileName, Document editedDocument, IConsoleLogger consoleLogger) { var classFileTxt = await editedDocument.GetTextAsync(); File.WriteAllText(editedDocument.Name, classFileTxt.ToString()); From 79329d82cf43ae6766a8ac8859db450698f84e5d Mon Sep 17 00:00:00 2001 From: Zach Halzel Date: Wed, 5 Jan 2022 14:15:05 -0800 Subject: [PATCH 7/8] Remove parameter --- .../CodeReaderWriter/ProjectModifier.cs | 4 ++-- .../Project/ProjectModifierHelper.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs index f041f7de7f..0416e15e6a 100644 --- a/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs +++ b/src/MSIdentityScaffolding/Microsoft.DotNet.MSIdentity/CodeReaderWriter/ProjectModifier.cs @@ -167,7 +167,7 @@ internal async Task ModifyRazorFile(string fileName, CodeFile file, CodeAnalysis var razorChanges = file?.RazorChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, toolOptions)); var editedDocument = await ProjectModifierHelper.ModifyDocumentText(document, razorChanges); - await ProjectModifierHelper.UpdateDocument(fileName, editedDocument, _consoleLogger); + await ProjectModifierHelper.UpdateDocument(editedDocument, _consoleLogger); } internal async Task ModifyCshtmlFile(string fileName, CodeFile cshtmlFile, CodeAnalysis.Project project, CodeChangeOptions options) @@ -188,7 +188,7 @@ internal async Task ModifyCshtmlFile(string fileName, CodeFile cshtmlFile, CodeA var filteredCodeFiles = globalMethod.CodeChanges.Where(cc => ProjectModifierHelper.FilterOptions(cc.Options, options)); var editedDocument = await ProjectModifierHelper.ModifyDocumentText(fileDoc, filteredCodeFiles); //replace the document - await ProjectModifierHelper.UpdateDocument(fileName, editedDocument, _consoleLogger); + await ProjectModifierHelper.UpdateDocument(editedDocument, _consoleLogger); } } } diff --git a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs index c62da60738..df6734ab6f 100644 --- a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs +++ b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs @@ -432,11 +432,11 @@ internal static async Task ModifyDocumentText(Document fileDoc, IEnume return fileDoc.WithText(updatedSourceText); } - internal static async Task UpdateDocument(string fileName, Document editedDocument, IConsoleLogger consoleLogger) + internal static async Task UpdateDocument(Document editedDocument, IConsoleLogger consoleLogger) { var classFileTxt = await editedDocument.GetTextAsync(); File.WriteAllText(editedDocument.Name, classFileTxt.ToString()); - consoleLogger.LogMessage($"Modified {fileName}.\n"); + consoleLogger.LogMessage($"Modified {editedDocument.Name}.\n"); } // Filter out CodeBlocks that are invalid using FilterOptions From 435ad5001874174021d6585e6ed8d7e749618d77 Mon Sep 17 00:00:00 2001 From: Zach Halzel Date: Wed, 5 Jan 2022 14:20:45 -0800 Subject: [PATCH 8/8] Add comment --- .../Project/ProjectModifierHelper.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs index df6734ab6f..df7629e76c 100644 --- a/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs +++ b/src/Shared/Microsoft.DotNet.Scaffolding.Shared/Project/ProjectModifierHelper.cs @@ -432,11 +432,13 @@ internal static async Task ModifyDocumentText(Document fileDoc, IEnume return fileDoc.WithText(updatedSourceText); } - internal static async Task UpdateDocument(Document editedDocument, IConsoleLogger consoleLogger) + internal static async Task UpdateDocument(Document document, IConsoleLogger consoleLogger) { - var classFileTxt = await editedDocument.GetTextAsync(); - File.WriteAllText(editedDocument.Name, classFileTxt.ToString()); - consoleLogger.LogMessage($"Modified {editedDocument.Name}.\n"); + var classFileTxt = await document.GetTextAsync(); + + // Note: Here, document.Name is the full filepath + File.WriteAllText(document.Name, classFileTxt.ToString()); + consoleLogger.LogMessage($"Modified {document.Name}.\n"); } // Filter out CodeBlocks that are invalid using FilterOptions