Skip to content

Commit 824df55

Browse files
Chen Linxuanblack-desk
authored andcommitted
Fix symlink handling in CopyDirectory method
Fixes #3234 This change adds proper support for symbolic links in the CopyDirectory method. NOTE: This patch was developed with GitHub Copilot assistance. I has **NO** C# experience at all and is not familiar with actions/runner. This change has not been tested in a local environment. Please review this patch carefully. Signed-off-by: Chen Linxuan <me@black-desk.cn>
1 parent 463496e commit 824df55

1 file changed

Lines changed: 32 additions & 6 deletions

File tree

src/Runner.Sdk/Util/IOUtil.cs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -389,23 +389,49 @@ public static void CopyDirectory(string source, string target, CancellationToken
389389
ArgUtil.NotNull(cancellationToken, nameof(cancellationToken));
390390
cancellationToken.ThrowIfCancellationRequested();
391391

392+
// Get the file contents of the directory to copy.
393+
DirectoryInfo sourceDir = new(source);
394+
395+
if (sourceDir.Attributes.HasFlag(FileAttributes.ReparsePoint))
396+
{
397+
DirectoryInfo targetDir = new(target);
398+
399+
if (targetDir.Exists &&
400+
targetDir.Attributes.HasFlag(FileAttributes.ReparsePoint) &&
401+
targetDir.LinkTarget.Equals(sourceDir.LinkTarget, StringComparison.OrdinalIgnoreCase))
402+
{
403+
return;
404+
}
405+
406+
Directory.CreateSymbolicLink(target, sourceDir.LinkTarget);
407+
return;
408+
}
409+
392410
// Create the target directory.
393411
Directory.CreateDirectory(target);
394412

395-
// Get the file contents of the directory to copy.
396-
DirectoryInfo sourceDir = new(source);
397413
foreach (FileInfo sourceFile in sourceDir.GetFiles() ?? new FileInfo[0])
398414
{
399-
// Check if the file already exists.
400415
cancellationToken.ThrowIfCancellationRequested();
416+
417+
// Check if the file already exists.
401418
FileInfo targetFile = new(Path.Combine(target, sourceFile.Name));
402-
if (!targetFile.Exists ||
403-
sourceFile.Length != targetFile.Length ||
404-
sourceFile.LastWriteTime != targetFile.LastWriteTime)
419+
if (targetFile.Exists &&
420+
sourceFile.Length == targetFile.Length &&
421+
sourceFile.LastWriteTime == targetFile.LastWriteTime)
422+
{
423+
continue;
424+
}
425+
426+
// Check if source is a symlink
427+
if (!sourceFile.Attributes.HasFlag(FileAttributes.ReparsePoint))
405428
{
406429
// Copy the file.
407430
sourceFile.CopyTo(targetFile.FullName, true);
431+
continue;
408432
}
433+
434+
File.CreateSymbolicLink(targetFile.FullName, sourceFile.LinkTarget);
409435
}
410436

411437
// Copy the subdirectories.

0 commit comments

Comments
 (0)