mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-04 04:09:09 +07:00
fix cross-platform build (part 2)
GitOrigin-RevId: 8e228c45e883dbf17dbe4284367c62e3ba1e7c4a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
01d08f3e96
commit
3af34ee528
@@ -42,7 +42,7 @@ private val unmap by lazy {
|
|||||||
lookup.findVirtual(unsafeClass, "invokeCleaner", MethodType.methodType(Void.TYPE, ByteBuffer::class.java)).bindTo(unsafe)
|
lookup.findVirtual(unsafeClass, "invokeCleaner", MethodType.methodType(Void.TYPE, ByteBuffer::class.java)).bindTo(unsafe)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun unmapBuffer(buffer: ByteBuffer) {
|
fun unmapBuffer(buffer: ByteBuffer) {
|
||||||
unmap.invokeExact(buffer)
|
unmap.invokeExact(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,20 +23,12 @@ fun zipWithCompression(targetFile: Path,
|
|||||||
Files.createDirectories(targetFile.parent)
|
Files.createDirectories(targetFile.parent)
|
||||||
ZipFileWriter(channel = FileChannel.open(targetFile, if (overwrite) W_OVERWRITE else W_CREATE_NEW),
|
ZipFileWriter(channel = FileChannel.open(targetFile, if (overwrite) W_OVERWRITE else W_CREATE_NEW),
|
||||||
deflater = Deflater(compressionLevel, true)).use { zipFileWriter ->
|
deflater = Deflater(compressionLevel, true)).use { zipFileWriter ->
|
||||||
val fileAdded: ((String) -> Boolean)?
|
|
||||||
val dirNameSetToAdd: Set<String>
|
|
||||||
if (addDirEntriesMode == AddDirEntriesMode.NONE) {
|
if (addDirEntriesMode == AddDirEntriesMode.NONE) {
|
||||||
if (fileFilter == null) {
|
doArchive(zipFileWriter = zipFileWriter, fileAdded = fileFilter, dirs = dirs)
|
||||||
fileAdded = null
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fileAdded = fileFilter
|
|
||||||
}
|
|
||||||
dirNameSetToAdd = emptySet()
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dirNameSetToAdd = LinkedHashSet()
|
val dirNameSetToAdd = LinkedHashSet<String>()
|
||||||
fileAdded = { name ->
|
val fileAdded = { name: String ->
|
||||||
if (fileFilter != null && !fileFilter(name)) {
|
if (fileFilter != null && !fileFilter(name)) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -49,11 +41,11 @@ fun zipWithCompression(targetFile: Path,
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
doArchive(zipFileWriter = zipFileWriter, fileAdded = fileAdded, dirs = dirs)
|
doArchive(zipFileWriter = zipFileWriter, fileAdded = fileAdded, dirs = dirs)
|
||||||
for (dir in dirNameSetToAdd) {
|
for (dir in dirNameSetToAdd) {
|
||||||
zipFileWriter.dir(dir)
|
zipFileWriter.dir(dir)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,19 +57,13 @@ fun zip(targetFile: Path,
|
|||||||
overwrite: Boolean = false,
|
overwrite: Boolean = false,
|
||||||
fileFilter: ((name: String) -> Boolean)? = null) {
|
fileFilter: ((name: String) -> Boolean)? = null) {
|
||||||
Files.createDirectories(targetFile.parent)
|
Files.createDirectories(targetFile.parent)
|
||||||
val packageIndexBuilder = PackageIndexBuilder()
|
|
||||||
ZipFileWriter(channel = FileChannel.open(targetFile, if (overwrite) W_OVERWRITE else W_CREATE_NEW)).use { zipFileWriter ->
|
ZipFileWriter(channel = FileChannel.open(targetFile, if (overwrite) W_OVERWRITE else W_CREATE_NEW)).use { zipFileWriter ->
|
||||||
val fileAdded: ((String) -> Boolean)?
|
|
||||||
if (addDirEntriesMode == AddDirEntriesMode.NONE) {
|
if (addDirEntriesMode == AddDirEntriesMode.NONE) {
|
||||||
if (fileFilter == null) {
|
doArchive(zipFileWriter = zipFileWriter, fileAdded = fileFilter, dirs = dirs)
|
||||||
fileAdded = null
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fileAdded = fileFilter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fileAdded = { name ->
|
val packageIndexBuilder = PackageIndexBuilder()
|
||||||
|
val fileAdded = { name: String ->
|
||||||
if (fileFilter != null && !fileFilter(name)) {
|
if (fileFilter != null && !fileFilter(name)) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -86,9 +72,9 @@ fun zip(targetFile: Path,
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
doArchive(zipFileWriter = zipFileWriter, fileAdded = fileAdded, dirs = dirs)
|
||||||
|
packageIndexBuilder.writePackageIndex(zipFileWriter, addDirEntriesMode = addDirEntriesMode)
|
||||||
}
|
}
|
||||||
doArchive(zipFileWriter = zipFileWriter, fileAdded = fileAdded, dirs = dirs)
|
|
||||||
packageIndexBuilder.writePackageIndex(zipFileWriter, addDirEntriesMode = addDirEntriesMode)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -204,6 +204,8 @@ private fun getIgnoredNames(): Set<String> {
|
|||||||
set.add("native-image")
|
set.add("native-image")
|
||||||
set.add("native")
|
set.add("native")
|
||||||
set.add("licenses")
|
set.add("licenses")
|
||||||
|
set.add("META-INF/LGPL2.1")
|
||||||
|
set.add("META-INF/AL2.0")
|
||||||
@Suppress("SpellCheckingInspection")
|
@Suppress("SpellCheckingInspection")
|
||||||
set.add(".gitkeep")
|
set.add(".gitkeep")
|
||||||
set.add(INDEX_FILENAME)
|
set.add(INDEX_FILENAME)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.intellij.util.lang.PathClassLoader
|
|||||||
import com.intellij.util.lang.UrlClassLoader
|
import com.intellij.util.lang.UrlClassLoader
|
||||||
import io.opentelemetry.api.common.AttributeKey
|
import io.opentelemetry.api.common.AttributeKey
|
||||||
import io.opentelemetry.api.trace.Span
|
import io.opentelemetry.api.trace.Span
|
||||||
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import org.jetbrains.intellij.build.*
|
import org.jetbrains.intellij.build.*
|
||||||
import org.jetbrains.intellij.build.TraceManager.spanBuilder
|
import org.jetbrains.intellij.build.TraceManager.spanBuilder
|
||||||
@@ -367,7 +368,7 @@ private fun createBuildOptions(runDir: Path): BuildOptions {
|
|||||||
val options = BuildOptions()
|
val options = BuildOptions()
|
||||||
options.printFreeSpace = false
|
options.printFreeSpace = false
|
||||||
options.useCompiledClassesFromProjectOutput = true
|
options.useCompiledClassesFromProjectOutput = true
|
||||||
options.targetOs = BuildOptions.OS_NONE
|
options.targetOs = persistentListOf()
|
||||||
options.cleanOutputFolder = false
|
options.cleanOutputFolder = false
|
||||||
options.skipDependencySetup = true
|
options.skipDependencySetup = true
|
||||||
options.outputRootPath = runDir
|
options.outputRootPath = runDir
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||||
package org.jetbrains.intellij.build
|
package org.jetbrains.intellij.build
|
||||||
|
|
||||||
import com.intellij.openapi.util.SystemInfoRt
|
|
||||||
import com.intellij.util.SystemProperties
|
import com.intellij.util.SystemProperties
|
||||||
|
import kotlinx.collections.immutable.PersistentList
|
||||||
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import org.jetbrains.annotations.ApiStatus
|
import org.jetbrains.annotations.ApiStatus
|
||||||
import org.jetbrains.annotations.ApiStatus.Internal
|
import org.jetbrains.annotations.ApiStatus.Internal
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@@ -181,7 +182,7 @@ class BuildOptions {
|
|||||||
/**
|
/**
|
||||||
* Specifies for which operating systems distributions should be built.
|
* Specifies for which operating systems distributions should be built.
|
||||||
*/
|
*/
|
||||||
var targetOs: String
|
var targetOs: PersistentList<OsFamily>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies for which arch distributions should be built. null means all
|
* Specifies for which arch distributions should be built. null means all
|
||||||
@@ -333,20 +334,21 @@ class BuildOptions {
|
|||||||
@ApiStatus.Experimental
|
@ApiStatus.Experimental
|
||||||
var signNativeFiles = true
|
var signNativeFiles = true
|
||||||
|
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
@ApiStatus.Internal
|
||||||
|
var compressZipFiles = true
|
||||||
|
|
||||||
init {
|
init {
|
||||||
var targetOs = System.getProperty(TARGET_OS_PROPERTY, OS_ALL)
|
val targetOsId = System.getProperty(TARGET_OS_PROPERTY, OS_ALL).lowercase()
|
||||||
if (targetOs == OS_CURRENT) {
|
targetOs = when {
|
||||||
targetOs = when {
|
targetOsId == OS_CURRENT -> persistentListOf(OsFamily.currentOs)
|
||||||
SystemInfoRt.isWindows -> OS_WINDOWS
|
targetOsId.isEmpty() || targetOsId == OS_ALL -> OsFamily.ALL
|
||||||
SystemInfoRt.isMac -> OS_MAC
|
targetOsId == OS_NONE -> persistentListOf()
|
||||||
SystemInfoRt.isLinux -> OS_LINUX
|
targetOsId == OsFamily.MACOS.osId -> persistentListOf(OsFamily.MACOS)
|
||||||
else -> throw RuntimeException("Unknown OS")
|
targetOsId == OsFamily.WINDOWS.osId -> persistentListOf(OsFamily.WINDOWS)
|
||||||
}
|
targetOsId == OsFamily.LINUX.osId -> persistentListOf(OsFamily.LINUX)
|
||||||
|
else -> throw IllegalStateException("Unknown target OS $targetOsId")
|
||||||
}
|
}
|
||||||
else if (targetOs.isEmpty()) {
|
|
||||||
targetOs = OS_ALL
|
|
||||||
}
|
|
||||||
this.targetOs = targetOs
|
|
||||||
|
|
||||||
val sourceDateEpoch = System.getenv("SOURCE_DATE_EPOCH")
|
val sourceDateEpoch = System.getenv("SOURCE_DATE_EPOCH")
|
||||||
buildDateInSeconds = sourceDateEpoch?.toLong() ?: (System.currentTimeMillis() / 1000)
|
buildDateInSeconds = sourceDateEpoch?.toLong() ?: (System.currentTimeMillis() / 1000)
|
||||||
|
|||||||
@@ -72,13 +72,6 @@ interface BuildTasks {
|
|||||||
*/
|
*/
|
||||||
fun buildFullUpdaterJar()
|
fun buildFullUpdaterJar()
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs a fast dry run to check that the build scripts a properly configured. It'll run compilation, build platform and plugin JAR files,
|
|
||||||
* build searchable options index and scramble the main JAR, but won't produce the product archives and installation files which occupy a lot
|
|
||||||
* of disk space and take a long time to build.
|
|
||||||
*/
|
|
||||||
suspend fun runTestBuild()
|
|
||||||
|
|
||||||
suspend fun buildUnpackedDistribution(targetDirectory: Path, includeBinAndRuntime: Boolean)
|
suspend fun buildUnpackedDistribution(targetDirectory: Path, includeBinAndRuntime: Boolean)
|
||||||
|
|
||||||
suspend fun buildDmg(macZipDir: Path)
|
suspend fun buildDmg(macZipDir: Path)
|
||||||
|
|||||||
@@ -243,14 +243,10 @@ class BuildContextImpl private constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldBuildDistributions(): Boolean {
|
override fun shouldBuildDistributions(): Boolean = !options.targetOs.isEmpty()
|
||||||
return options.targetOs.lowercase() != BuildOptions.OS_NONE
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun shouldBuildDistributionForOS(os: OsFamily, arch: JvmArchitecture): Boolean {
|
override fun shouldBuildDistributionForOS(os: OsFamily, arch: JvmArchitecture): Boolean {
|
||||||
return shouldBuildDistributions()
|
return shouldBuildDistributions() && options.targetOs.contains(os) && (options.targetArch == null || options.targetArch == arch)
|
||||||
&& listOf(BuildOptions.OS_ALL, os.osId).contains(options.targetOs.lowercase())
|
|
||||||
&& (options.targetArch == null || options.targetArch == arch)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCopyForProduct(productProperties: ProductProperties, projectHomeForCustomizers: Path): BuildContext {
|
override fun createCopyForProduct(productProperties: ProductProperties, projectHomeForCustomizers: Path): BuildContext {
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ import java.nio.file.StandardCopyOption
|
|||||||
import java.nio.file.attribute.DosFileAttributeView
|
import java.nio.file.attribute.DosFileAttributeView
|
||||||
import java.nio.file.attribute.PosixFilePermission
|
import java.nio.file.attribute.PosixFilePermission
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.function.BiConsumer
|
|
||||||
import java.util.function.Predicate
|
import java.util.function.Predicate
|
||||||
import java.util.stream.Collectors
|
import java.util.stream.Collectors
|
||||||
|
|
||||||
@@ -139,27 +138,10 @@ class BuildTasksImpl(context: BuildContext) : BuildTasks {
|
|||||||
doBuildUpdaterJar(context, "updater.jar")
|
doBuildUpdaterJar(context, "updater.jar")
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun runTestBuild() {
|
|
||||||
checkProductProperties(context)
|
|
||||||
val builderState = compileModulesForDistribution(context)
|
|
||||||
|
|
||||||
coroutineScope {
|
|
||||||
createMavenArtifactJob(context, builderState)
|
|
||||||
|
|
||||||
val entries = DistributionJARsBuilder(builderState).buildJARs(context)
|
|
||||||
layoutShared(context)
|
|
||||||
checkClassFiles(context.paths.distAllDir, context)
|
|
||||||
if (context.productProperties.buildSourcesArchive) {
|
|
||||||
buildSourcesArchive(entries, context)
|
|
||||||
}
|
|
||||||
buildOsSpecificDistributions(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun buildUnpackedDistribution(targetDirectory: Path, includeBinAndRuntime: Boolean) {
|
override suspend fun buildUnpackedDistribution(targetDirectory: Path, includeBinAndRuntime: Boolean) {
|
||||||
val currentOs = OsFamily.currentOs
|
val currentOs = OsFamily.currentOs
|
||||||
context.paths.distAllDir = targetDirectory
|
context.paths.distAllDir = targetDirectory
|
||||||
context.options.targetOs = currentOs.osId
|
context.options.targetOs = persistentListOf(currentOs)
|
||||||
context.options.buildStepsToSkip.add(BuildOptions.GENERATE_JAR_ORDER_STEP)
|
context.options.buildStepsToSkip.add(BuildOptions.GENERATE_JAR_ORDER_STEP)
|
||||||
BundledMavenDownloader.downloadMavenCommonLibs(context.paths.communityHomeDirRoot)
|
BundledMavenDownloader.downloadMavenCommonLibs(context.paths.communityHomeDirRoot)
|
||||||
BundledMavenDownloader.downloadMavenDistribution(context.paths.communityHomeDirRoot)
|
BundledMavenDownloader.downloadMavenDistribution(context.paths.communityHomeDirRoot)
|
||||||
@@ -189,6 +171,23 @@ class BuildTasksImpl(context: BuildContext) : BuildTasks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun doRunTestBuild(context: BuildContext) {
|
||||||
|
checkProductProperties(context as BuildContextImpl)
|
||||||
|
val builderState = compileModulesForDistribution(context)
|
||||||
|
|
||||||
|
coroutineScope {
|
||||||
|
createMavenArtifactJob(context, builderState)
|
||||||
|
|
||||||
|
val entries = DistributionJARsBuilder(builderState).buildJARs(context)
|
||||||
|
layoutShared(context)
|
||||||
|
checkClassFiles(context.paths.distAllDir, context)
|
||||||
|
if (context.productProperties.buildSourcesArchive) {
|
||||||
|
buildSourcesArchive(entries, context)
|
||||||
|
}
|
||||||
|
buildOsSpecificDistributions(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal data class SupportedDistribution(@JvmField val os: OsFamily, @JvmField val arch: JvmArchitecture)
|
internal data class SupportedDistribution(@JvmField val os: OsFamily, @JvmField val arch: JvmArchitecture)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
@@ -653,7 +652,7 @@ suspend fun buildDistributions(context: BuildContext) {
|
|||||||
if (context.buildNumber == null) {
|
if (context.buildNumber == null) {
|
||||||
Span.current().addEvent("Toolbox LiteGen is not executed - it does not support SNAPSHOT build numbers")
|
Span.current().addEvent("Toolbox LiteGen is not executed - it does not support SNAPSHOT build numbers")
|
||||||
}
|
}
|
||||||
else if (context.options.targetOs != BuildOptions.OS_ALL) {
|
else if (context.options.targetOs != OsFamily.ALL) {
|
||||||
Span.current().addEvent(
|
Span.current().addEvent(
|
||||||
"Toolbox LiteGen is not executed - it doesn't support installers are being built only for specific OS")
|
"Toolbox LiteGen is not executed - it doesn't support installers are being built only for specific OS")
|
||||||
}
|
}
|
||||||
@@ -1004,6 +1003,7 @@ private fun buildCrossPlatformZip(distResults: List<DistributionForOsTaskResult>
|
|||||||
distFiles = context.getDistFiles(os = null, arch = null),
|
distFiles = context.getDistFiles(os = null, arch = null),
|
||||||
extraFiles = mapOf("dependencies.txt" to dependenciesFile),
|
extraFiles = mapOf("dependencies.txt" to dependenciesFile),
|
||||||
distAllDir = context.paths.distAllDir,
|
distAllDir = context.paths.distAllDir,
|
||||||
|
compress = context.options.compressZipFiles,
|
||||||
)
|
)
|
||||||
|
|
||||||
checkInArchive(targetFile, "", context)
|
checkInArchive(targetFile, "", context)
|
||||||
@@ -1067,9 +1067,10 @@ private fun crossPlatformZip(macX64DistDir: Path,
|
|||||||
executablePatterns: List<String>,
|
executablePatterns: List<String>,
|
||||||
distFiles: Collection<DistFile>,
|
distFiles: Collection<DistFile>,
|
||||||
extraFiles: Map<String, Path>,
|
extraFiles: Map<String, Path>,
|
||||||
distAllDir: Path) {
|
distAllDir: Path,
|
||||||
|
compress: Boolean) {
|
||||||
writeNewFile(targetFile) { outFileChannel ->
|
writeNewFile(targetFile) { outFileChannel ->
|
||||||
NoDuplicateZipArchiveOutputStream(outFileChannel).use { out ->
|
NoDuplicateZipArchiveOutputStream(outFileChannel, compress = compress).use { out ->
|
||||||
out.setUseZip64(Zip64Mode.Never)
|
out.setUseZip64(Zip64Mode.Never)
|
||||||
|
|
||||||
out.entryToDir(winX64DistDir.resolve("bin/idea.properties"), "bin/win")
|
out.entryToDir(winX64DistDir.resolve("bin/idea.properties"), "bin/win")
|
||||||
@@ -1079,9 +1080,9 @@ private fun crossPlatformZip(macX64DistDir: Path,
|
|||||||
out.entryToDir(macX64DistDir.resolve("bin/${executableName}.vmoptions"), "bin/mac")
|
out.entryToDir(macX64DistDir.resolve("bin/${executableName}.vmoptions"), "bin/mac")
|
||||||
out.entry("bin/mac/${executableName}64.vmoptions", macX64DistDir.resolve("bin/${executableName}.vmoptions"))
|
out.entry("bin/mac/${executableName}64.vmoptions", macX64DistDir.resolve("bin/${executableName}.vmoptions"))
|
||||||
|
|
||||||
extraFiles.forEach(BiConsumer { p, f ->
|
for ((p, f) in extraFiles) {
|
||||||
out.entry(p, f)
|
out.entry(p, f)
|
||||||
})
|
}
|
||||||
|
|
||||||
out.entry("product-info.json", productJson)
|
out.entry("product-info.json", productJson)
|
||||||
|
|
||||||
@@ -1145,7 +1146,7 @@ private fun crossPlatformZip(macX64DistDir: Path,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val commonFilter: (String) -> Boolean = { relPath: String ->
|
val commonFilter: (String) -> Boolean = { relPath ->
|
||||||
!relPath.startsWith("bin/fsnotifier") &&
|
!relPath.startsWith("bin/fsnotifier") &&
|
||||||
!relPath.startsWith("bin/repair") &&
|
!relPath.startsWith("bin/repair") &&
|
||||||
!relPath.startsWith("bin/restart") &&
|
!relPath.startsWith("bin/restart") &&
|
||||||
@@ -1155,32 +1156,39 @@ private fun crossPlatformZip(macX64DistDir: Path,
|
|||||||
!relPath.startsWith("help/")
|
!relPath.startsWith("help/")
|
||||||
}
|
}
|
||||||
|
|
||||||
val zipFiles = LinkedHashMap<String, Path>()
|
val zipFileUniqueGuard = HashMap<String, Path>()
|
||||||
|
|
||||||
out.dir(distAllDir, "", fileFilter = { _, relPath -> relPath != "bin/idea.properties" }, entryCustomizer = entryCustomizer)
|
out.dir(distAllDir, "", fileFilter = { _, relPath -> relPath != "bin/idea.properties" }, entryCustomizer = entryCustomizer)
|
||||||
|
|
||||||
out.dir(macX64DistDir, "", fileFilter = { _, relPath ->
|
out.dir(macX64DistDir, "", fileFilter = { _, relativePath ->
|
||||||
commonFilter.invoke(relPath) &&
|
commonFilter.invoke(relativePath) &&
|
||||||
filterFileIfAlreadyInZip(relPath, macX64DistDir.resolve(relPath), zipFiles)
|
filterFileIfAlreadyInZip(relativePath, macX64DistDir.resolve(relativePath), zipFileUniqueGuard)
|
||||||
}, entryCustomizer = entryCustomizer)
|
}, entryCustomizer = entryCustomizer)
|
||||||
|
|
||||||
out.dir(macArm64DistDir, "", fileFilter = { _, relPath ->
|
out.dir(macArm64DistDir, "", fileFilter = { _, relPath ->
|
||||||
commonFilter.invoke(relPath) &&
|
commonFilter.invoke(relPath) &&
|
||||||
filterFileIfAlreadyInZip(relPath, macArm64DistDir.resolve(relPath), zipFiles)
|
filterFileIfAlreadyInZip(relPath, macArm64DistDir.resolve(relPath), zipFileUniqueGuard)
|
||||||
}, entryCustomizer = entryCustomizer)
|
}, entryCustomizer = entryCustomizer)
|
||||||
|
|
||||||
out.dir(linuxX64DistDir, "", fileFilter = { _, relPath ->
|
out.dir(linuxX64DistDir, "", fileFilter = { _, relPath ->
|
||||||
commonFilter.invoke(relPath) &&
|
commonFilter.invoke(relPath) &&
|
||||||
filterFileIfAlreadyInZip(relPath, linuxX64DistDir.resolve(relPath), zipFiles)
|
filterFileIfAlreadyInZip(relPath, linuxX64DistDir.resolve(relPath), zipFileUniqueGuard)
|
||||||
}, entryCustomizer = entryCustomizer)
|
}, entryCustomizer = entryCustomizer)
|
||||||
|
|
||||||
val winExcludes = distFiles.mapTo(HashSet(distFiles.size)) { "${it.relativeDir}/${it.file.fileName}" }
|
out.dir(startDir = winX64DistDir, prefix = "", fileFilter = { _, relativePath ->
|
||||||
out.dir(winX64DistDir, "", fileFilter = { _, relPath ->
|
commonFilter.invoke(relativePath) &&
|
||||||
commonFilter.invoke(relPath) &&
|
!(relativePath.startsWith("bin/${executableName}") && relativePath.endsWith(".exe")) &&
|
||||||
!(relPath.startsWith("bin/${executableName}") && relPath.endsWith(".exe")) &&
|
filterFileIfAlreadyInZip(relativePath, winX64DistDir.resolve(relativePath), zipFileUniqueGuard)
|
||||||
!winExcludes.contains(relPath) &&
|
|
||||||
filterFileIfAlreadyInZip(relPath, winX64DistDir.resolve(relPath), zipFiles)
|
|
||||||
}, entryCustomizer = entryCustomizer)
|
}, entryCustomizer = entryCustomizer)
|
||||||
|
|
||||||
|
for (distFile in distFiles) {
|
||||||
|
// linux and windows: we don't add win and linux specific dist dirs for ARM, so, copy distFiles explicitly
|
||||||
|
// macOS: we don't copy dist files for macOS distribution to avoid extra copy operation
|
||||||
|
val relativePath = "${distFile.relativeDir}/${distFile.file.fileName}"
|
||||||
|
if (zipFileUniqueGuard.putIfAbsent(relativePath, distFile.file) == null) {
|
||||||
|
out.entry(relativePath, distFile.file)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1125,7 +1125,7 @@ private suspend fun archivePlugins(items: Collection<NonBundledPlugin>, compress
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
writeNewFile(target) { outFileChannel ->
|
writeNewFile(target) { outFileChannel ->
|
||||||
NoDuplicateZipArchiveOutputStream(outFileChannel).use { out ->
|
NoDuplicateZipArchiveOutputStream(outFileChannel, compress = context.options.compressZipFiles).use { out ->
|
||||||
out.setUseZip64(Zip64Mode.Never)
|
out.setUseZip64(Zip64Mode.Never)
|
||||||
out.dir(source, "${source.fileName}/", entryCustomizer = { entry, file, _ ->
|
out.dir(source, "${source.fileName}/", entryCustomizer = { entry, file, _ ->
|
||||||
if (Files.isExecutable(file)) {
|
if (Files.isExecutable(file)) {
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ class MacDistributionBuilder(override val context: BuildContext,
|
|||||||
unpackPty4jNative(context, macDistDir, "darwin")
|
unpackPty4jNative(context, macDistDir, "darwin")
|
||||||
|
|
||||||
generateBuildTxt(context, macDistDir.resolve("Resources"))
|
generateBuildTxt(context, macDistDir.resolve("Resources"))
|
||||||
|
// if copyDistFiles false, it means that we will copy dist files directly without stage dir
|
||||||
if (copyDistFiles) {
|
if (copyDistFiles) {
|
||||||
copyDistFiles(context = context, newDir = macDistDir, os = OsFamily.MACOS, arch = arch)
|
copyDistFiles(context = context, newDir = macDistDir, os = OsFamily.MACOS, arch = arch)
|
||||||
}
|
}
|
||||||
@@ -487,7 +488,7 @@ private fun MacDistributionBuilder.buildMacZip(targetFile: Path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
writeNewFile(targetFile) { targetFileChannel ->
|
writeNewFile(targetFile) { targetFileChannel ->
|
||||||
NoDuplicateZipArchiveOutputStream(targetFileChannel).use { zipOutStream ->
|
NoDuplicateZipArchiveOutputStream(targetFileChannel, compress = context.options.compressZipFiles).use { zipOutStream ->
|
||||||
zipOutStream.setLevel(compressionLevel)
|
zipOutStream.setLevel(compressionLevel)
|
||||||
|
|
||||||
zipOutStream.entry("$zipRoot/Resources/product-info.json", productJson.encodeToByteArray())
|
zipOutStream.entry("$zipRoot/Resources/product-info.json", productJson.encodeToByteArray())
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ internal suspend fun signAndBuildDmg(builder: MacDistributionBuilder,
|
|||||||
val targetName = context.productProperties.getBaseArtifactName(context.applicationInfo, context.buildNumber) + suffix
|
val targetName = context.productProperties.getBaseArtifactName(context.applicationInfo, context.buildNumber) + suffix
|
||||||
val sitFile = (if (context.publishSitArchive) context.paths.artifactDir else context.paths.tempDir).resolve("$targetName.sit")
|
val sitFile = (if (context.publishSitArchive) context.paths.artifactDir else context.paths.tempDir).resolve("$targetName.sit")
|
||||||
|
|
||||||
prepareMacZip(macZip, sitFile, productJson, zipRoot)
|
prepareMacZip(macZip, sitFile, productJson, zipRoot, context.options.compressZipFiles)
|
||||||
|
|
||||||
val sign = !context.options.buildStepsToSkip.contains(BuildOptions.MAC_SIGN_STEP)
|
val sign = !context.options.buildStepsToSkip.contains(BuildOptions.MAC_SIGN_STEP)
|
||||||
if (!sign) {
|
if (!sign) {
|
||||||
@@ -224,14 +224,11 @@ private fun buildDmgLocally(tempDir: Path, targetFileName: String, customizer: M
|
|||||||
}
|
}
|
||||||
|
|
||||||
// our zip for JARs, but here we need to support file permissions - that's why apache compress is used
|
// our zip for JARs, but here we need to support file permissions - that's why apache compress is used
|
||||||
private fun prepareMacZip(macZip: Path,
|
private fun prepareMacZip(macZip: Path, sitFile: Path, productJson: String, zipRoot: String, compress: Boolean) {
|
||||||
sitFile: Path,
|
|
||||||
productJson: String,
|
|
||||||
zipRoot: String) {
|
|
||||||
Files.newByteChannel(macZip, StandardOpenOption.READ).use { sourceFileChannel ->
|
Files.newByteChannel(macZip, StandardOpenOption.READ).use { sourceFileChannel ->
|
||||||
ZipFile(sourceFileChannel).use { zipFile ->
|
ZipFile(sourceFileChannel).use { zipFile ->
|
||||||
writeNewFile(sitFile) { targetFileChannel ->
|
writeNewFile(sitFile) { targetFileChannel ->
|
||||||
NoDuplicateZipArchiveOutputStream(targetFileChannel).use { out ->
|
NoDuplicateZipArchiveOutputStream(targetFileChannel, compress = compress).use { out ->
|
||||||
// file is used only for transfer to mac builder
|
// file is used only for transfer to mac builder
|
||||||
out.setLevel(Deflater.BEST_SPEED)
|
out.setLevel(Deflater.BEST_SPEED)
|
||||||
out.setUseZip64(Zip64Mode.Never)
|
out.setUseZip64(Zip64Mode.Never)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.intellij.openapi.util.SystemInfoRt
|
|||||||
import com.intellij.openapi.util.io.FileUtilRt
|
import com.intellij.openapi.util.io.FileUtilRt
|
||||||
import com.intellij.openapi.util.io.NioFiles
|
import com.intellij.openapi.util.io.NioFiles
|
||||||
import com.intellij.util.io.Decompressor
|
import com.intellij.util.io.Decompressor
|
||||||
|
import io.opentelemetry.api.trace.Span
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.jetbrains.intellij.build.BuildContext
|
import org.jetbrains.intellij.build.BuildContext
|
||||||
@@ -68,13 +69,13 @@ internal suspend fun buildNsisInstaller(winDistPath: Path,
|
|||||||
jreDir: Path,
|
jreDir: Path,
|
||||||
context: BuildContext): Path? {
|
context: BuildContext): Path? {
|
||||||
if (!SystemInfoRt.isWindows && !SystemInfoRt.isLinux) {
|
if (!SystemInfoRt.isWindows && !SystemInfoRt.isLinux) {
|
||||||
context.messages.warning("Windows installer can be built only under Windows or Linux")
|
Span.current().addEvent("Windows installer can be built only under Windows or Linux")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val communityHome = context.paths.communityHomeDir
|
val communityHome = context.paths.communityHomeDir
|
||||||
val outFileName = context.productProperties.getBaseArtifactName(context.applicationInfo, context.buildNumber) + suffix
|
val outFileName = context.productProperties.getBaseArtifactName(context.applicationInfo, context.buildNumber) + suffix
|
||||||
context.messages.progress("Building Windows installer $outFileName")
|
Span.current().setAttribute(outFileName, outFileName)
|
||||||
|
|
||||||
val box = context.paths.tempDir.resolve("winInstaller${suffix}")
|
val box = context.paths.tempDir.resolve("winInstaller${suffix}")
|
||||||
//noinspection SpellCheckingInspection
|
//noinspection SpellCheckingInspection
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ internal class WindowsDistributionBuilder(
|
|||||||
context = context)
|
context = context)
|
||||||
}
|
}
|
||||||
|
|
||||||
context.executeStep(spanBuilder("build Windows Exe Installer"), BuildOptions.WINDOWS_EXE_INSTALLER_STEP) {
|
context.executeStep(spanBuilder("build Windows installer").setAttribute("arch", arch.dirName), BuildOptions.WINDOWS_EXE_INSTALLER_STEP) {
|
||||||
val productJsonDir = context.paths.tempDir.resolve("win.dist.product-info.json.exe")
|
val productJsonDir = context.paths.tempDir.resolve("win.dist.product-info.json.exe")
|
||||||
validateProductJson(jsonText = generateProductJson(targetDir = productJsonDir, isJreIncluded = true, context = context),
|
validateProductJson(jsonText = generateProductJson(targetDir = productJsonDir, isJreIncluded = true, context = context),
|
||||||
relativePathToProductJson = "",
|
relativePathToProductJson = "",
|
||||||
@@ -388,7 +388,13 @@ private fun CoroutineScope.createBuildWinZipTask(jreDirectoryPaths: List<Path>,
|
|||||||
val zipPrefix = customizer.getRootDirectoryName(context.applicationInfo, context.buildNumber)
|
val zipPrefix = customizer.getRootDirectoryName(context.applicationInfo, context.buildNumber)
|
||||||
val dirs = listOf(context.paths.distAllDir, winDistPath, productJsonDir) + jreDirectoryPaths
|
val dirs = listOf(context.paths.distAllDir, winDistPath, productJsonDir) + jreDirectoryPaths
|
||||||
|
|
||||||
zipWithCompression(targetFile = targetFile, dirs = dirs.associateWithTo(LinkedHashMap(dirs.size)) { zipPrefix })
|
val dirMap = dirs.associateWithTo(LinkedHashMap(dirs.size)) { zipPrefix }
|
||||||
|
if (context.options.compressZipFiles) {
|
||||||
|
zipWithCompression(targetFile = targetFile, dirs = dirMap)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
zip(targetFile = targetFile, dirs = dirMap, addDirEntriesMode = AddDirEntriesMode.NONE)
|
||||||
|
}
|
||||||
checkInArchive(archiveFile = targetFile, pathInArchive = zipPrefix, context = context)
|
checkInArchive(archiveFile = targetFile, pathInArchive = zipPrefix, context = context)
|
||||||
context.notifyArtifactWasBuilt(targetFile)
|
context.notifyArtifactWasBuilt(targetFile)
|
||||||
targetFile
|
targetFile
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||||
|
@file:Suppress("ConstPropertyName")
|
||||||
|
|
||||||
package org.jetbrains.intellij.build.impl
|
package org.jetbrains.intellij.build.impl
|
||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtilRt
|
import com.intellij.openapi.util.io.FileUtilRt
|
||||||
@@ -7,19 +9,16 @@ import org.apache.commons.compress.archivers.ArchiveEntry
|
|||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
|
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
|
||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
|
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
|
||||||
import org.apache.commons.io.FileExistsException
|
import org.apache.commons.io.FileExistsException
|
||||||
import org.apache.commons.io.IOUtils
|
|
||||||
import org.jetbrains.intellij.build.io.readZipFile
|
import org.jetbrains.intellij.build.io.readZipFile
|
||||||
|
import org.jetbrains.intellij.build.io.unmapBuffer
|
||||||
|
import java.nio.channels.FileChannel
|
||||||
import java.nio.channels.SeekableByteChannel
|
import java.nio.channels.SeekableByteChannel
|
||||||
import java.nio.file.Files
|
import java.nio.file.*
|
||||||
import java.nio.file.LinkOption
|
|
||||||
import java.nio.file.NoSuchFileException
|
|
||||||
import java.nio.file.Path
|
|
||||||
import java.nio.file.attribute.BasicFileAttributes
|
import java.nio.file.attribute.BasicFileAttributes
|
||||||
import java.nio.file.attribute.FileTime
|
import java.nio.file.attribute.FileTime
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.function.BiConsumer
|
import java.util.function.BiConsumer
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import kotlin.io.path.inputStream
|
|
||||||
import kotlin.io.path.readText
|
import kotlin.io.path.readText
|
||||||
|
|
||||||
private const val fileFlag = 32768 // 0100000
|
private const val fileFlag = 32768 // 0100000
|
||||||
@@ -27,16 +26,15 @@ private const val fileFlag = 32768 // 0100000
|
|||||||
const val executableFileUnixMode = fileFlag or 493 // 0755
|
const val executableFileUnixMode = fileFlag or 493 // 0755
|
||||||
|
|
||||||
fun filterFileIfAlreadyInZip(relativePath: String, file: Path, zipFiles: MutableMap<String, Path>): Boolean {
|
fun filterFileIfAlreadyInZip(relativePath: String, file: Path, zipFiles: MutableMap<String, Path>): Boolean {
|
||||||
val found = zipFiles.put(relativePath, file) ?: return true
|
val old = zipFiles.putIfAbsent(relativePath, file) ?: return true
|
||||||
|
if (compareByMemoryMappedFiles(file, old)) {
|
||||||
if (IOUtils.contentEquals(file.inputStream(), found.inputStream())) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val file1Text = file.readText()
|
val file1Text = file.readText()
|
||||||
val file2Text = found.readText()
|
val file2Text = old.readText()
|
||||||
val isAsciiText: (Char) -> Boolean = { it == '\t' || it == '\n' || it == '\r' || it.code in 32..126 }
|
val isAsciiText: (Char) -> Boolean = { it == '\t' || it == '\n' || it == '\r' || it.code in 32..126 }
|
||||||
val message = "Two files '${found}' and '${file}' with the same target path '${relativePath}' have different content"
|
val message = "Two files '${old}' and '${file}' with the same target path '${relativePath}' have different content"
|
||||||
if (file1Text.take(1024).all(isAsciiText) && file2Text.take(1024).all(isAsciiText)) {
|
if (file1Text.take(1024).all(isAsciiText) && file2Text.take(1024).all(isAsciiText)) {
|
||||||
throw RuntimeException("$message\n\nFile 1: ${"-".repeat(80)}\n$file1Text\n\nFile 2 ${"-".repeat(80)}\n$file2Text")
|
throw RuntimeException("$message\n\nFile 1: ${"-".repeat(80)}\n$file1Text\n\nFile 2 ${"-".repeat(80)}\n$file2Text")
|
||||||
}
|
}
|
||||||
@@ -45,6 +43,31 @@ fun filterFileIfAlreadyInZip(relativePath: String, file: Path, zipFiles: Mutable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun compareByMemoryMappedFiles(path1: Path, path2: Path): Boolean {
|
||||||
|
FileChannel.open(path1, StandardOpenOption.READ).use { channel1 ->
|
||||||
|
FileChannel.open(path2, StandardOpenOption.READ).use { channel2 ->
|
||||||
|
val size = channel1.size()
|
||||||
|
if (size != channel2.size()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val m1 = channel1.map(FileChannel.MapMode.READ_ONLY, 0, size)
|
||||||
|
try {
|
||||||
|
val m2 = channel2.map(FileChannel.MapMode.READ_ONLY, 0, size)
|
||||||
|
try {
|
||||||
|
return m1 == m2
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
unmapBuffer(m2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
unmapBuffer(m1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun consumeDataByPrefix(file: Path, prefixWithEndingSlash: String, consumer: BiConsumer<String, ByteArray>) {
|
fun consumeDataByPrefix(file: Path, prefixWithEndingSlash: String, consumer: BiConsumer<String, ByteArray>) {
|
||||||
readZipFile(file) { name, entry ->
|
readZipFile(file) { name, entry ->
|
||||||
if (name.startsWith(prefixWithEndingSlash)) {
|
if (name.startsWith(prefixWithEndingSlash)) {
|
||||||
@@ -179,9 +202,15 @@ private class ZipArchiveEntryAssertName(name: String): ZipArchiveEntry(name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class NoDuplicateZipArchiveOutputStream(channel: SeekableByteChannel) : ZipArchiveOutputStream(channel) {
|
internal class NoDuplicateZipArchiveOutputStream(channel: SeekableByteChannel, compress: Boolean) : ZipArchiveOutputStream(channel) {
|
||||||
private val entries = HashSet<String>()
|
private val entries = HashSet<String>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (!compress) {
|
||||||
|
setMethod(ZipEntry.STORED)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun putArchiveEntry(archiveEntry: ArchiveEntry) {
|
override fun putArchiveEntry(archiveEntry: ArchiveEntry) {
|
||||||
val entryName = archiveEntry.name
|
val entryName = archiveEntry.name
|
||||||
assertRelativePathIsCorrectForPackaging(entryName)
|
assertRelativePathIsCorrectForPackaging(entryName)
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ internal fun generateBuildTxt(context: BuildContext, targetDirectory: Path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun copyDistFiles(context: BuildContext, newDir: Path, os: OsFamily, arch: JvmArchitecture) {
|
internal fun copyDistFiles(context: BuildContext, newDir: Path, os: OsFamily, arch: JvmArchitecture) {
|
||||||
Files.createDirectories(newDir)
|
|
||||||
for (item in context.getDistFiles(os, arch)) {
|
for (item in context.getDistFiles(os, arch)) {
|
||||||
val dir = newDir.resolve(item.relativeDir)
|
val dir = newDir.resolve(item.relativeDir)
|
||||||
Files.createDirectories(dir)
|
Files.createDirectories(dir)
|
||||||
|
|||||||
@@ -3,18 +3,20 @@ package org.jetbrains.intellij.build.impl.productInfo
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import com.intellij.openapi.util.io.FileUtilRt
|
import com.intellij.openapi.util.io.FileUtilRt
|
||||||
import com.intellij.util.lang.ImmutableZipFile
|
|
||||||
import com.networknt.schema.JsonSchemaFactory
|
import com.networknt.schema.JsonSchemaFactory
|
||||||
import com.networknt.schema.SpecVersion
|
import com.networknt.schema.SpecVersion
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream
|
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream
|
||||||
|
import org.apache.commons.compress.archivers.zip.ZipFile
|
||||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream
|
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream
|
||||||
import org.jetbrains.intellij.build.BuildContext
|
import org.jetbrains.intellij.build.BuildContext
|
||||||
import org.jetbrains.intellij.build.BuildMessages
|
import org.jetbrains.intellij.build.BuildMessages
|
||||||
import org.jetbrains.intellij.build.CompilationContext
|
import org.jetbrains.intellij.build.CompilationContext
|
||||||
import org.jetbrains.intellij.build.OsFamily
|
import org.jetbrains.intellij.build.OsFamily
|
||||||
|
import java.nio.channels.FileChannel
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.StandardOpenOption
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks that product-info.json file located in `archivePath` archive in `pathInArchive` subdirectory is correct
|
* Checks that product-info.json file located in `archivePath` archive in `pathInArchive` subdirectory is correct
|
||||||
@@ -99,8 +101,11 @@ private fun joinPaths(parent: String, child: String): String {
|
|||||||
private fun archiveContainsEntry(archiveFile: Path, entryPath: String): Boolean {
|
private fun archiveContainsEntry(archiveFile: Path, entryPath: String): Boolean {
|
||||||
val fileName = archiveFile.fileName.toString()
|
val fileName = archiveFile.fileName.toString()
|
||||||
if (fileName.endsWith(".zip") || fileName.endsWith(".jar")) {
|
if (fileName.endsWith(".zip") || fileName.endsWith(".jar")) {
|
||||||
ImmutableZipFile.load(archiveFile).use {
|
// don't use ImmutableZipFile - archive maybe more than 2GB
|
||||||
return it.getResource(entryPath) != null
|
FileChannel.open(archiveFile, StandardOpenOption.READ).use { channel ->
|
||||||
|
ZipFile(channel).use {
|
||||||
|
return it.getEntry(entryPath) != null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fileName.endsWith(".tar.gz")) {
|
else if (fileName.endsWith(".tar.gz")) {
|
||||||
@@ -122,8 +127,11 @@ private fun archiveContainsEntry(archiveFile: Path, entryPath: String): Boolean
|
|||||||
private fun loadEntry(archiveFile: Path, entryPath: String): ByteArray? {
|
private fun loadEntry(archiveFile: Path, entryPath: String): ByteArray? {
|
||||||
val fileName = archiveFile.fileName.toString()
|
val fileName = archiveFile.fileName.toString()
|
||||||
if (fileName.endsWith(".zip") || fileName.endsWith(".jar")) {
|
if (fileName.endsWith(".zip") || fileName.endsWith(".jar")) {
|
||||||
ImmutableZipFile.load(archiveFile).use {
|
// don't use ImmutableZipFile - archive maybe more than 2GB
|
||||||
return it.getResource(entryPath)?.data
|
FileChannel.open(archiveFile, StandardOpenOption.READ).use { channel ->
|
||||||
|
ZipFile(channel).use {
|
||||||
|
return it.getInputStream(it.getEntry(entryPath)).readAllBytes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fileName.endsWith(".tar.gz")) {
|
else if (fileName.endsWith(".tar.gz")) {
|
||||||
@@ -136,6 +144,9 @@ private fun loadEntry(archiveFile: Path, entryPath: String): ByteArray? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import kotlinx.coroutines.runBlocking
|
|||||||
import org.jetbrains.intellij.build.*
|
import org.jetbrains.intellij.build.*
|
||||||
import org.jetbrains.intellij.build.dependencies.BuildDependenciesCommunityRoot
|
import org.jetbrains.intellij.build.dependencies.BuildDependenciesCommunityRoot
|
||||||
import org.jetbrains.intellij.build.impl.BuildContextImpl
|
import org.jetbrains.intellij.build.impl.BuildContextImpl
|
||||||
|
import org.jetbrains.intellij.build.impl.buildDistributions
|
||||||
|
import org.jetbrains.intellij.build.impl.doRunTestBuild
|
||||||
import org.jetbrains.intellij.build.impl.logging.BuildMessagesImpl
|
import org.jetbrains.intellij.build.impl.logging.BuildMessagesImpl
|
||||||
import org.jetbrains.intellij.build.testFramework.binaryReproducibility.BuildArtifactsReproducibilityTest
|
import org.jetbrains.intellij.build.testFramework.binaryReproducibility.BuildArtifactsReproducibilityTest
|
||||||
import org.opentest4j.TestAbortedException
|
import org.opentest4j.TestAbortedException
|
||||||
@@ -60,6 +62,7 @@ suspend fun createBuildContext(
|
|||||||
): BuildContext {
|
): BuildContext {
|
||||||
val options = BuildOptions()
|
val options = BuildOptions()
|
||||||
options.signNativeFiles = false
|
options.signNativeFiles = false
|
||||||
|
options.compressZipFiles = false
|
||||||
customizeBuildOptionsForTest(options, productProperties, skipDependencySetup)
|
customizeBuildOptionsForTest(options, productProperties, skipDependencySetup)
|
||||||
buildOptionsCustomizer(options)
|
buildOptionsCustomizer(options)
|
||||||
return BuildContextImpl.createContext(communityHome = communityHomePath,
|
return BuildContextImpl.createContext(communityHome = communityHomePath,
|
||||||
@@ -127,7 +130,7 @@ private fun testBuild(
|
|||||||
}
|
}
|
||||||
|
|
||||||
runTestBuild(
|
runTestBuild(
|
||||||
buildContext = context,
|
context = context,
|
||||||
traceSpanName = traceSpanName,
|
traceSpanName = traceSpanName,
|
||||||
onFinish = onFinish,
|
onFinish = onFinish,
|
||||||
)
|
)
|
||||||
@@ -135,13 +138,13 @@ private fun testBuild(
|
|||||||
|
|
||||||
// FIXME: test reproducibility
|
// FIXME: test reproducibility
|
||||||
fun runTestBuild(
|
fun runTestBuild(
|
||||||
buildContext: BuildContext,
|
context: BuildContext,
|
||||||
traceSpanName: String? = null,
|
traceSpanName: String? = null,
|
||||||
onFinish: suspend (context: BuildContext) -> Unit = {},
|
onFinish: suspend (context: BuildContext) -> Unit = {},
|
||||||
) {
|
) {
|
||||||
initializeTracer
|
initializeTracer
|
||||||
|
|
||||||
val productProperties = buildContext.productProperties
|
val productProperties = context.productProperties
|
||||||
|
|
||||||
// to see in Jaeger as a one trace
|
// to see in Jaeger as a one trace
|
||||||
val traceFileName = "${productProperties.baseFileName}-trace.json"
|
val traceFileName = "${productProperties.baseFileName}-trace.json"
|
||||||
@@ -150,13 +153,18 @@ fun runTestBuild(
|
|||||||
val spanScope = span.makeCurrent()
|
val spanScope = span.makeCurrent()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val outDir = buildContext.paths.buildOutputDir
|
val outDir = context.paths.buildOutputDir
|
||||||
span.setAttribute("outDir", outDir.toString())
|
span.setAttribute("outDir", outDir.toString())
|
||||||
val messages = buildContext.messages as BuildMessagesImpl
|
val messages = context.messages as BuildMessagesImpl
|
||||||
try {
|
try {
|
||||||
runBlocking(Dispatchers.Default) {
|
runBlocking(Dispatchers.Default) {
|
||||||
BuildTasks.create(buildContext).runTestBuild()
|
doRunTestBuild(context)
|
||||||
onFinish(buildContext)
|
if (context.options.targetOs == OsFamily.ALL) {
|
||||||
|
buildDistributions(context)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
onFinish(context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e: Throwable) {
|
catch (e: Throwable) {
|
||||||
|
|||||||
Reference in New Issue
Block a user