mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-82318: Unlock files locked by pip and python on Windows.
GitOrigin-RevId: 7b72a365964314707b28f6a7f20e3cedbe4bc194
This commit is contained in:
committed by
intellij-monorepo-bot
parent
fb1a3c893b
commit
530fb3f4c8
+1
-1
@@ -26,5 +26,5 @@ fun getProcessLockedPath(path: Path): Result<List<ProcessHandle>, @NlsSafe Strin
|
||||
fun deleteCheckLocking(path: Path, vararg processesToKillIfLocked: Regex = arrayOf(PYTHON)): Unit = deleteCheckLockingImpl(path, *processesToKillIfLocked)
|
||||
|
||||
|
||||
private val PYTHON = Regex("^python[0-9.]*\\.exe$")
|
||||
private val PYTHON = Regex("^(python|pip)[0-9.]*\\.exe$")
|
||||
|
||||
|
||||
+3
-2
@@ -14,6 +14,8 @@ import kotlin.io.path.isDirectory
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
|
||||
private val fileLogger = fileLogger()
|
||||
|
||||
@OptIn(ExperimentalPathApi::class)
|
||||
@Throws(IOException::class, FileLockedException::class)
|
||||
internal fun deleteCheckLockingImpl(path: Path, vararg processesToKill: Regex) {
|
||||
@@ -26,7 +28,6 @@ internal fun deleteCheckLockingImpl(path: Path, vararg processesToKill: Regex) {
|
||||
}
|
||||
|
||||
val paths = listOf(path) + if (path.isDirectory()) Files.walk(path).use { it.toList() } else emptyList()
|
||||
|
||||
// First, kill processes
|
||||
for (child in paths) {
|
||||
for (process in getProcessLockedPath(child).orThrow()) {
|
||||
@@ -34,7 +35,7 @@ internal fun deleteCheckLockingImpl(path: Path, vararg processesToKill: Regex) {
|
||||
val fileName = Path.of(command).fileName.toString()
|
||||
if (processesToKill.any { it.matches(fileName) }) {
|
||||
val processInfo = WinProcessInfo.get(process.pid())
|
||||
fileLogger().warn("Killing ${process.pid()} ${processInfo}")
|
||||
fileLogger.warn("Killing ${process.pid()} ${processInfo}")
|
||||
killProcess(process)
|
||||
}
|
||||
}
|
||||
|
||||
+25
@@ -3,6 +3,9 @@ package com.intellij.python.junit5Tests.unit.showCase
|
||||
import com.intellij.python.junit5Tests.framework.winLockedFile.FileLockedException
|
||||
import com.intellij.python.junit5Tests.framework.winLockedFile.deleteCheckLocking
|
||||
import com.intellij.python.junit5Tests.framework.winLockedFile.getProcessLockedPath
|
||||
import com.intellij.util.io.awaitExit
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import org.hamcrest.CoreMatchers
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.hamcrest.Matchers
|
||||
@@ -16,7 +19,9 @@ import org.junit.jupiter.api.io.TempDir
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.ExperimentalPathApi
|
||||
import kotlin.io.path.deleteIfExists
|
||||
import kotlin.io.path.writeText
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
class WinLockedFilesTest {
|
||||
|
||||
@@ -60,4 +65,24 @@ class WinLockedFilesTest {
|
||||
process.waitFor()
|
||||
deleteCheckLocking(path)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalPathApi::class)
|
||||
@EnabledOnOs(value = [OS.WINDOWS])
|
||||
@Test
|
||||
fun testDirectoryLockedUnlock(@TempDir path: Path): Unit = runBlocking {
|
||||
val systemRoot = System.getenv("SystemRoot") ?: "c:\\windows"
|
||||
val process = ProcessBuilder("$systemRoot/system32/cmd.exe")
|
||||
.directory(path.toFile())
|
||||
.start()
|
||||
try {
|
||||
deleteCheckLocking(path, Regex("cmd\\.exe"))
|
||||
withTimeoutOrNull(10.seconds) {
|
||||
process.awaitExit()
|
||||
}
|
||||
path.deleteIfExists()
|
||||
}
|
||||
finally {
|
||||
process.destroyForcibly()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user