Skip to content
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
## Improvements:

## Bug fixes:
* Fix: GenerateFeatureFileCodeBehindTask fails with misleading DirectoryNotFoundException when ndjson output path exceeds Windows MAX_PATH (260)

*Contributors of this release (in alphabetical order):*
*Contributors of this release (in alphabetical order):* @clrudolphi

# v3.3.4 - 2026-03-23

Expand Down
44 changes: 36 additions & 8 deletions Reqnroll.Tools.MsBuild.Generation/GeneratedFileWriter.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
using System;
using System.IO;
using System.Text;
using Reqnroll.Utils;

namespace Reqnroll.Tools.MsBuild.Generation;

/// <summary>
/// This class is going to be obsolete once we implement MsBuild level up-to-date checks.
/// </summary>
public class GeneratedFileWriter(IReqnrollTaskLoggingHelper log)
{
public void WriteGeneratedFile(string outputPath, string generatedFileContent)
Expand All @@ -17,13 +15,15 @@ public void WriteGeneratedFile(string outputPath, string generatedFileContent)

public void DeleteGeneratedFile(string outputPath)
{
if (!File.Exists(outputPath))
var path = ChangePathToSupportLongPaths(outputPath);

if (!File.Exists(path))
return;

log.LogTaskDiagnosticMessage($"Deleting {outputPath}");
try
{
File.Delete(outputPath);
File.Delete(path);
}
catch (IOException ex)
{
Expand All @@ -34,12 +34,40 @@ public void DeleteGeneratedFile(string outputPath)
private void WriteFile(string filePath, string content)
{
string directoryPath = Path.GetDirectoryName(filePath);
Comment thread
gasparnagy marked this conversation as resolved.
if (directoryPath != null && !Directory.Exists(directoryPath))
var longDirPath = ChangePathToSupportLongPaths(directoryPath);
if (!string.IsNullOrEmpty(longDirPath) && !Directory.Exists(longDirPath))
{
Directory.CreateDirectory(longDirPath);
}
var longPath = ChangePathToSupportLongPaths(filePath);
WriteAllTextWithRetry(longPath, content, Encoding.UTF8);
}

private static string ChangePathToSupportLongPaths(string path)
{
if (string.IsNullOrWhiteSpace(path))
return path;

string fullPath = Path.GetFullPath(path);

// Cross-platform: only apply extended syntax on Windows.
if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
System.Runtime.InteropServices.OSPlatform.Windows))
{
Directory.CreateDirectory(directoryPath);
return fullPath;
}

WriteAllTextWithRetry(filePath, content, Encoding.UTF8);
// Already device/extended syntax.
if (fullPath.StartsWith(@"\\?\", StringComparison.Ordinal) ||
fullPath.StartsWith(@"\\.\", StringComparison.Ordinal))
return fullPath;

// UNC longDirPath.
if (fullPath.StartsWith(@"\\", StringComparison.Ordinal))
return @"\\?\UNC\" + fullPath.Substring(2);

// Drive-qualified longDirPath.
return @"\\?\" + fullPath;
}

/// <summary>
Expand Down
Loading