diff --git a/updater/src/com/intellij/updater/CreateAction.java b/updater/src/com/intellij/updater/CreateAction.java index fc44de69a690..d9e7a62cefbe 100644 --- a/updater/src/com/intellij/updater/CreateAction.java +++ b/updater/src/com/intellij/updater/CreateAction.java @@ -5,7 +5,6 @@ import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.LinkOption; -import java.nio.file.attribute.BasicFileAttributes; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; @@ -23,8 +22,7 @@ public class CreateAction extends PatchAction { protected void doBuildPatchFile(File olderFile, File newerFile, ZipOutputStream patchOutput) throws IOException { patchOutput.putNextEntry(new ZipEntry(getPath())); - BasicFileAttributes attrs = Files.readAttributes(newerFile.toPath(), BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS); - if (!attrs.isDirectory()) { + if (!Files.isDirectory(newerFile.toPath(), LinkOption.NOFOLLOW_LINKS)) { FileType type = getFileType(newerFile); writeFileType(patchOutput, type); if (type == FileType.SYMLINK) { diff --git a/updater/src/com/intellij/updater/DeleteAction.java b/updater/src/com/intellij/updater/DeleteAction.java index 6ef4831f8997..388fe535b355 100644 --- a/updater/src/com/intellij/updater/DeleteAction.java +++ b/updater/src/com/intellij/updater/DeleteAction.java @@ -1,9 +1,13 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.updater; import java.io.DataInputStream; import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.util.stream.Stream; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; @@ -53,17 +57,27 @@ public class DeleteAction extends PatchAction { @Override protected void doApply(ZipFile patchFile, File backupDir, File toFile) throws IOException { Runner.logger().info("Delete action. File: " + toFile.getAbsolutePath()); - //NOTE: a folder can be deleted only in case if it does not contain any user's files/folders. - String[] children; - if (!toFile.isDirectory() || (children = toFile.list()) != null && children.length == 0) { + + // a directory can be deleted only when it does not contain any user's content + boolean canDelete = true; + if (Files.isDirectory(toFile.toPath(), LinkOption.NOFOLLOW_LINKS)) { + try (Stream children = Files.list(toFile.toPath())) { + canDelete = !children.findAny().isPresent(); + } + } + + if (canDelete) { Runner.logger().info("Delete: " + toFile.getAbsolutePath()); Utils.delete(toFile); } + else { + Runner.logger().info("Preserved: " + toFile.getAbsolutePath()); + } } @Override protected void doRevert(File toFile, File backupFile) throws IOException { - if (!toFile.exists() || toFile.isDirectory() || isModified(toFile)) { + if (!toFile.exists() || Files.isDirectory(toFile.toPath(), LinkOption.NOFOLLOW_LINKS) || isModified(toFile)) { Utils.delete(toFile); // make sure there is no directory remained on this path (may remain from previous 'create' actions Utils.copy(backupFile, toFile); } diff --git a/updater/testSrc/com/intellij/updater/PatchApplyingRevertingTest.java b/updater/testSrc/com/intellij/updater/PatchApplyingRevertingTest.java index 2c1bbb6de01f..32ae247a72e7 100644 --- a/updater/testSrc/com/intellij/updater/PatchApplyingRevertingTest.java +++ b/updater/testSrc/com/intellij/updater/PatchApplyingRevertingTest.java @@ -606,6 +606,8 @@ public abstract class PatchApplyingRevertingTest extends PatchTestCase { Files.createSymbolicLink(myOlderDir.toPath().resolve("A.framework/Versions/Current"), Paths.get("A")); Files.createSymbolicLink(myOlderDir.toPath().resolve("A.framework/Libraries"), Paths.get("Versions/Current/Libraries")); Files.createSymbolicLink(myOlderDir.toPath().resolve("A.framework/Resources"), Paths.get("Versions/Current/Resources")); + Files.createDirectories(myOlderDir.toPath().resolve("Home/Frameworks")); + Files.createSymbolicLink(myOlderDir.toPath().resolve("Home/Frameworks/A.framework"), Paths.get("../../A.framework")); randomFile(myNewerDir.toPath().resolve("A.framework/Versions/A/Libraries/lib1.dylib")); randomFile(myNewerDir.toPath().resolve("A.framework/Versions/A/Libraries/lib2.dylib"));