Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes tests to use the correct context to enable async refactor #413

Merged
merged 9 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/Microsoft.OData.Cli/ODataCliFileHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,16 @@ public Task<string> AddFileAsync(string fileName, string targetPath, ODataFileOp
/// Emits the container property attribute. The lastest version gets installed. so we'll always emit this property.
/// </summary>
/// <returns>A bool indicating whether to emit the container property or not</returns>
public bool EmitContainerPropertyAttribute()
public Task<bool> EmitContainerPropertyAttributeAsync()
{
return true;
return Task.FromResult(true);
}

/// <summary>
/// Sets the CSDL file as an embedded resource
/// </summary>
/// <param name="fileName">The name of the file to set as embedded resource</param>
public void SetFileAsEmbeddedResource(string fileName)
public Task SetFileAsEmbeddedResourceAsync(string fileName)
{
if (this.project != null)
{
Expand All @@ -111,6 +111,8 @@ public void SetFileAsEmbeddedResource(string fileName)
ProjectHelper.AddProjectItem(this.project, Constants.EmbeddedResourceTag, fileName);
}
}

return Task.CompletedTask;
}
}
}
21 changes: 12 additions & 9 deletions src/Microsoft.OData.CodeGen/CodeGeneration/V4CodeGenDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ public V4CodeGenDescriptor(IFileHandler fileHandler, IMessageLogger logger, IPac

public override async Task AddNugetPackagesAsync()
{
await MessageLogger.WriteMessageAsync(LogMessageCategory.Information, "Adding Nuget Packages...").ConfigureAwait(false);
await MessageLogger.WriteMessageAsync(LogMessageCategory.Information, "Adding Nuget Packages...");


foreach (var nugetPackage in Common.Constants.V4NuGetPackages)
await PackageInstaller.CheckAndInstallNuGetPackageAsync(Common.Constants.NuGetOnlineRepository, nugetPackage).ConfigureAwait(false);
await PackageInstaller.CheckAndInstallNuGetPackageAsync(Common.Constants.NuGetOnlineRepository, nugetPackage);

await MessageLogger.WriteMessageAsync(LogMessageCategory.Information, "Nuget Packages were installed.").ConfigureAwait(false);
await MessageLogger.WriteMessageAsync(LogMessageCategory.Information, "Nuget Packages were installed.");
}

public override async Task AddGeneratedClientCodeAsync(string metadata, string outputDirectory, LanguageOption languageOption, ServiceConfiguration serviceConfiguration)
Expand Down Expand Up @@ -96,7 +96,7 @@ private async Task AddT4FileAsync(string metadata, string outputDirectory, Langu

await FileHandler.AddFileAsync(csdlTempFile, metadataFile, new ODataFileOptions { SuppressOverwritePrompt = true });

FileHandler.SetFileAsEmbeddedResource(csdlFileName);
await FileHandler.SetFileAsEmbeddedResourceAsync(csdlFileName);

var t4TempFile = Path.GetTempFileName();

Expand Down Expand Up @@ -193,28 +193,31 @@ private async Task AddGeneratedCodeAsync(string metadata, string outputDirectory
var metadataFile = Path.Combine(referenceFolder, csdlFileName);
await FileHandler.AddFileAsync(tempFile, metadataFile, new ODataFileOptions { SuppressOverwritePrompt = true });

FileHandler.SetFileAsEmbeddedResource(csdlFileName);
t4CodeGenerator.EmitContainerPropertyAttribute = FileHandler.EmitContainerPropertyAttribute();
await FileHandler.SetFileAsEmbeddedResourceAsync(csdlFileName);
t4CodeGenerator.EmitContainerPropertyAttribute = await FileHandler.EmitContainerPropertyAttributeAsync();

t4CodeGenerator.MetadataFilePath = metadataFile;
t4CodeGenerator.MetadataFileRelativePath = csdlFileName;

using (StreamWriter writer = File.CreateText(tempFile))
{
await writer.WriteAsync(t4CodeGenerator.TransformText());
await writer.WriteAsync(await t4CodeGenerator.TransformTextAsync());
await writer.FlushAsync();
if (t4CodeGenerator.Errors != null && t4CodeGenerator.Errors.Count > 0)
{
foreach (var err in t4CodeGenerator.Errors)
{
await MessageLogger.WriteMessageAsync(LogMessageCategory.Warning, err.ToString()).ConfigureAwait(false);
await MessageLogger.WriteMessageAsync(LogMessageCategory.Warning, err.ToString());
}
}
}

var outputFile = Path.Combine(referenceFolder, $"{this.GeneratedFileNamePrefix(serviceConfiguration.GeneratedFileNamePrefix)}{(languageOption == LanguageOption.GenerateCSharpCode ? ".cs" : ".vb")}");
await FileHandler.AddFileAsync(tempFile, outputFile, new ODataFileOptions { SuppressOverwritePrompt = true });
t4CodeGenerator.MultipleFilesManager?.GenerateFiles(serviceConfiguration.GenerateMultipleFiles, FileHandler, MessageLogger, referenceFolder, true, serviceConfiguration.OpenGeneratedFilesInIDE);
if (t4CodeGenerator.MultipleFilesManager != null)
{
await t4CodeGenerator.MultipleFilesManager?.CopyGeneratedFilesAsync(serviceConfiguration.GenerateMultipleFiles, FileHandler, MessageLogger, referenceFolder, true, serviceConfiguration.OpenGeneratedFilesInIDE);
}
await MessageLogger.WriteMessageAsync(LogMessageCategory.Information, "Client Proxy for OData V4 was generated.");
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.OData.CodeGen/FileHandling/IFileHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ public interface IFileHandler
/// Sets a file as an embedded resource
/// </summary>
/// <param name="fileName">The name of the file to set as an embedded resource</param>
void SetFileAsEmbeddedResource(string fileName);
Task SetFileAsEmbeddedResourceAsync(string fileName);

/// <summary>
/// Emits container property attribute
/// </summary>
/// <returns></returns>
bool EmitContainerPropertyAttribute();
Task<bool> EmitContainerPropertyAttributeAsync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#><#@ import namespace="System.IO"
#><#@ import namespace="System.Linq"
#><#@ import namespace="System.Text"
#><#@ import namespace="System.Threading.Tasks"
#><#@ import namespace="System.Security"
#><#@ import namespace="System.Xml.Linq"
#><#@ import namespace="Microsoft.OData.CodeGen.Logging"
Expand All @@ -34,35 +35,36 @@ public class FilesManager {
/// Creates an instance of the FilesManager. The object used to generate and manage
/// multiple source files.
/// </summary>
private class Block {

internal class Block
{
/// <summary> Name of the block.</summary>
public string Name;

/// <summary> Temporary file path of the block.</summary>
public string TemporaryFilePath;

/// <summary> The line in the template from which the block starts.</summary>
public int Start;

/// <summary> Length of the block.</summary>
public int Length;

/// <summary> Block currently being processed.</summary>
/// <summary> Block currently being processed.</summary>
public bool IsContainer;
}

/// <summary> Block currently being processed.</summary>
private Block _currentBlock;

/// <summary> A list of all the blocks of texts to be used to generate multiple files.</summary>
private List<Block> _files = new List<Block>();
internal List<Block> files = new List<Block>();

/// <summary> A block describing the footer of all files.</summary>
private Block _footer = new Block();

/// <summary> A block describing the header of all files.</summary>
private Block _header = new Block();

/// <summary> A list of file names to be generated.</summary>
protected List<String> _generatedFileNames = new List<String>();

/// <summary> Contains generated text.</summary>
public StringBuilder Template
Expand All @@ -84,6 +86,8 @@ public class FilesManager {
CurrentBlock = new Block { Name = name, IsContainer = isContainer};
}

public int FileCount => files.Count;

/// <summary>
/// Marks the start of the footer for all files.
/// </summary>
Expand Down Expand Up @@ -115,7 +119,7 @@ public class FilesManager {

if (CurrentBlock != _header && CurrentBlock != _footer)
{
_files.Add(CurrentBlock);
files.Add(CurrentBlock);
}

_currentBlock = null;
Expand All @@ -126,43 +130,58 @@ public class FilesManager {
/// </summary>
/// <param name="split">If true the function is executed and multiple files generated
/// otherwise only a single file is generated.</param>
[SecurityCritical]
public virtual void GenerateFiles(bool split, IFileHandler handlerHelper, IMessageLogger logger, string referenceFolder, bool fileCreated, bool OpenGeneratedFilesInIDE)
public virtual async Task GenerateFilesAsync(bool split)
{
if (split)
{
var tasks = new List<Task>();
EndBlock();
string headerText = Template.ToString(_header.Start, _header.Length);
string footerText = Template.ToString(_footer.Start, _footer.Length);
string outputPath ="";

outputPath = Path.GetTempPath();

_files.Reverse();

foreach(Block block in _files)
var outputPath = Path.GetTempPath();
int length = files.Count;
for (int i = length; i > 0; i--)
{
if(block.IsContainer) continue;
Block block = files[i - 1];
if (block.IsContainer) continue;
string fileName = Path.Combine(outputPath, block.Name);
string content = headerText + Template.ToString(block.Start, block.Length) + footerText;
tasks.Add(CreateFileAsync(fileName, content));
block.TemporaryFilePath = fileName;
Template.Remove(block.Start, block.Length);
}

await Task.WhenAll(tasks);
}
}

if(fileCreated)
{
string outputFile = Path.Combine(referenceFolder, block.Name);
bool fileExists = File.Exists(outputFile);
handlerHelper.AddFileAsync(fileName, outputFile, new ODataFileOptions { OpenOnComplete = OpenGeneratedFilesInIDE, SuppressOverwritePrompt = true }).ContinueWith(
async _ =>
{
await logger?.WriteMessageAsync(LogMessageCategory.Information,
"\"{0}\" has been {1}.", new FileInfo(fileName).Name, fileExists ? "updated" : "added");
}, System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously);
}
else
{
string content = headerText + Template.ToString(block.Start, block.Length) + footerText;
_generatedFileNames.Add(fileName);
CreateFile(fileName, content);
Template.Remove(block.Start, block.Length);
}
/// <summary>
/// Copies the generated file asyncronously using the file handler.
/// </summary>
/// <param name="split">If true the function is executed and multiple files generated otherwise only a single file is generated.</param>
public virtual async Task CopyGeneratedFilesAsync(bool split, IFileHandler handlerHelper, IMessageLogger logger, string referenceFolder, bool fileCreated, bool OpenGeneratedFilesInIDE)
{
if (split)
{
int length = files.Count;
await logger?.WriteMessageAsync(LogMessageCategory.Information, "Adding {0} Generated files to the project. This may take a while!", length);
for (int i = length; i > 0; i--)
{
Block block = files[i - 1];
if (block.IsContainer) continue;
string fileName = block.TemporaryFilePath;
if (!File.Exists(fileName)) continue;

string outputFile = Path.Combine(referenceFolder, block.Name);
bool fileExists = File.Exists(outputFile);

await handlerHelper.AddFileAsync(fileName, outputFile, new ODataFileOptions { OpenOnComplete = OpenGeneratedFilesInIDE, SuppressOverwritePrompt = true })
.ContinueWith(
async _ =>
{
await logger?.WriteMessageAsync(LogMessageCategory.Information,
"\"{0}\" has been {1}.", block.Name, fileExists ? "updated" : "added");
}, System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously);
}
}
}
Expand All @@ -172,12 +191,15 @@ public class FilesManager {
/// </summary>
/// <param name="fileName">Name of the file to be created</param>
/// <param name="content">Content of the file to be created</param>
protected virtual void CreateFile(string fileName, string content)
protected virtual async Task CreateFileAsync(string fileName, string content)
{
if (IsFileContentDifferent(fileName, content))
using (FileStream fileStream = File.OpenWrite(fileName))
using (var writer = new StreamWriter(fileStream))
{
File.WriteAllText(fileName, content);
}
// Truncates the file so if it exists the older content is overwritten.
fileStream.SetLength(0);
await writer.WriteAsync(content).ConfigureAwait(false);
}
}

public virtual string GetCustomToolNamespace(string fileName)
Expand All @@ -193,17 +215,6 @@ public class FilesManager {
}
}

/// <summary>
/// checks if the generated content is different from the existing content.
/// </summary>
/// <param name="fileName">Name of the existing file</param>
/// <param name="newContent">Content of existing file</param>
/// <returns>true if the file content is different</returns>
protected bool IsFileContentDifferent(string fileName, string newContent)
{
return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent);
}

/// <summary>
/// FilesManager constructor. Initializes the template variable.
/// </summary>
Expand Down Expand Up @@ -235,30 +246,6 @@ public class FilesManager {

private class VSManager : FilesManager {

/// <summary>
///Creates a file with the name <paramref name="fileName"> and content <paramref name="content">.
/// </summary>
/// <param name="fileName">Name of the file to be created</param>
/// <param name="content">Content of the file to be created</param>
protected override void CreateFile(string fileName, string content)
{
if (IsFileContentDifferent(fileName, content))
{
File.WriteAllText(fileName, content);
}
}

/// <summary>
/// Generates multiple files depending on the number of blocks.
/// </summary>
/// <param name="split">If true the function is executed and multiple files generated
/// otherwise only a single file is generated.</param>
[SecurityCritical]
public override void GenerateFiles(bool split, IFileHandler handlerHelper, IMessageLogger logger, string referenceFolder, bool fileCreated, bool OpenGeneratedFilesInIDE)
{
base.GenerateFiles(split, handlerHelper, logger, referenceFolder, fileCreated, OpenGeneratedFilesInIDE);
}

/// <summary>
/// VSManager constructor. Initializes the template variable.
/// </summary>
Expand All @@ -267,4 +254,4 @@ public class FilesManager {
{
}
}
} #>
} #>
Loading