From 1d177119a292a08535c4962a85a14dc78211c7b7 Mon Sep 17 00:00:00 2001
From: "bazel.build machine account" <ci.bazel@gmail.com>
Date: Fri, 25 Oct 2024 11:37:22 +0200
Subject: [PATCH] [8.0.0] Partial fix for bug with creating a junction to file
 instead of symlink (#24058)

This is a partial fix for issue #21747 for the
`--windows_enable_symlinks` case.
The fix was suggested in discussion of this issue. This resolves the
problem with creating a junction if the target path doesn't exist for
those who have Windows symlinks enabled, until a complete solution is
provided.

Closes #24051.

PiperOrigin-RevId: 688724224
Change-Id: Ie44f7834af5fd35ab57961e6012b9f336c25d606

Commit
https://github.com/bazelbuild/bazel/commit/3e5514d97342421ac285c5b5edcf76ba743fda8e

Co-authored-by: Alexander Golovlev <golovlev@gmail.com>
---
 .../build/lib/windows/WindowsFileSystem.java       | 14 +++++++-------
 src/main/native/windows/file.cc                    |  3 ++-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/google/devtools/build/lib/windows/WindowsFileSystem.java b/src/main/java/com/google/devtools/build/lib/windows/WindowsFileSystem.java
index 7edea00bc17..9c351785872 100644
--- a/src/main/java/com/google/devtools/build/lib/windows/WindowsFileSystem.java
+++ b/src/main/java/com/google/devtools/build/lib/windows/WindowsFileSystem.java
@@ -79,15 +79,15 @@ public class WindowsFileSystem extends JavaIoFileSystem {
     try {
       java.nio.file.Path link = getIoFile(linkPath).toPath();
       java.nio.file.Path target = getIoFile(targetPath).toPath();
-      // Still Create a dangling junction if the target doesn't exist.
-      if (!target.toFile().exists() || target.toFile().isDirectory()) {
+      if (target.toFile().isDirectory()) {
+        WindowsFileOperations.createJunction(link.toString(), target.toString());
+      } else if (createSymbolicLinks) {
+        WindowsFileOperations.createSymlink(link.toString(), target.toString());
+      } else if (!target.toFile().exists()) {
+        // Still Create a dangling junction if the target doesn't exist.
         WindowsFileOperations.createJunction(link.toString(), target.toString());
       } else {
-        if (createSymbolicLinks) {
-          WindowsFileOperations.createSymlink(link.toString(), target.toString());
-        } else {
-          Files.copy(target, link);
-        }
+        Files.copy(target, link);
       }
     } catch (java.nio.file.FileAlreadyExistsException e) {
       throw new IOException(linkPath + ERR_FILE_EXISTS, e);
diff --git a/src/main/native/windows/file.cc b/src/main/native/windows/file.cc
index f20831e09bc..70809bde048 100644
--- a/src/main/native/windows/file.cc
+++ b/src/main/native/windows/file.cc
@@ -505,7 +505,8 @@ int CreateSymlink(const wstring& symlink_name, const wstring& symlink_target,
   const wstring target = AddUncPrefixMaybe(symlink_target);
 
   DWORD attrs = GetFileAttributesW(target.c_str());
-  if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
+  if ((attrs != INVALID_FILE_ATTRIBUTES) &&
+      (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
     // Instead of creating a symlink to a directory use a Junction.
     return CreateSymlinkResult::kTargetIsDirectory;
   }
-- 
GitLab