mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 11:53:49 +07:00
IJI-2358 artifacts may be supplied in both the flat and the regular Maven layout
(cherry picked from commit 915a4c59cd6e5ef1f9d8c111876bad07e0b3ea97) IJ-MR-159792 GitOrigin-RevId: dff1f3cc50c3ce95f4ef858853c23b1d098c7a25
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ccf7641949
commit
6cc9f277fc
@@ -28,7 +28,18 @@ import org.jetbrains.intellij.build.telemetry.use
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.io.path.*
|
||||
import kotlin.io.path.ExperimentalPathApi
|
||||
import kotlin.io.path.PathWalkOption
|
||||
import kotlin.io.path.deleteIfExists
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.inputStream
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.listDirectoryEntries
|
||||
import kotlin.io.path.name
|
||||
import kotlin.io.path.readLines
|
||||
import kotlin.io.path.relativeTo
|
||||
import kotlin.io.path.walk
|
||||
import kotlin.io.path.writeText
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
|
||||
/**
|
||||
@@ -41,6 +52,7 @@ import kotlin.time.Duration.Companion.minutes
|
||||
* See https://youtrack.jetbrains.com/articles/IJPL-A-611 internal article for more details
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@OptIn(ExperimentalPathApi::class)
|
||||
class MavenCentralPublication(
|
||||
private val context: BuildContext,
|
||||
private val workDir: Path,
|
||||
@@ -75,24 +87,53 @@ class MavenCentralPublication(
|
||||
val distributionFiles: List<Path> = listOf(jar, pom, javadoc, sources)
|
||||
|
||||
val signatures: List<Path>
|
||||
get() = if (sign) files(extension = "asc") else emptyList()
|
||||
get() = distributionFiles.asSequence()
|
||||
.map { it.resolveSibling("${it.fileName}.asc") }
|
||||
.onEach {
|
||||
check(sign || dryRun || it.exists()) {
|
||||
"Signature file $it is expected to present"
|
||||
}
|
||||
}.filter {
|
||||
it.exists()
|
||||
}.toList()
|
||||
|
||||
val checksums: List<Path>
|
||||
get() = files("md5") +
|
||||
files("sha1") +
|
||||
files("sha256") +
|
||||
files("sha512")
|
||||
get() = distributionFiles.asSequence().flatMap {
|
||||
sequenceOf(
|
||||
it.resolveSibling("${it.fileName}.md5"),
|
||||
it.resolveSibling("${it.fileName}.sha1"),
|
||||
it.resolveSibling("${it.fileName}.sha256"),
|
||||
it.resolveSibling("${it.fileName}.sha512"),
|
||||
)
|
||||
}.onEach {
|
||||
check(it.exists()) {
|
||||
"Checksum file $it is expected to present"
|
||||
}
|
||||
}.toList()
|
||||
}
|
||||
|
||||
private fun Path.listDirectoryEntriesRecursively(glob: String): List<Path> {
|
||||
val matchingFiles = walk(PathWalkOption.INCLUDE_DIRECTORIES)
|
||||
.filter { it.isDirectory() }
|
||||
.flatMap { it.listDirectoryEntries(glob = glob) }
|
||||
.toList()
|
||||
check(matchingFiles.size == matchingFiles.distinctBy { it.name }.size) {
|
||||
matchingFiles.joinToString(prefix = "Duplicate files found in $this:\n", separator = "\n") {
|
||||
it.relativeTo(this).toString()
|
||||
}
|
||||
}
|
||||
return matchingFiles
|
||||
}
|
||||
|
||||
private fun file(name: String): Path {
|
||||
val matchingFiles = workDir.listDirectoryEntries(glob = name)
|
||||
val matchingFiles = workDir.listDirectoryEntriesRecursively(glob = name)
|
||||
return requireNotNull(matchingFiles.singleOrNull()) {
|
||||
"A single $name file is expected to be present in $workDir but found: $matchingFiles"
|
||||
}
|
||||
}
|
||||
|
||||
private fun files(extension: String): List<Path> {
|
||||
val matchingFiles = workDir.listDirectoryEntries(glob = "*.$extension")
|
||||
val matchingFiles = workDir.listDirectoryEntriesRecursively(glob = "*.$extension")
|
||||
require(matchingFiles.any()) {
|
||||
"No *.$extension files in $workDir"
|
||||
}
|
||||
@@ -178,6 +219,7 @@ class MavenCentralPublication(
|
||||
private suspend fun bundle(): Path {
|
||||
return spanBuilder("creating a bundle").use {
|
||||
val bundle = workDir.resolve("bundle.zip")
|
||||
bundle.deleteIfExists()
|
||||
Compressor.Zip(bundle).use { zip ->
|
||||
for (artifact in artifacts) {
|
||||
artifact.distributionFiles.asSequence()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2024 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.maven
|
||||
|
||||
import com.intellij.testFramework.assertions.Assertions.assertThat
|
||||
import com.intellij.testFramework.utils.io.createFile
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.intellij.build.BuildContext
|
||||
@@ -15,7 +16,6 @@ import org.junit.jupiter.api.assertThrows
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.name
|
||||
import kotlin.io.path.writeText
|
||||
|
||||
class MavenCentralPublicationTest {
|
||||
@@ -34,26 +34,35 @@ class MavenCentralPublicationTest {
|
||||
@TempDir
|
||||
lateinit var workDir: Path
|
||||
val publication: MavenCentralPublication by lazy { MavenCentralPublication(context, workDir, dryRun = true) }
|
||||
val coordinates = MavenCoordinates("foo", "bar", "1.0")
|
||||
fun createDistributionFiles(): List<Path> {
|
||||
|
||||
class Result(val workDirPath: Path, val zipPath: String)
|
||||
|
||||
fun createDistributionFiles(flatLayout: Boolean = false): List<Result> {
|
||||
return sequenceOf(
|
||||
"pom" to "",
|
||||
"jar" to "",
|
||||
"jar" to "sources",
|
||||
"jar" to "javadoc",
|
||||
).map { (packaging, classifier) ->
|
||||
workDir.resolve(coordinates.getFileName(classifier = classifier, packaging = packaging)).createFile().apply {
|
||||
MavenCoordinates("org.jetbrains", "bar", "1.0"),
|
||||
MavenCoordinates("org.jetbrains", "foo", "2.0"),
|
||||
).flatMap { coordinates ->
|
||||
sequenceOf(
|
||||
"pom" to "",
|
||||
"jar" to "",
|
||||
"jar" to "sources",
|
||||
"jar" to "javadoc",
|
||||
).map { (packaging, classifier) ->
|
||||
val name = coordinates.getFileName(classifier = classifier, packaging = packaging)
|
||||
val zipPath = "${coordinates.directoryPath}/$name"
|
||||
val file = workDir.resolve(if (flatLayout) name else zipPath).createFile()
|
||||
if (packaging == "pom") {
|
||||
writeText(
|
||||
file.writeText(
|
||||
"""
|
||||
<project>
|
||||
<groupId>${coordinates.groupId}</groupId>
|
||||
<artifactId>${coordinates.artifactId}</artifactId>
|
||||
<version>${coordinates.version}</version>
|
||||
</project>
|
||||
""".trimIndent()
|
||||
<project>
|
||||
<groupId>${coordinates.groupId}</groupId>
|
||||
<artifactId>${coordinates.artifactId}</artifactId>
|
||||
<version>${coordinates.version}</version>
|
||||
</project>
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
Result(file, zipPath = zipPath)
|
||||
}
|
||||
}.toList()
|
||||
}
|
||||
@@ -68,9 +77,33 @@ class MavenCentralPublicationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should generate a bundle zip`() {
|
||||
fun `should generate a bundle zip for artifacts`() {
|
||||
runBlocking {
|
||||
val files = createDistributionFiles().map { "${coordinates.directoryPath}/${it.name}" }
|
||||
val files = createDistributionFiles().map { it.zipPath }
|
||||
publication.execute()
|
||||
val bundle = workDir.resolve("bundle.zip")
|
||||
assertThat(bundle).exists()
|
||||
val entries = buildList {
|
||||
suspendAwareReadZipFile(bundle) { entry, _ ->
|
||||
add(entry)
|
||||
}
|
||||
}.sorted()
|
||||
Assertions.assertEquals(
|
||||
files.asSequence()
|
||||
.plus(files.asSequence().map { "$it.sha1" })
|
||||
.plus(files.asSequence().map { "$it.sha256" })
|
||||
.plus(files.asSequence().map { "$it.sha512" })
|
||||
.plus(files.asSequence().map { "$it.md5" })
|
||||
.sorted().toList(),
|
||||
entries,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should generate a bundle zip for flat artifacts layout`() {
|
||||
runBlocking {
|
||||
val files = createDistributionFiles(flatLayout = true).map { it.zipPath }
|
||||
publication.execute()
|
||||
val bundle = workDir.resolve("bundle.zip")
|
||||
assert(bundle.exists())
|
||||
@@ -78,19 +111,23 @@ class MavenCentralPublicationTest {
|
||||
suspendAwareReadZipFile(bundle) { entry, _ ->
|
||||
add(entry)
|
||||
}
|
||||
}
|
||||
assert(entries.containsAll(files))
|
||||
assert(entries.containsAll(files.map { "$it.sha1" }))
|
||||
assert(entries.containsAll(files.map { "$it.sha256" }))
|
||||
assert(entries.containsAll(files.map { "$it.sha512" }))
|
||||
assert(entries.containsAll(files.map { "$it.md5" }))
|
||||
}.sorted()
|
||||
Assertions.assertEquals(
|
||||
files.asSequence()
|
||||
.plus(files.asSequence().map { "$it.sha1" })
|
||||
.plus(files.asSequence().map { "$it.sha256" })
|
||||
.plus(files.asSequence().map { "$it.sha512" })
|
||||
.plus(files.asSequence().map { "$it.md5" })
|
||||
.sorted().toList(),
|
||||
entries,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should fail upon an invalid input checksum`() {
|
||||
runBlocking {
|
||||
val files = createDistributionFiles()
|
||||
val files = createDistributionFiles().map { it.workDirPath }
|
||||
val malformedChecksum = files.first()
|
||||
.resolveSibling("${files.first().fileName}.sha1")
|
||||
.createFile()
|
||||
|
||||
Reference in New Issue
Block a user