Skip to content

Commit

Permalink
Merge pull request #18262 from unoplatform/dev/dr/devSrv
Browse files Browse the repository at this point in the history
feat: Add ability to send null old content to overwrite file
  • Loading branch information
dr1rrb authored Sep 20, 2024
2 parents 05a35d2 + 613e64b commit 10aed0d
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -438,32 +438,29 @@ private async Task ProcessUpdateFile(UpdateFile message)

try
{
var (result, error) = DoUpdateFile();
var (result, error) = message switch
{
{ FilePath: null or { Length: 0 } } => (FileUpdateResult.BadRequest, "Invalid request (file path is empty)"),
{ OldText: not null, NewText: not null } => DoUpdate(message.OldText, message.NewText),
{ OldText: null, NewText: not null } => DoWrite(message.NewText),
{ NewText: null, IsCreateDeleteAllowed: true } => DoDelete(),
_ => (FileUpdateResult.BadRequest, "Invalid request")
};
if ((int)result < 300 && !message.IsForceHotReloadDisabled)
{
await RequestHotReloadToIde(hotReload.Id);
}

await _remoteControlServer.SendFrame(new UpdateFileResponse(message.RequestId, message.FilePath, result, error, hotReload.Id));
await _remoteControlServer.SendFrame(new UpdateFileResponse(message.RequestId, message.FilePath ?? "", result, error, hotReload.Id));
}
catch (Exception ex)
{
await hotReload.Complete(HotReloadServerResult.InternalError, ex);
await _remoteControlServer.SendFrame(new UpdateFileResponse(message.RequestId, message.FilePath, FileUpdateResult.Failed, ex.Message));
await _remoteControlServer.SendFrame(new UpdateFileResponse(message.RequestId, message.FilePath ?? "", FileUpdateResult.Failed, ex.Message));
}

(FileUpdateResult, string?) DoUpdateFile()
(FileUpdateResult, string?) DoUpdate(string oldText, string newText)
{
if (message?.IsValid() is not true)
{
if (this.Log().IsEnabled(LogLevel.Debug))
{
this.Log().LogDebug($"Got an invalid update file frame ({message}) [{message?.RequestId}].");
}

return (FileUpdateResult.BadRequest, "Invalid request");
}

if (!File.Exists(message.FilePath))
{
if (this.Log().IsEnabled(LogLevel.Debug))
Expand All @@ -474,21 +471,16 @@ private async Task ProcessUpdateFile(UpdateFile message)
return (FileUpdateResult.FileNotFound, $"Requested file '{message.FilePath}' does not exists.");
}

if (this.Log().IsEnabled(LogLevel.Debug))
{
this.Log().LogDebug($"Apply Changes to {message.FilePath} [{message.RequestId}].");
}

var originalContent = File.ReadAllText(message.FilePath);
if (this.Log().IsEnabled(LogLevel.Trace))
{
this.Log().LogTrace($"Original content: {message.FilePath} [{message.RequestId}].");
this.Log().LogTrace($"Original content: {originalContent} [{message.RequestId}].");
}

var updatedContent = originalContent.Replace(message.OldText, message.NewText);
var updatedContent = originalContent.Replace(oldText, newText);
if (this.Log().IsEnabled(LogLevel.Trace))
{
this.Log().LogTrace($"Updated content: {message.FilePath} [{message.RequestId}].");
this.Log().LogTrace($"Updated content: {updatedContent} [{message.RequestId}].");
}

if (updatedContent == originalContent)
Expand All @@ -504,6 +496,43 @@ private async Task ProcessUpdateFile(UpdateFile message)
File.WriteAllText(message.FilePath, updatedContent);
return (FileUpdateResult.Success, null);
}

(FileUpdateResult, string?) DoWrite(string newText)
{
if (!message.IsCreateDeleteAllowed && !File.Exists(message.FilePath))
{
if (this.Log().IsEnabled(LogLevel.Debug))
{
this.Log().LogDebug($"Requested file '{message.FilePath}' does not exists [{message.RequestId}].");
}

return (FileUpdateResult.FileNotFound, $"Requested file '{message.FilePath}' does not exists.");
}

if (this.Log().IsEnabled(LogLevel.Trace))
{
this.Log().LogTrace($"Write content: {newText} [{message.RequestId}].");
}

File.WriteAllText(message.FilePath, newText);
return (FileUpdateResult.Success, null);
}

