diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.kt index 44ca77acf519..a75edeeeeb5a 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.kt @@ -73,11 +73,11 @@ class LinuxDistributionBuilder( withContext(Dispatchers.IO) { val distBinDir = targetPath.resolve("bin") val sourceBinDir = context.paths.communityHomeDir.resolve("bin/linux") - addNativeLauncher(distBinDir = distBinDir, targetPath = targetPath, arch = arch, context = context) + addNativeLauncher(distBinDir, targetPath, arch, context) copyFileToDir(NativeBinaryDownloader.getRestarter(context, OsFamily.LINUX, arch), distBinDir) copyFileToDir(sourceBinDir.resolve("${arch.dirName}/fsnotifier"), distBinDir) - generateBuildTxt(context = context, targetDirectory = targetPath) - copyDistFiles(context = context, newDir = targetPath, os = OsFamily.LINUX, arch = arch, libcImpl = targetLibcImpl) + generateBuildTxt(context, targetPath) + copyDistFiles(context, targetPath, OsFamily.LINUX, arch, targetLibcImpl) //todo converting line separators to unix-style make sense only when building Linux distributions under Windows on a local machine; // for real installers we need to checkout all text files with 'lf' separators anyway @@ -87,15 +87,11 @@ class LinuxDistributionBuilder( Files.copy(iconPngPath, distBinDir.resolve("${context.productProperties.baseFileName}.png"), StandardCopyOption.REPLACE_EXISTING) } writeVmOptions(distBinDir) - generateScripts(distBinDir = distBinDir, arch = arch, targetLibcImpl = targetLibcImpl, context = context) + generateScripts(distBinDir, arch, targetLibcImpl, context) createFrontendContextForLaunchers(context)?.let { clientContext -> writeLinuxVmOptions(distBinDir, clientContext) generateLauncherScript( - distBinDir = distBinDir, - arch = arch, - nonCustomizableJvmArgs = ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS, - context = clientContext, - targetLibcImpl = targetLibcImpl + distBinDir, arch, ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS, clientContext, targetLibcImpl ) } generateReadme(targetPath) @@ -183,9 +179,8 @@ class LinuxDistributionBuilder( ) } - override fun generateExecutableFilesPatterns(includeRuntime: Boolean, arch: JvmArchitecture, libc: LibcImpl): Sequence { - return customizer.generateExecutableFilesPatterns(context, includeRuntime, arch, libc) - } + override fun generateExecutableFilesPatterns(includeRuntime: Boolean, arch: JvmArchitecture, libc: LibcImpl): Sequence = + customizer.generateExecutableFilesPatterns(context, includeRuntime, arch, libc) private val rootDirectoryName: String get() = customizer.getRootDirectoryName(context.applicationInfo, context.buildNumber) @@ -237,9 +232,7 @@ class LinuxDistributionBuilder( JvmArchitecture.aarch64 -> "arm64" } - private fun getSnapArtifactName(snapName: String, arch: JvmArchitecture): String { - return "${snapName}_${snapVersion}_${getSnapArchName(arch)}.snap" - } + private fun getSnapArtifactName(snapName: String, arch: JvmArchitecture): String = "${snapName}_${snapVersion}_${getSnapArchName(arch)}.snap" private suspend fun buildSnapPackage(runtimeDir: Path, unixDistPath: Path, arch: JvmArchitecture, targetLibcImpl: LinuxLibcImpl) { if (!context.options.buildUnixSnaps) { @@ -331,7 +324,7 @@ class LinuxDistributionBuilder( "--volume=$runtimeDir:/build/jre:ro", "--workdir=/build", context.options.snapDockerImage, - "snapcraft", + @Suppress("SpellCheckingInspection") "snapcraft", "snap", "--build-for=$architecture", "-o", "result/$snapArtifactName" @@ -392,104 +385,101 @@ class LinuxDistributionBuilder( writeProductInfoJson(file, json, context) return file } -} -private fun generateVersionMarker(unixDistPath: Path, context: BuildContext) { - val targetDir = unixDistPath.resolve("lib") - Files.createDirectories(targetDir) - Files.writeString(targetDir.resolve("build-marker-" + context.fullBuildNumber), context.fullBuildNumber) -} + private fun generateVersionMarker(unixDistPath: Path, context: BuildContext) { + val targetDir = unixDistPath.resolve("lib") + Files.createDirectories(targetDir) + Files.writeString(targetDir.resolve("build-marker-" + context.fullBuildNumber), context.fullBuildNumber) + } + private fun generateScripts(distBinDir: Path, arch: JvmArchitecture, targetLibcImpl: LinuxLibcImpl, context: BuildContext) { + Files.createDirectories(distBinDir) -private fun generateScripts(distBinDir: Path, arch: JvmArchitecture, targetLibcImpl: LinuxLibcImpl, context: BuildContext) { - Files.createDirectories(distBinDir) - - val sourceScriptDir = context.paths.communityHomeDir.resolve("platform/build-scripts/resources/linux/scripts") - Files.newDirectoryStream(sourceScriptDir).use { - for (file in it) { - val fileName = file.fileName.toString() - if (fileName != EXECUTABLE_TEMPLATE_NAME) { - copyScript(file, distBinDir.resolve(fileName), additionalTemplateValues = emptyList(), context) + val sourceScriptDir = context.paths.communityHomeDir.resolve("platform/build-scripts/resources/linux/scripts") + Files.newDirectoryStream(sourceScriptDir).use { + for (file in it) { + val fileName = file.fileName.toString() + if (fileName != EXECUTABLE_TEMPLATE_NAME) { + copyScript(file, distBinDir.resolve(fileName), additionalTemplateValues = emptyList(), context) + } } } + + copyInspectScript(context, distBinDir) + + generateLauncherScript(distBinDir, arch, nonCustomizableJvmArgs = emptyList(), context, targetLibcImpl) } - copyInspectScript(context, distBinDir) - - generateLauncherScript(distBinDir, arch, nonCustomizableJvmArgs = emptyList(), context, targetLibcImpl) -} - -private suspend fun addNativeLauncher(distBinDir: Path, targetPath: Path, arch: JvmArchitecture, context: BuildContext) { - val (execPath, licensePath) = NativeBinaryDownloader.getLauncher(context, OsFamily.LINUX, arch) - copyFile(execPath, distBinDir.resolve(context.productProperties.baseFileName)) - copyFile(licensePath, targetPath.resolve("license/launcher-third-party-libraries.html")) -} - -private fun generateLauncherScript(distBinDir: Path, arch: JvmArchitecture, nonCustomizableJvmArgs: List, context: BuildContext, targetLibcImpl: LinuxLibcImpl) { - val vmOptionsPath = distBinDir.resolve("${context.productProperties.baseFileName}64.vmoptions") - - val defaultXmxParameter = try { - Files.readAllLines(vmOptionsPath).firstOrNull { it.startsWith("-Xmx") } - ?: throw IllegalStateException("-Xmx was not found in '$vmOptionsPath'") - } - catch (e: NoSuchFileException) { - throw IllegalStateException("File '$vmOptionsPath' should be already generated at this point", e) + private suspend fun addNativeLauncher(distBinDir: Path, targetPath: Path, arch: JvmArchitecture, context: BuildContext) { + val (execPath, licensePath) = NativeBinaryDownloader.getLauncher(context, OsFamily.LINUX, arch) + copyFile(execPath, distBinDir.resolve(context.productProperties.baseFileName)) + copyFile(licensePath, targetPath.resolve("license/launcher-third-party-libraries.html")) } - val classPathJars = context.bootClassPathJarNames - var classPath = $$"CLASS_PATH=\"$IDE_HOME/lib/$${classPathJars[0]}\"" - for (i in 1 until classPathJars.size) { - classPath += $$"\nCLASS_PATH=\"$CLASS_PATH:$IDE_HOME/lib/$${classPathJars[i]}\"" + private fun generateLauncherScript(distBinDir: Path, arch: JvmArchitecture, nonCustomizableJvmArgs: List, context: BuildContext, targetLibcImpl: LinuxLibcImpl) { + val vmOptionsPath = distBinDir.resolve("${context.productProperties.baseFileName}64.vmoptions") + + val defaultXmxParameter = try { + Files.readAllLines(vmOptionsPath).firstOrNull { it.startsWith("-Xmx") } + ?: throw IllegalStateException("-Xmx was not found in '$vmOptionsPath'") + } + catch (e: NoSuchFileException) { + throw IllegalStateException("File '$vmOptionsPath' should be already generated at this point", e) + } + + val classPathJars = context.bootClassPathJarNames + var classPath = $$"CLASS_PATH=\"$IDE_HOME/lib/$${classPathJars[0]}\"" + for (i in 1 until classPathJars.size) { + classPath += $$"\nCLASS_PATH=\"$CLASS_PATH:$IDE_HOME/lib/$${classPathJars[i]}\"" + } + + val additionalJvmArguments = mutableListOf() + // https://youtrack.jetbrains.com/issue/IDEA-304440 + // "-Djdk.lang.Process.launchMechanism=vfork" + if (targetLibcImpl == LinuxLibcImpl.MUSL) { + additionalJvmArguments.add("-Djdk.lang.Process.launchMechanism=vfork") + } + additionalJvmArguments.addAll(context.getAdditionalJvmArguments(OsFamily.LINUX, arch, isScript = true) + nonCustomizableJvmArgs) + + val additionalTemplateValues = listOf( + Pair("vm_options", context.productProperties.baseFileName), + Pair("system_selector", context.systemSelector), + Pair("ide_jvm_args", additionalJvmArguments.joinToString(separator = " ")), + Pair("ide_default_xmx", defaultXmxParameter.trim()), + Pair("class_path", classPath), + Pair("main_class_name", context.ideMainClassName), + ) + + val template = context.paths.communityHomeDir.resolve("platform/build-scripts/resources/linux/scripts/${EXECUTABLE_TEMPLATE_NAME}") + copyScript(template, distBinDir.resolve("${context.productProperties.baseFileName}.sh"), additionalTemplateValues, context) } - val additionalJvmArguments = mutableListOf() - // https://youtrack.jetbrains.com/issue/IDEA-304440 - // "-Djdk.lang.Process.launchMechanism=vfork" - if (targetLibcImpl == LinuxLibcImpl.MUSL) { - additionalJvmArguments.add("-Djdk.lang.Process.launchMechanism=vfork") + private fun copyScript(sourceFile: Path, targetFile: Path, additionalTemplateValues: List>, context: BuildContext) { + // Until CR (\r) will be removed from the repository checkout, we need to filter it out from Unix-style scripts + // https://youtrack.jetbrains.com/issue/IJI-526/Force-git-to-use-LF-line-endings-in-working-copy-of-via-gitattri + substituteTemplatePlaceholders( + inputFile = sourceFile, + outputFile = targetFile, + placeholder = "__", + values = listOf( + Pair("product_full", context.applicationInfo.fullProductName), + Pair("product_uc", context.productProperties.getEnvironmentVariableBaseName(context.applicationInfo)), + Pair("product_vendor", context.applicationInfo.shortCompanyName), + Pair("product_code", context.applicationInfo.productCode), + Pair("script_name", "${context.productProperties.baseFileName}.sh"), + ) + additionalTemplateValues, + mustUseAllPlaceholders = false, + convertToUnixLineEndings = true, + ) } - additionalJvmArguments.addAll(context.getAdditionalJvmArguments(OsFamily.LINUX, arch, isScript = true) + nonCustomizableJvmArgs) - val additionalTemplateValues = listOf( - Pair("vm_options", context.productProperties.baseFileName), - Pair("system_selector", context.systemSelector), - Pair("ide_jvm_args", additionalJvmArguments.joinToString(separator = " ")), - Pair("ide_default_xmx", defaultXmxParameter.trim()), - Pair("class_path", classPath), - Pair("main_class_name", context.ideMainClassName), - ) + private fun writeLinuxVmOptions(distBinDir: Path, context: BuildContext): Path { + val vmOptionsPath = distBinDir.resolve("${context.productProperties.baseFileName}64.vmoptions") + val vmOptions = VmOptionsGenerator.generate(context).asSequence() + sequenceOf("-Dsun.tools.attach.tmp.only=true", "-Dawt.lock.fair=true") + VmOptionsGenerator.writeVmOptions(vmOptionsPath, vmOptions, separator = "\n") + return vmOptionsPath + } - val template = context.paths.communityHomeDir.resolve("platform/build-scripts/resources/linux/scripts/${EXECUTABLE_TEMPLATE_NAME}") - copyScript(template, distBinDir.resolve("${context.productProperties.baseFileName}.sh"), additionalTemplateValues, context) -} - -private fun copyScript(sourceFile: Path, targetFile: Path, additionalTemplateValues: List>, context: BuildContext) { - // Until CR (\r) will be removed from the repository checkout, we need to filter it out from Unix-style scripts - // https://youtrack.jetbrains.com/issue/IJI-526/Force-git-to-use-LF-line-endings-in-working-copy-of-via-gitattri - substituteTemplatePlaceholders( - inputFile = sourceFile, - outputFile = targetFile, - placeholder = "__", - values = listOf( - Pair("product_full", context.applicationInfo.fullProductName), - Pair("product_uc", context.productProperties.getEnvironmentVariableBaseName(context.applicationInfo)), - Pair("product_vendor", context.applicationInfo.shortCompanyName), - Pair("product_code", context.applicationInfo.productCode), - Pair("script_name", "${context.productProperties.baseFileName}.sh"), - ) + additionalTemplateValues, - mustUseAllPlaceholders = false, - convertToUnixLineEndings = true, - ) -} - -private fun writeLinuxVmOptions(distBinDir: Path, context: BuildContext): Path { - val vmOptionsPath = distBinDir.resolve("${context.productProperties.baseFileName}64.vmoptions") - val vmOptions = VmOptionsGenerator.generate(context).asSequence() + sequenceOf("-Dsun.tools.attach.tmp.only=true", "-Dawt.lock.fair=true") - writeVmOptions(file = vmOptionsPath, vmOptions = vmOptions, separator = "\n") - return vmOptionsPath -} - - -private fun suffix(arch: JvmArchitecture, targetLibcImpl: LinuxLibcImpl): String { - return suffix(arch) + if (targetLibcImpl == LinuxLibcImpl.MUSL) "-musl" else "" + private fun suffix(arch: JvmArchitecture, targetLibcImpl: LinuxLibcImpl): String = + suffix(arch) + if (targetLibcImpl == LinuxLibcImpl.MUSL) "-musl" else "" } diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/MacDistributionBuilder.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/MacDistributionBuilder.kt index fe6a2e5c9013..81ea43d9a0d9 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/MacDistributionBuilder.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/MacDistributionBuilder.kt @@ -123,7 +123,6 @@ class MacDistributionBuilder( } private suspend fun doCopyExtraFiles(macDistDir: Path, arch: JvmArchitecture, copyDistFiles: Boolean) { - @Suppress("SpellCheckingInspection") val platformProperties = mutableListOf( "\n#---------------------------------------------------------------------", "# macOS-specific system properties", @@ -185,36 +184,20 @@ class MacDistributionBuilder( val builder = this@MacDistributionBuilder val productJson = generateProductJson(context, arch, withRuntime = true) - val productJsonWithoutRuntime = generateProductJson(context = context, arch = arch, withRuntime = false) + val productJsonWithoutRuntime = generateProductJson(context, arch, withRuntime = false) withContext(Dispatchers.IO) { macZipProductInfoJson.writeText(productJson) macZipWithoutRuntimeProductInfoJson.writeText(productJsonWithoutRuntime) } buildMacZip( - macDistributionBuilder = builder, - targetFile = macZip, - zipRoot = zipRoot, - arch = arch, - productJson = productJson, - directories = directories, - extraFiles = extraFiles, - includeRuntime = true, - compressionLevel = compressionLevel, + builder, macZip, zipRoot, arch, productJson, directories, extraFiles, includeRuntime = true, compressionLevel ) if (customizer.buildArtifactWithoutRuntime) { val directoriesSansRuntime = directories.filterNot { it == runtimeDir } buildMacZip( - macDistributionBuilder = builder, - targetFile = macZipWithoutRuntime, - zipRoot = zipRoot, - arch = arch, - productJson = productJsonWithoutRuntime, - directories = directoriesSansRuntime, - extraFiles = extraFiles, - includeRuntime = false, - compressionLevel = compressionLevel, + builder, macZipWithoutRuntime, zipRoot, arch, productJsonWithoutRuntime, directoriesSansRuntime, extraFiles, includeRuntime = false, compressionLevel ) } @@ -228,13 +211,7 @@ class MacDistributionBuilder( } } else { - buildForArch( - arch = arch, - macZip = macZip, - macZipProductInfoJson = macZipProductInfoJson, - macZipWithoutRuntime = macZipWithoutRuntime, - macZipWithoutRuntimeProductInfoJson = macZipWithoutRuntimeProductInfoJson, - ) + buildForArch(arch, macZip, macZipProductInfoJson, macZipWithoutRuntime, macZipWithoutRuntimeProductInfoJson) } } } @@ -259,8 +236,7 @@ class MacDistributionBuilder( } } - override fun writeVmOptions(distBinDir: Path): Path = - writeMacOsVmOptions(distBinDir, context) + override fun writeVmOptions(distBinDir: Path): Path = writeMacOsVmOptions(distBinDir, context) private suspend fun layoutMacApp( ideaPropertyContent: CharSequence, @@ -359,9 +335,9 @@ class MacDistributionBuilder( macZipWithoutRuntime: Path, macZipWithoutRuntimeProductInfoJson: Path, ) { spanBuilder("build macOS artifacts for specific arch").setAttribute("arch", arch.name).use(Dispatchers.IO) { - val notarize = System.getProperty("intellij.build.mac.notarize")?.toBoolean() - ?: !context.isStepSkipped(BuildOptions.MAC_NOTARIZE_STEP) - && !context.isStepSkipped(BuildOptions.MAC_SIGN_STEP) + val notarize = + (System.getProperty("intellij.build.mac.notarize")?.toBoolean() ?: !context.isStepSkipped(BuildOptions.MAC_NOTARIZE_STEP)) && + !context.isStepSkipped(BuildOptions.MAC_SIGN_STEP) buildForArch(arch, macZip, macZipProductInfoJson, macZipWithoutRuntime, macZipWithoutRuntimeProductInfoJson, notarize) Files.deleteIfExists(macZip) } @@ -372,7 +348,7 @@ class MacDistributionBuilder( macZip: Path, macZipProductInfoJson: Path, macZipWithoutRuntime: Path, macZipWithoutRuntimeProductInfoJson: Path, notarize: Boolean, - ) { + ) { val archStr = arch.name coroutineScope { val taskId = "${BuildOptions.MAC_ARTIFACTS_STEP}_jre_${archStr}" @@ -412,10 +388,10 @@ class MacDistributionBuilder( override fun isRuntimeBundled(file: Path): Boolean = !file.name.contains(NO_RUNTIME_SUFFIX) private suspend fun generateProductJson(context: BuildContext, arch: JvmArchitecture, withRuntime: Boolean): String { - val embeddedFrontendLaunchData = generateEmbeddedFrontendLaunchData(arch = arch, os = OsFamily.MACOS, ideContext = context) { + val embeddedFrontendLaunchData = generateEmbeddedFrontendLaunchData(arch, OsFamily.MACOS, context) { "../bin/${it.productProperties.baseFileName}.vmoptions" } - val qodanaCustomLaunchData = generateQodanaLaunchData(ideContext = context, arch = arch, os = OsFamily.MACOS) + val qodanaCustomLaunchData = generateQodanaLaunchData(context, arch, OsFamily.MACOS) return generateProductInfoJson( relativePathToBin = "../bin", builtinModules = context.builtinModule, @@ -432,7 +408,7 @@ class MacDistributionBuilder( customCommands = listOfNotNull(embeddedFrontendLaunchData, qodanaCustomLaunchData) ) ), - context = context + context ) } @@ -520,9 +496,9 @@ class MacDistributionBuilder( private fun writeMacOsVmOptions(distBinDir: Path, context: BuildContext): Path { val executable = context.productProperties.baseFileName - val fileVmOptions = VmOptionsGenerator.generate(context).asSequence() + sequenceOf("-Dapple.awt.application.appearance=system") + val vmOptions = VmOptionsGenerator.generate(context).asSequence() + sequenceOf("-Dapple.awt.application.appearance=system") val vmOptionsPath = distBinDir.resolve("${executable}.vmoptions") - writeVmOptions(file = vmOptionsPath, vmOptions = fileVmOptions, separator = "\n") + VmOptionsGenerator.writeVmOptions(vmOptionsPath, vmOptions, separator = "\n") return vmOptionsPath } @@ -591,9 +567,8 @@ class MacDistributionBuilder( } } - private fun getMacZipRoot(customizer: MacDistributionCustomizer, context: BuildContext): String { - return "${customizer.getRootDirectoryName(context.applicationInfo, context.buildNumber)}/Contents" - } + private fun getMacZipRoot(customizer: MacDistributionCustomizer, context: BuildContext): String = + "${customizer.getRootDirectoryName(context.applicationInfo, context.buildNumber)}/Contents" private val publishSitArchive: Boolean get() = !context.isStepSkipped(BuildOptions.MAC_SIT_PUBLICATION_STEP) @@ -615,7 +590,7 @@ class MacDistributionBuilder( notarize(sitFile, context) } - buildDmg(sitFile = sitFile, productInfoJson = productInfoJson, dmgName = "${baseName}.dmg", staple = notarize) + buildDmg(sitFile, productInfoJson, "${baseName}.dmg", notarize) if (publishSitArchive) { context.notifyArtifactBuilt(sitFile) @@ -623,7 +598,7 @@ class MacDistributionBuilder( } val zipRoot = getMacZipRoot(customizer, context) - checkExecutablePermissions(distribution = sitFile, root = zipRoot, includeRuntime = isRuntimeBundled, arch = arch, libc = targetLibcImpl) + checkExecutablePermissions(sitFile, zipRoot, isRuntimeBundled, arch, targetLibcImpl) if (isRuntimeBundled) { generateIntegrityManifest(sitFile, zipRoot, arch, context) @@ -637,7 +612,7 @@ class MacDistributionBuilder( NioFiles.deleteRecursively(tempDir) NioFiles.createDirectories(tempDir) NioFiles.createDirectories(context.paths.artifactDir) - val entrypoint = prepareDmgBuildScripts(tempDir = tempDir, staple = staple, customizer = customizer, context = context) + val entrypoint = prepareDmgBuildScripts(tempDir, staple, customizer, context) if (!SystemInfoRt.isMac) { it.addEvent(".dmg can be built only on macOS") if (publishSitArchive) { @@ -661,76 +636,76 @@ class MacDistributionBuilder( NioFiles.deleteRecursively(tempDir) } } -} -private fun prepareDmgBuildScripts(tempDir: Path, staple: Boolean, customizer: MacDistributionCustomizer, context: BuildContext): Path { - NioFiles.deleteRecursively(tempDir) - Files.createDirectories(tempDir) - val dmgImageCopy = tempDir.resolve("${context.fullBuildNumber}.png") - Files.copy(Path.of((if (context.applicationInfo.isEAP) customizer.dmgImagePathForEAP else null) ?: customizer.dmgImagePath), dmgImageCopy) - val scriptsDir = context.paths.communityHomeDir.resolve("platform/build-scripts/tools/mac/scripts") - Files.copy(scriptsDir.resolve("makedmg.sh"), tempDir.resolve("makedmg.sh"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES) - NioFiles.setExecutable(tempDir.resolve("makedmg.sh")) - Files.copy(scriptsDir.resolve("makedmg.py"), tempDir.resolve("makedmg.py"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES) - Files.copy(scriptsDir.resolve("staple.sh"), tempDir.resolve("staple.sh"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES) - val entrypoint = tempDir.resolve("build.sh") - Files.writeString( - entrypoint, - Files.readString(scriptsDir.resolve("build-template.sh")) - .resolveTemplateVar("staple", "$staple") - .resolveTemplateVar("appName", context.fullBuildNumber) - .resolveTemplateVar("contentSigned", "${context.isMacCodeSignEnabled}") - .resolveTemplateVar("buildDateInSeconds", "${context.options.buildDateInSeconds}") - ) - NioFiles.setExecutable(entrypoint) - return entrypoint -} + private fun prepareDmgBuildScripts(tempDir: Path, staple: Boolean, customizer: MacDistributionCustomizer, context: BuildContext): Path { + NioFiles.deleteRecursively(tempDir) + Files.createDirectories(tempDir) + val dmgImageCopy = tempDir.resolve("${context.fullBuildNumber}.png") + Files.copy(Path.of((if (context.applicationInfo.isEAP) customizer.dmgImagePathForEAP else null) ?: customizer.dmgImagePath), dmgImageCopy) + val scriptsDir = context.paths.communityHomeDir.resolve("platform/build-scripts/tools/mac/scripts") + Files.copy(scriptsDir.resolve("makedmg.sh"), tempDir.resolve("makedmg.sh"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES) + NioFiles.setExecutable(tempDir.resolve("makedmg.sh")) + Files.copy(scriptsDir.resolve("makedmg.py"), tempDir.resolve("makedmg.py"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES) + Files.copy(scriptsDir.resolve("staple.sh"), tempDir.resolve("staple.sh"), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES) + val entrypoint = tempDir.resolve("build.sh") + Files.writeString( + entrypoint, + Files.readString(scriptsDir.resolve("build-template.sh")) + .resolveTemplateVar("staple", "$staple") + .resolveTemplateVar("appName", context.fullBuildNumber) + .resolveTemplateVar("contentSigned", "${context.isMacCodeSignEnabled}") + .resolveTemplateVar("buildDateInSeconds", "${context.options.buildDateInSeconds}") + ) + NioFiles.setExecutable(entrypoint) + return entrypoint + } -private fun String.resolveTemplateVar(variable: String, value: String): String { - val reference = "%$variable%" - check(contains(reference)) { "No $reference is found in:\n'$this'" } - return replace(reference, value) -} + private fun String.resolveTemplateVar(variable: String, value: String): String { + val reference = "%$variable%" + check(contains(reference)) { "No $reference is found in:\n'$this'" } + return replace(reference, value) + } -private fun publishDmgBuildScripts(entrypoint: Path, tempDir: Path, context: BuildContext) { - val artifactDir = context.paths.artifactDir.resolve("macos-dmg-build") - artifactDir.createDirectories() - synchronized("$artifactDir".intern()) { - tempDir.listDirectoryEntries().forEach { - Files.copy(it, artifactDir.resolve(it.name), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES) - } - val message = """ + private fun publishDmgBuildScripts(entrypoint: Path, tempDir: Path, context: BuildContext) { + val artifactDir = context.paths.artifactDir.resolve("macos-dmg-build") + artifactDir.createDirectories() + synchronized("$artifactDir".intern()) { + tempDir.listDirectoryEntries().forEach { + Files.copy(it, artifactDir.resolve(it.name), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES) + } + val message = """ To build .dmg(s): 1. transfer .sit(s) to macOS host; 2. transfer ${artifactDir.name}/ content to the same folder; 3. execute ${entrypoint.name} from Terminal. .dmg(s) will be built in the same folder. """.trimIndent() - artifactDir.resolve("README.txt").writeText(message) - context.messages.info(message) - context.notifyArtifactBuilt(artifactDir) - } -} - -private suspend fun generateIntegrityManifest(sitFile: Path, sitRoot: String, arch: JvmArchitecture, context: BuildContext) { - if (context.options.buildStepsToSkip.contains(BuildOptions.REPAIR_UTILITY_BUNDLE_STEP)) { - return - } - - val tempSit = Files.createTempDirectory(context.paths.tempDir, "sit-") - try { - spanBuilder("extracting ${sitFile.name}").use(Dispatchers.IO) { - Decompressor.Zip(sitFile) - .withZipExtensions() - .extract(tempSit) + artifactDir.resolve("README.txt").writeText(message) + context.messages.info(message) + context.notifyArtifactBuilt(artifactDir) } - RepairUtilityBuilder.generateManifest(context, tempSit.resolve(sitRoot), OsFamily.MACOS, arch) } - finally { - withContext(Dispatchers.IO + NonCancellable) { - @OptIn(ExperimentalPathApi::class) - tempSit.deleteRecursively() + + private suspend fun generateIntegrityManifest(sitFile: Path, sitRoot: String, arch: JvmArchitecture, context: BuildContext) { + if (context.options.buildStepsToSkip.contains(BuildOptions.REPAIR_UTILITY_BUNDLE_STEP)) { + return + } + + val tempSit = Files.createTempDirectory(context.paths.tempDir, "sit-") + try { + spanBuilder("extracting ${sitFile.name}").use(Dispatchers.IO) { + Decompressor.Zip(sitFile) + .withZipExtensions() + .extract(tempSit) + } + RepairUtilityBuilder.generateManifest(context, tempSit.resolve(sitRoot), OsFamily.MACOS, arch) + } + finally { + withContext(Dispatchers.IO + NonCancellable) { + @OptIn(ExperimentalPathApi::class) + tempSit.deleteRecursively() + } } } } diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt index a3e33e655892..1c192cc06739 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/TestingTasksImpl.kt @@ -635,7 +635,6 @@ internal class TestingTasksImpl(context: CompilationContext, private val options index = 0, elements = VmOptionsGenerator.generate( isEAP = true, - bundledRuntime = context.bundledRuntime, customVmMemoryOptions = if (customMemoryOptions == null) mapOf("-Xms" to "750m", "-Xmx" to "1024m") else emptyMap(), additionalVmOptions = customMemoryOptions ?: emptyList(), platformPrefix = options.platformPrefix, diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/VmOptionsGenerator.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/VmOptionsGenerator.kt index b2a28419531b..a0829ef7d9a1 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/VmOptionsGenerator.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/VmOptionsGenerator.kt @@ -1,7 +1,6 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.intellij.build.impl -import com.intellij.ReviseWhenPortedToJDK import com.intellij.platform.ijent.community.buildConstants.MULTI_ROUTING_FILE_SYSTEM_VMOPTIONS import com.intellij.platform.ijent.community.buildConstants.isMultiRoutingFileSystemEnabledForProduct import org.jetbrains.intellij.build.BuildContext @@ -10,51 +9,46 @@ import java.nio.file.Files import java.nio.file.Path import kotlin.io.path.name -private const val DEFAULT_MIN_HEAP = "128m" -private const val DEFAULT_MAX_HEAP = "2048m" - -private val COMMON_VM_OPTIONS: List = listOf( - "-XX:JbrShrinkingGcMaxHeapFreeRatio=40", // IJPL-181469. Used in a couple with AppIdleMemoryCleaner.runGc() - "-XX:ReservedCodeCacheSize=512m", - "-XX:+HeapDumpOnOutOfMemoryError", - "-XX:-OmitStackTraceInFastThrow", - "-XX:CICompilerCount=2", - "-XX:+IgnoreUnrecognizedVMOptions", // allowing the JVM to start even with outdated options stuck in user configs - "-ea", - "-Dsun.io.useCanonCaches=false", - "-Dsun.java2d.metal=true", - "-Djbr.catch.SIGABRT=true", - "-Djdk.http.auth.tunneling.disabledSchemes=\"\"", - "-Djdk.attach.allowAttachSelf=true", - "-Djdk.module.illegalAccess.silent=true", - "-Djdk.nio.maxCachedBufferSize=2097152", - "-Djava.util.zip.use.nio.for.zip.file.access=true", // IJPL-149160 - "-Dkotlinx.coroutines.debug=off", -) - -/** duplicates RepositoryHelper.CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY */ -private const val CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY = "intellij.plugins.custom.built.in.repository.url" - object VmOptionsGenerator { + private const val DEFAULT_MIN_HEAP = "128m" + private const val DEFAULT_MAX_HEAP = "2048m" + + private val COMMON_VM_OPTIONS: List = listOf( + "-XX:JbrShrinkingGcMaxHeapFreeRatio=40", // IJPL-181469. Used in a couple with AppIdleMemoryCleaner.runGc() + "-XX:ReservedCodeCacheSize=512m", + "-XX:+HeapDumpOnOutOfMemoryError", + "-XX:-OmitStackTraceInFastThrow", + "-XX:CICompilerCount=2", + "-XX:+IgnoreUnrecognizedVMOptions", // allowing the JVM to start even with outdated options stuck in user configs + "-XX:+UnlockDiagnosticVMOptions", + "-XX:TieredOldPercentage=100000", + "-ea", + "-Dsun.io.useCanonCaches=false", + "-Dsun.java2d.metal=true", + "-Djbr.catch.SIGABRT=true", + "-Djdk.http.auth.tunneling.disabledSchemes=\"\"", + "-Djdk.attach.allowAttachSelf=true", + "-Djdk.module.illegalAccess.silent=true", + "-Djdk.nio.maxCachedBufferSize=2097152", + "-Djava.util.zip.use.nio.for.zip.file.access=true", // IJPL-149160 + "-Dkotlinx.coroutines.debug=off", + ) + + /** duplicates RepositoryHelper.CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY */ + private const val CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY = "intellij.plugins.custom.built.in.repository.url" + fun generate(context: BuildContext): List = generate( context.applicationInfo.isEAP, - context.bundledRuntime, context.productProperties.customJvmMemoryOptions, context.productProperties.additionalVmOptions.let { - val customPluginRepositoryUrl = computeCustomPluginRepositoryUrl(context) - if (customPluginRepositoryUrl == null) { - it - } - else { - it + "-D${CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY}=${customPluginRepositoryUrl}" - } + val url = computeCustomPluginRepositoryUrl(context) + if (url == null) it else it + "-D${CUSTOM_BUILT_IN_PLUGIN_REPOSITORY_PROPERTY}=${url}" }, context.productProperties.platformPrefix, ) internal fun generate( isEAP: Boolean, - bundledRuntime: BundledRuntime, customVmMemoryOptions: Map, additionalVmOptions: List, platformPrefix: String?, @@ -63,12 +57,12 @@ object VmOptionsGenerator { val memory = LinkedHashMap(customVmMemoryOptions) memory.putIfAbsent("-Xms", DEFAULT_MIN_HEAP) - memory.putIfAbsent("-Xmx", DEFAULT_MAX_HEAP) // must be the same as [com.intellij.diagnostic.MemorySizeConfigurator.DEFAULT_XMX] + memory.putIfAbsent("-Xmx", DEFAULT_MAX_HEAP) for ((k, v) in memory) { - result.add(k + v) + result += k + v } - result.addAll(COMMON_VM_OPTIONS) + result += COMMON_VM_OPTIONS if (isMultiRoutingFileSystemEnabledForProduct(platformPrefix)) { result.addAll(MULTI_ROUTING_FILE_SYSTEM_VMOPTIONS) @@ -76,48 +70,31 @@ object VmOptionsGenerator { result += additionalVmOptions - var index = result.indexOf("-ea") - if (index < 0) { - index = result.indexOfFirst { it.startsWith("-D") } - } - if (index < 0) { - index = result.size - } - - result.addAll( - index, - @ReviseWhenPortedToJDK("21", description = "Merge into `COMMON_VM_OPTIONS`") - if (bundledRuntime.build.startsWith("17.")) { - listOf( - "-XX:CompileCommand=exclude,com/intellij/openapi/vfs/impl/FilePartNodeRoot,trieDescend", // temporary workaround for crashes in ะก2 (JBR-4509) - "-XX:SoftRefLRUPolicyMSPerMB=50", - ) - } - else listOf("-XX:+UnlockDiagnosticVMOptions", "-XX:TieredOldPercentage=100000") - ) - if (isEAP) { + var index = result.indexOf("-ea") + if (index < 0) index = result.indexOfFirst { it.startsWith("-D") } + if (index < 0) index = result.size result.add(index, "-XX:MaxJavaStackTraceDepth=10000") // must be consistent with `ConfigImportHelper#updateVMOptions` } return result } -} -private fun computeCustomPluginRepositoryUrl(context: BuildContext): String? { - val artifactsServer = context.proprietaryBuildTools.artifactsServer - if (artifactsServer != null && context.productProperties.productLayout.prepareCustomPluginRepositoryForPublishedPlugins) { - val builtinPluginsRepoUrl = artifactsServer.urlToArtifact(context, "${context.nonBundledPlugins.name}/plugins.xml") - if (builtinPluginsRepoUrl != null) { - if (builtinPluginsRepoUrl.startsWith("http:")) { - context.messages.logErrorAndThrow("Insecure artifact server: ${builtinPluginsRepoUrl}") + private fun computeCustomPluginRepositoryUrl(context: BuildContext): String? { + val artifactsServer = context.proprietaryBuildTools.artifactsServer + if (artifactsServer != null && context.productProperties.productLayout.prepareCustomPluginRepositoryForPublishedPlugins) { + val builtinPluginsRepoUrl = artifactsServer.urlToArtifact(context, "${context.nonBundledPlugins.name}/plugins.xml") + if (builtinPluginsRepoUrl != null) { + if (builtinPluginsRepoUrl.startsWith("http:")) { + context.messages.logErrorAndThrow("Insecure artifact server: ${builtinPluginsRepoUrl}") + } + return builtinPluginsRepoUrl } - return builtinPluginsRepoUrl } + return null } - return null -} -internal fun writeVmOptions(file: Path, vmOptions: Sequence, separator: String) { - Files.writeString(file, vmOptions.joinToString(separator, postfix = separator), StandardCharsets.US_ASCII) + internal fun writeVmOptions(file: Path, vmOptions: Sequence, separator: String) { + Files.writeString(file, vmOptions.joinToString(separator, postfix = separator), StandardCharsets.US_ASCII) + } } diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.kt index 6ea59fca9ebc..007ca16059aa 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.kt @@ -89,7 +89,7 @@ internal class WindowsDistributionBuilder( copyFileToDir(NativeBinaryDownloader.getRestarter(context, OsFamily.WINDOWS, arch), distBinDir) generateBuildTxt(context, targetPath) - copyDistFiles(context = context, newDir = targetPath, os = OsFamily.WINDOWS, arch = arch, libcImpl = WindowsLibcImpl.DEFAULT) + copyDistFiles(context, targetPath, OsFamily.WINDOWS, arch, WindowsLibcImpl.DEFAULT) Files.writeString(distBinDir.resolve(PROPERTIES_FILE_NAME), StringUtilRt.convertLineSeparators(ideaProperties!!, "\r\n")) @@ -101,11 +101,11 @@ internal class WindowsDistributionBuilder( writeVmOptions(distBinDir) - buildWinLauncher(winDistPath = targetPath, arch = arch, context = context, copyLicense = true) + buildWinLauncher(targetPath, arch, context, copyLicense = true) createFrontendContextForLaunchers(context)?.let { clientContext -> writeWindowsVmOptions(distBinDir, clientContext) - buildWinLauncher(winDistPath = targetPath, arch = arch, context = clientContext, copyLicense = false) + buildWinLauncher(targetPath, arch, clientContext, copyLicense = false) } customizer.copyAdditionalFiles(context, targetPath, arch) @@ -133,7 +133,6 @@ internal class WindowsDistributionBuilder( copyFilesForOsDistribution(osAndArchSpecificDistPath, arch) val runtimeDir = context.bundledRuntime.extract(OsFamily.WINDOWS, arch, WindowsLibcImpl.DEFAULT) - @Suppress("SpellCheckingInspection") val vcRtDll = runtimeDir.resolve("jbr/bin/msvcp140.dll") check(Files.exists(vcRtDll)) { "VS C++ Runtime DLL (${vcRtDll.fileName}) not found in ${vcRtDll.parent}.\n" + @@ -151,14 +150,7 @@ internal class WindowsDistributionBuilder( if (customizer.buildZipArchiveWithBundledJre && !context.isStepSkipped(BuildOptions.WINDOWS_ZIP_STEP)) { val zipNameSuffix = suffix(arch) + customizer.zipArchiveWithBundledJreSuffix launch(Dispatchers.IO + CoroutineName("build Windows ${zipNameSuffix}.zip distribution")) { - zipWithJbrPath = createBuildWinZipTask( - runtimeDir = runtimeDir, - zipNameSuffix = zipNameSuffix, - winDistPath = osAndArchSpecificDistPath, - arch = arch, - customizer = customizer, - context = context, - ) + zipWithJbrPath = createBuildWinZipTask(runtimeDir, zipNameSuffix, osAndArchSpecificDistPath, arch, customizer, context) } } @@ -176,14 +168,7 @@ internal class WindowsDistributionBuilder( validateProductJson(jsonText = productJsonFile.readText(), installationDirectories, installationArchives = emptyList(), context) launch(Dispatchers.IO + CoroutineName("build Windows ${arch.dirName} installer")) { exePath = buildNsisInstaller( - winDistPath = osAndArchSpecificDistPath, - productInfoJsonFile = productJsonFile, - additionalDirectoryToInclude = productJsonDir, - suffix = suffix(arch), - customizer = customizer, - runtimeDir = runtimeDir, - context = context, - arch = arch, + osAndArchSpecificDistPath, productJsonFile, productJsonDir, suffix(arch), customizer, runtimeDir, context, arch ) } } @@ -222,7 +207,7 @@ internal class WindowsDistributionBuilder( val winScripts = context.paths.communityHomeDir.resolve("platform/build-scripts/resources/win/scripts") val actualScriptNames = Files.newDirectoryStream(winScripts).use { dirStream -> dirStream.map { it.fileName.toString() }.sorted() } - val expectedScriptNames = listOf("executable-template.bat", "format.bat", "inspect.bat", @Suppress("SpellCheckingInspection") "ltedit.bat") + val expectedScriptNames = listOf("executable-template.bat", "format.bat", "inspect.bat", "ltedit.bat") check(actualScriptNames == expectedScriptNames) { "Expected script names '${expectedScriptNames.joinToString(separator = " ")}', " + "but got '${actualScriptNames.joinToString(separator = " ")}' " + @@ -247,7 +232,7 @@ internal class WindowsDistributionBuilder( ) val inspectScript = context.productProperties.inspectCommandName - for (fileName in listOf("format.bat", "inspect.bat", @Suppress("SpellCheckingInspection") "ltedit.bat")) { + for (fileName in listOf("format.bat", "inspect.bat", "ltedit.bat")) { substituteTemplatePlaceholders( inputFile = winScripts.resolve(fileName), outputFile = distBinDir.resolve(fileName), @@ -479,40 +464,40 @@ internal class WindowsDistributionBuilder( } } } -} -private fun writeWindowsVmOptions(distBinDir: Path, context: BuildContext): Path { - val vmOptionsFile = distBinDir.resolve("${context.productProperties.baseFileName}64.exe.vmoptions") - val vmOptions = VmOptionsGenerator.generate(context).asSequence() - writeVmOptions(file = vmOptionsFile, vmOptions = vmOptions, separator = "\r\n") - return vmOptionsFile -} - -private suspend fun writeProductJsonFile(targetDir: Path, arch: JvmArchitecture, context: BuildContext, withRuntime: Boolean = true): Path { - val embeddedFrontendLaunchData = generateEmbeddedFrontendLaunchData(arch, OsFamily.WINDOWS, context) { - "bin/${it.productProperties.baseFileName}64.exe.vmoptions" + private fun writeWindowsVmOptions(distBinDir: Path, context: BuildContext): Path { + val vmOptionsFile = distBinDir.resolve("${context.productProperties.baseFileName}64.exe.vmoptions") + val vmOptions = VmOptionsGenerator.generate(context).asSequence() + VmOptionsGenerator.writeVmOptions(vmOptionsFile, vmOptions, separator = "\r\n") + return vmOptionsFile } - val qodanaCustomLaunchData = generateQodanaLaunchData(context, arch, OsFamily.WINDOWS) - val json = generateProductInfoJson( - relativePathToBin = "bin", - builtinModules = context.builtinModule, - launch = listOf( - ProductInfoLaunchData.create( - os = OsFamily.WINDOWS.osName, - arch = arch.dirName, - launcherPath = "bin/${context.productProperties.baseFileName}64.exe", - javaExecutablePath = if (withRuntime) "jbr/bin/java.exe" else null, - vmOptionsFilePath = "bin/${context.productProperties.baseFileName}64.exe.vmoptions", - bootClassPathJarNames = context.bootClassPathJarNames, - additionalJvmArguments = context.getAdditionalJvmArguments(OsFamily.WINDOWS, arch), - mainClass = context.ideMainClassName, - customCommands = listOfNotNull(embeddedFrontendLaunchData, qodanaCustomLaunchData), - ) - ), - context) - val file = targetDir.resolve(PRODUCT_INFO_FILE_NAME) - writeProductInfoJson(file, json, context) - return file -} -private fun toDosLineEndings(x: String): String = x.replace("\r", "").replace("\n", "\r\n") + private suspend fun writeProductJsonFile(targetDir: Path, arch: JvmArchitecture, context: BuildContext, withRuntime: Boolean = true): Path { + val embeddedFrontendLaunchData = generateEmbeddedFrontendLaunchData(arch, OsFamily.WINDOWS, context) { + "bin/${it.productProperties.baseFileName}64.exe.vmoptions" + } + val qodanaCustomLaunchData = generateQodanaLaunchData(context, arch, OsFamily.WINDOWS) + val json = generateProductInfoJson( + relativePathToBin = "bin", + builtinModules = context.builtinModule, + launch = listOf( + ProductInfoLaunchData.create( + os = OsFamily.WINDOWS.osName, + arch = arch.dirName, + launcherPath = "bin/${context.productProperties.baseFileName}64.exe", + javaExecutablePath = if (withRuntime) "jbr/bin/java.exe" else null, + vmOptionsFilePath = "bin/${context.productProperties.baseFileName}64.exe.vmoptions", + bootClassPathJarNames = context.bootClassPathJarNames, + additionalJvmArguments = context.getAdditionalJvmArguments(OsFamily.WINDOWS, arch), + mainClass = context.ideMainClassName, + customCommands = listOfNotNull(embeddedFrontendLaunchData, qodanaCustomLaunchData), + ) + ), + context) + val file = targetDir.resolve(PRODUCT_INFO_FILE_NAME) + writeProductInfoJson(file, json, context) + return file + } + + private fun toDosLineEndings(x: String): String = x.replace("\r", "").replace("\n", "\r\n") +} diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/productInfo/ProductInfoGenerator.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/productInfo/ProductInfoGenerator.kt index aa5847270ee5..f7014aa947ce 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/productInfo/ProductInfoGenerator.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/productInfo/ProductInfoGenerator.kt @@ -120,18 +120,16 @@ internal suspend fun generateEmbeddedFrontendLaunchData( os: OsFamily, ideContext: BuildContext, vmOptionsFilePath: (BuildContext) -> String -): CustomCommandLaunchData? { - return createFrontendContextForLaunchers(ideContext)?.let { clientContext -> - CustomCommandLaunchData( - commands = listOf("thinClient", "thinClient-headless", "installFrontendPlugins"), - vmOptionsFilePath = vmOptionsFilePath(clientContext), - bootClassPathJarNames = clientContext.bootClassPathJarNames, - additionalJvmArguments = clientContext.getAdditionalJvmArguments(os, arch) + ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS, - mainClass = clientContext.ideMainClassName, - envVarBaseName = "JETBRAINS_CLIENT", - dataDirectoryName = clientContext.systemSelector, - ) - } +): CustomCommandLaunchData? = createFrontendContextForLaunchers(ideContext)?.let { clientContext -> + CustomCommandLaunchData( + commands = listOf("thinClient", "thinClient-headless", "installFrontendPlugins"), + vmOptionsFilePath = vmOptionsFilePath(clientContext), + bootClassPathJarNames = clientContext.bootClassPathJarNames, + additionalJvmArguments = clientContext.getAdditionalJvmArguments(os, arch) + ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS, + mainClass = clientContext.ideMainClassName, + envVarBaseName = "JETBRAINS_CLIENT", + dataDirectoryName = clientContext.systemSelector, + ) } /** @@ -139,6 +137,4 @@ internal suspend fun generateEmbeddedFrontendLaunchData( * * E.g., if [this] is `installer.tag.gz`, returned Path will be `installer.tag.gz.product-info.json`. */ -internal fun Path.resolveProductInfoJsonSibling(): Path { - return resolveSibling("${this.fileName}.$PRODUCT_INFO_FILE_NAME") -} \ No newline at end of file +internal fun Path.resolveProductInfoJsonSibling(): Path = resolveSibling("${this.fileName}.$PRODUCT_INFO_FILE_NAME") diff --git a/platform/buildData/src/productInfo/ProductInfoData.kt b/platform/buildData/src/productInfo/ProductInfoData.kt index c450b00991ae..67fe55c421fa 100644 --- a/platform/buildData/src/productInfo/ProductInfoData.kt +++ b/platform/buildData/src/productInfo/ProductInfoData.kt @@ -6,7 +6,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.Serializer import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import org.jetbrains.annotations.ApiStatus.Internal +import org.jetbrains.annotations.ApiStatus import java.time.LocalDate import java.time.format.DateTimeFormatter @@ -43,7 +43,7 @@ class ProductInfoData private constructor( val flavors: List = emptyList(), // not used by the launcher; must be at the end - @Internal + @ApiStatus.Internal val layout: List = emptyList(), ) { companion object { @@ -52,7 +52,7 @@ class ProductInfoData private constructor( * Some properties that are nullable in the primary constructor are deliberately marked as not-null in this function to state that they * are required in the current version, and internal clients may rely on their presence. */ - @Internal + @ApiStatus.Internal @JvmStatic fun create( name: String, @@ -72,32 +72,15 @@ class ProductInfoData private constructor( fileExtensions: List, flavors: List, layout: List, - ): ProductInfoData { - return ProductInfoData( - name = name, - version = version, - versionSuffix = versionSuffix, - buildNumber = buildNumber, - productCode = productCode, - envVarBaseName = envVarBaseName, - dataDirectoryName = dataDirectoryName, - svgIconPath = svgIconPath, - productVendor = productVendor, - majorVersionReleaseDate = majorVersionReleaseDate, - launch = launch, - customProperties = customProperties, - bundledPlugins = bundledPlugins, - modules = modules, - fileExtensions = fileExtensions, - flavors = flavors, - layout = layout - ) - } + ): ProductInfoData = ProductInfoData( + name, version, versionSuffix, buildNumber, productCode, envVarBaseName, dataDirectoryName, svgIconPath, productVendor, + majorVersionReleaseDate, launch, customProperties, bundledPlugins, modules, fileExtensions, flavors, layout + ) } } @Serializable -class ProductFlavorData @Internal constructor(@JvmField val id: String) +class ProductFlavorData @ApiStatus.Internal constructor(@JvmField val id: String) /** * Describes 'launch' section in [product-info.json][ProductInfoData] file. @@ -121,7 +104,7 @@ class ProductInfoLaunchData private constructor( * Some properties that are nullable in the primary constructor are deliberately marked as not-null in this function to state that they * are required in the current version, and internal clients may rely on their presence. */ - @Internal + @ApiStatus.Internal @JvmStatic fun create( os: String, @@ -134,25 +117,16 @@ class ProductInfoLaunchData private constructor( mainClass: String, startupWmClass: String? = null, customCommands: List = emptyList(), - ): ProductInfoLaunchData { - return ProductInfoLaunchData( - os = os, - arch = arch, - launcherPath = launcherPath, - javaExecutablePath = javaExecutablePath, - vmOptionsFilePath = vmOptionsFilePath, - startupWmClass = startupWmClass, - bootClassPathJarNames = bootClassPathJarNames, - additionalJvmArguments = additionalJvmArguments, - mainClass = mainClass, - customCommands = customCommands - ) - } + ): ProductInfoLaunchData = ProductInfoLaunchData( + os, arch, launcherPath, javaExecutablePath, vmOptionsFilePath, startupWmClass, bootClassPathJarNames, additionalJvmArguments, + mainClass, customCommands + ) } } @Serializable -class CustomCommandLaunchData @Internal constructor( +@Suppress("unused") +class CustomCommandLaunchData @ApiStatus.Internal constructor( val commands: List, val vmOptionsFilePath: String? = null, val bootClassPathJarNames: List = emptyList(), @@ -163,20 +137,18 @@ class CustomCommandLaunchData @Internal constructor( ) @Serializable -class CustomProperty @Internal constructor( +class CustomProperty @ApiStatus.Internal constructor( val key: String, val value: String, ) @Serializer(forClass = LocalDate::class) private object LocalDateSerializer : KSerializer { - private val formatter = DateTimeFormatter.ofPattern("yyyyMMdd") + private val formatter = DateTimeFormatter.ofPattern(@Suppress("SpellCheckingInspection") "yyyyMMdd") override fun serialize(encoder: Encoder, value: LocalDate) { encoder.encodeString(value.format(formatter)) } - override fun deserialize(decoder: Decoder): LocalDate { - return LocalDate.parse(decoder.decodeString(), formatter) - } + override fun deserialize(decoder: Decoder): LocalDate = LocalDate.parse(decoder.decodeString(), formatter) }