From a1c260aacd7e6cfd23f098a3baa6240ff4a76d79 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sun, 10 Mar 2024 10:59:36 -0700 Subject: [PATCH 1/3] Check for long paths on Windows --- .../papermc/paperweight/util/project-util.kt | 2 ++ .../io/papermc/paperweight/util/utils.kt | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt index c719fa48..8f61174f 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt @@ -50,6 +50,8 @@ fun Project.setupServerProject( packagesToFix: Provider?>, reobfMappings: Provider, ): ServerTasks? { + testPathLength(layout) + if (!projectDir.exists()) { return null } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt index 8b131d59..7035f76c 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt @@ -348,6 +348,35 @@ fun FileCollection.toJarClassProviderRoots(): List = files.as .map { p -> ClassProviderRoot.fromJar(p) } .toList() +// Longest path as of 1.20.4 +private const val longestPath: String = + "paperweight/mc-dev-sources/data/minecraft/datapacks/update_1_21/data/minecraft/advancements/" + + "recipes/building_blocks/waxed_weathered_chiseled_copper_from_waxed_weathered_cut_copper_stonecutting.json" + +fun testPathLength(projectLayout: ProjectLayout) { + if (System.getProperty("os.name").lowercase().contains("win")) { + val tmpProjDir = projectLayout.projectDirectory.path.resolveSibling( + projectLayout.projectDirectory.path.name + "_" + ) + val cache = tmpProjDir.resolve(".gradle/$CACHE_PATH") + val testFile = cache.resolve(longestPath) + + try { + testFile.parent.createDirectories() + testFile.writeText("test") + } catch (e: Exception) { + throw PaperweightException( + "The directory this project is cloned in is too nested. Either enable long paths in Windows and Git, or use WSL.\n" + + "Windows documentation: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry\n" + + "Git command: git config --global core.longpaths true", + e + ) + } finally { + tmpProjDir.deleteRecursive() + } + } +} + private fun javaVersion(): Int { val version = System.getProperty("java.specification.version") val parts = version.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() From 90616d74fa0cf293fe913911198132f3c69be962 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sun, 10 Mar 2024 12:03:39 -0700 Subject: [PATCH 2/3] Adjust message --- .../src/main/kotlin/io/papermc/paperweight/util/utils.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt index 7035f76c..1cf9774d 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt @@ -366,9 +366,12 @@ fun testPathLength(projectLayout: ProjectLayout) { testFile.writeText("test") } catch (e: Exception) { throw PaperweightException( - "The directory this project is cloned in is too nested. Either enable long paths in Windows and Git, or use WSL.\n" + - "Windows documentation: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry\n" + - "Git command: git config --global core.longpaths true", + """The directory this project is cloned in is too nested. Possible solutions: +1) Move the project to a less nested directory (i.e. C:\Paper) +2) Enable long paths in Windows and Git: + Windows documentation: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation + Git command: git config --global core.longpaths true +3) Clone and build the project in WSL (this will also improve build speed)""", e ) } finally { From f99621dd657fafe47b867facee236f2333bac29c Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:17:08 -0700 Subject: [PATCH 3/3] Rework long path warning --- .../paperweight/tasks/GenerateDevBundle.kt | 4 - .../papermc/paperweight/util/project-util.kt | 2 +- .../io/papermc/paperweight/util/utils.kt | 74 +++++++++++++------ 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt index 423c44e4..ce46d834 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt @@ -29,7 +29,6 @@ import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* import io.papermc.paperweight.util.data.* import java.io.ByteArrayOutputStream -import java.nio.charset.Charset import java.nio.file.Files import java.nio.file.Path import java.util.Locale @@ -319,9 +318,6 @@ abstract class GenerateDevBundle : DefaultTask() { return asString(outBytes) } - private fun asString(out: ByteArrayOutputStream) = String(out.toByteArray(), Charset.defaultCharset()) - .replace(System.getProperty("line.separator"), "\n") - @Suppress("SameParameterValue") private fun createBundleConfig(dataTargetDir: String, patchTargetDir: String): DevBundleConfig { return DevBundleConfig( diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt index 8f61174f..b99221ee 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt @@ -50,7 +50,7 @@ fun Project.setupServerProject( packagesToFix: Provider?>, reobfMappings: Provider, ): ServerTasks? { - testPathLength(layout) + testPathLength(providers) if (!projectDir.exists()) { return null diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt index 1cf9774d..30787bd2 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt @@ -29,6 +29,7 @@ import io.papermc.paperweight.DownloadService import io.papermc.paperweight.PaperweightException import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.constants.* +import java.io.ByteArrayOutputStream import java.io.File import java.io.InputStream import java.io.OutputStream @@ -36,6 +37,7 @@ import java.lang.management.ManagementFactory import java.lang.reflect.Type import java.net.URI import java.net.URL +import java.nio.charset.Charset import java.nio.file.Path import java.nio.file.Paths import java.security.MessageDigest @@ -45,6 +47,7 @@ import java.util.Locale import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.ThreadLocalRandom +import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicLong import kotlin.io.path.* import org.cadixdev.lorenz.merge.MergeResult @@ -57,6 +60,7 @@ import org.gradle.api.file.RegularFile import org.gradle.api.file.RegularFileProperty import org.gradle.api.invocation.Gradle import org.gradle.api.logging.LogLevel +import org.gradle.api.logging.Logging import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.provider.Property import org.gradle.api.provider.Provider @@ -348,35 +352,57 @@ fun FileCollection.toJarClassProviderRoots(): List = files.as .map { p -> ClassProviderRoot.fromJar(p) } .toList() -// Longest path as of 1.20.4 -private const val longestPath: String = - "paperweight/mc-dev-sources/data/minecraft/datapacks/update_1_21/data/minecraft/advancements/" + - "recipes/building_blocks/waxed_weathered_chiseled_copper_from_waxed_weathered_cut_copper_stonecutting.json" +fun asString(out: ByteArrayOutputStream) = String(out.toByteArray(), Charset.defaultCharset()) + .replace(System.lineSeparator(), "\n") -fun testPathLength(projectLayout: ProjectLayout) { +fun testPathLength(providers: ProviderFactory) { + if (!providers.gradleProperty("paperweight.windowsLongPathWarning").map { it.toBoolean() }.orElse(true).get()) { + return + } if (System.getProperty("os.name").lowercase().contains("win")) { - val tmpProjDir = projectLayout.projectDirectory.path.resolveSibling( - projectLayout.projectDirectory.path.name + "_" - ) - val cache = tmpProjDir.resolve(".gradle/$CACHE_PATH") - val testFile = cache.resolve(longestPath) + val registryQuery = + "reg query HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\FileSystem /v LongPathsEnabled" + val proc = ProcessBuilder() + .command(registryQuery.split(" ")) + .redirectErrorStream(true) + .start() + val outBytes = ByteArrayOutputStream() + val outFuture = redirect(proc.inputStream, outBytes) + if (!proc.waitFor(10L, TimeUnit.SECONDS)) { + proc.destroyForcibly() + throw PaperweightException("Command '$registryQuery' did not finish after 10 seconds, killed process") + } + outFuture.get(500L, TimeUnit.MILLISECONDS) + val out = asString(outBytes) + + val gitQuery = "git config --global --get core.longpaths" + val gitProc = ProcessBuilder() + .command(gitQuery.split(" ")) + .redirectErrorStream(true) + .start() + val gitOutBytes = ByteArrayOutputStream() + val gitOutFuture = redirect(gitProc.inputStream, gitOutBytes) + if (!gitProc.waitFor(10L, TimeUnit.SECONDS)) { + gitProc.destroyForcibly() + throw PaperweightException("Command '$gitQuery' did not finish after 10 seconds, killed process") + } + gitOutFuture.get(500L, TimeUnit.MILLISECONDS) + val gitOut = asString(gitOutBytes) - try { - testFile.parent.createDirectories() - testFile.writeText("test") - } catch (e: Exception) { - throw PaperweightException( - """The directory this project is cloned in is too nested. Possible solutions: -1) Move the project to a less nested directory (i.e. C:\Paper) -2) Enable long paths in Windows and Git: + if (out.contains("LongPathsEnabled REG_DWORD 0x1") && gitOut.contains("true")) { + return + } + val logger = Logging.getLogger("paperweight-path-length-warning") + logger.warn( + """paperweight uses long paths that may exceed the Windows MAX_PATH limit depending on where the project is located. +To avoid build failures and disable this warning, do one of the following: +1) Enable long paths in Windows and Git: Windows documentation: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation Git command: git config --global core.longpaths true -3) Clone and build the project in WSL (this will also improve build speed)""", - e - ) - } finally { - tmpProjDir.deleteRecursive() - } +2) Clone and build the project in WSL (this will also improve build speed) + +This warning can also be disabled by setting the gradle property 'paperweight.windowsLongPathWarning' to 'false'.""" + ) } }