(FileUpdateResult, string?) DoDelete()
{
if (!File.Exists(message.FilePath))
{
if (this.Log().IsEnabled(LogLevel.Debug))
{
this.Log().LogDebug($"Requested file '{message.FilePath}' does not exists [{message.RequestId}].");
}

return (FileUpdateResult.FileNotFound, $"Requested file '{message.FilePath}' does not exists.");
}

File.Delete(message.FilePath);
return (FileUpdateResult.Success, null);
}
}

private async Task<bool> RequestHotReloadToIde(long sequenceId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public record struct UpdateResult(
/// <param name="WaitForHotReload">Indicates if we should also wait for the change to be applied in the application before completing the resulting task.</param>
public record struct UpdateRequest(
string FilePath,
string OldText,
string NewText,
string? OldText,
string? NewText,
bool WaitForHotReload = true)
{
/// <summary>
Expand Down Expand Up @@ -82,7 +82,7 @@ public UpdateRequest Undo(bool waitForHotReload)
=> this with { OldText = NewText, NewText = OldText, WaitForHotReload = waitForHotReload };
}

public Task UpdateFileAsync(string filePath, string oldText, string newText, bool waitForHotReload, CancellationToken ct)
public Task UpdateFileAsync(string filePath, string? oldText, string newText, bool waitForHotReload, CancellationToken ct)
=> UpdateFileAsync(new UpdateRequest(filePath, oldText, newText, waitForHotReload), ct);

public async Task UpdateFileAsync(UpdateRequest req, CancellationToken ct)
Expand All @@ -93,7 +93,7 @@ public async Task UpdateFileAsync(UpdateRequest req, CancellationToken ct)
}
}

public Task TryUpdateFileAsync(string filePath, string oldText, string newText, bool waitForHotReload, CancellationToken ct)
public Task TryUpdateFileAsync(string filePath, string? oldText, string newText, bool waitForHotReload, CancellationToken ct)
=> TryUpdateFileAsync(new UpdateRequest(filePath, oldText, newText, waitForHotReload), ct);

public async Task<UpdateResult> TryUpdateFileAsync(UpdateRequest req, CancellationToken ct)
Expand All @@ -111,7 +111,7 @@ public async Task<UpdateResult> TryUpdateFileAsync(UpdateRequest req, Cancellati
var debug = log.IsDebugEnabled(LogLevel.Debug) ? log : default;
var tag = $"[{Interlocked.Increment(ref _reqId):D2}-{Path.GetFileName(req.FilePath)}]";

debug?.Debug($"{tag} Updating file {req.FilePath} (from: {req.OldText[..100]} | to: {req.NewText[..100]}.");
debug?.Debug($"{tag} Updating file {req.FilePath} (from: {req.OldText?[..100]} | to: {req.NewText?[..100]}.");

// As the local HR is not really ID trackable (trigger by VS without any ID), we capture the current ID here to make sure that if HR completes locally before we get info from the server, we won't miss it.
var currentLocalHrId = GetCurrentLocalHotReloadId();
Expand Down
20 changes: 18 additions & 2 deletions src/Uno.UI.RemoteControl/HotReload/Messages/UpdateFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,23 @@ public class UpdateFile : IMessage
[JsonProperty]
public string FilePath { get; set; } = string.Empty;

/// <summary>
/// The old text to replace in the file, or `null` to create a new file (only if <see cref="IsCreateDeleteAllowed"/> is true).
/// </summary>
[JsonProperty]
public string? OldText { get; set; }

/// <summary>
/// The new text to replace in the file, or `null` to delete the file (only if <see cref="IsCreateDeleteAllowed"/> is true).
/// </summary>
[JsonProperty]
public string OldText { get; set; } = string.Empty;
public string? NewText { get; set; }

/// <summary>
/// Indicates if the file can be created or deleted.
/// </summary>
[JsonProperty]
public string NewText { get; set; } = string.Empty;
public bool IsCreateDeleteAllowed { get; set; }

/// <summary>
/// Disable the forced hot-reload requested on VS after the file has been modified.
Expand All @@ -37,6 +49,10 @@ public class UpdateFile : IMessage
[JsonIgnore]
string IMessage.Name => Name;

/// <summary>
/// LEGACY, indicates if valid for the legacy processor to handle it.
/// </summary>
/// <returns></returns>
[MemberNotNullWhen(true, nameof(FilePath), nameof(OldText), nameof(NewText))]
public bool IsValid()
=> !FilePath.IsNullOrEmpty() &&
Expand Down

0 comments on commit 10aed0d

Please sign in to comment.