aboutsummaryrefslogtreecommitdiff
path: root/buildSrc/src
diff options
context:
space:
mode:
Diffstat (limited to 'buildSrc/src')
-rw-r--r--buildSrc/src/main/groovy/org/jetbrains/CorrectShadowPublishing.groovy40
-rw-r--r--buildSrc/src/main/groovy/org/jetbrains/CrossPlatformExec.groovy84
-rw-r--r--buildSrc/src/main/groovy/org/jetbrains/DependenciesVersionGetter.groovy14
-rw-r--r--buildSrc/src/main/groovy/org/jetbrains/PluginXmlTransformer.groovy71
-rw-r--r--buildSrc/src/main/kotlin/org/jetbrains/CrossPlatformExec.kt63
-rw-r--r--buildSrc/src/main/kotlin/org/jetbrains/DokkaVersion.kt26
-rw-r--r--buildSrc/src/main/kotlin/org/jetbrains/SetupMaven.kt48
-rw-r--r--buildSrc/src/main/kotlin/org/jetbrains/ValidatePublications.kt79
-rw-r--r--buildSrc/src/main/kotlin/org/jetbrains/projectUtils.kt16
-rw-r--r--buildSrc/src/main/kotlin/org/jetbrains/publication.kt61
-rw-r--r--buildSrc/src/main/kotlin/org/jetbrains/taskUtils.kt13
11 files changed, 306 insertions, 209 deletions
diff --git a/buildSrc/src/main/groovy/org/jetbrains/CorrectShadowPublishing.groovy b/buildSrc/src/main/groovy/org/jetbrains/CorrectShadowPublishing.groovy
deleted file mode 100644
index 62cc3d3c..00000000
--- a/buildSrc/src/main/groovy/org/jetbrains/CorrectShadowPublishing.groovy
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.jetbrains
-
-import org.gradle.api.Project
-import org.gradle.api.artifacts.ModuleVersionIdentifier
-import org.gradle.api.artifacts.ProjectDependency
-import org.gradle.api.artifacts.SelfResolvingDependency
-import org.gradle.api.internal.artifacts.ivyservice.projectmodule.ProjectDependencyPublicationResolver
-import org.gradle.api.publish.maven.MavenPom
-import org.gradle.api.publish.maven.MavenPublication
-
-//https://github.com/johnrengelman/shadow/issues/334
-static void configure(MavenPublication publication, Project project) {
- publication.artifact(project.tasks.shadowJar)
-
-
- publication.pom { MavenPom pom ->
- pom.withXml { xml ->
- def dependenciesNode = xml.asNode().appendNode('dependencies')
-
- project.configurations.shadow.allDependencies.each {
- if (it instanceof ProjectDependency) {
- final ProjectDependencyPublicationResolver projectDependencyResolver = project.gradle.services.get(ProjectDependencyPublicationResolver)
- final ModuleVersionIdentifier identifier = projectDependencyResolver.resolve(ModuleVersionIdentifier, it)
- addDependency(dependenciesNode, identifier)
- } else if (!(it instanceof SelfResolvingDependency)) {
- addDependency(dependenciesNode, it)
- }
-
- }
- }
- }
-}
-
-private static void addDependency(Node dependenciesNode, dep) {
- def dependencyNode = dependenciesNode.appendNode('dependency')
- dependencyNode.appendNode('groupId', dep.group)
- dependencyNode.appendNode('artifactId', dep.name)
- dependencyNode.appendNode('version', dep.version)
- dependencyNode.appendNode('scope', 'compile')
-}
diff --git a/buildSrc/src/main/groovy/org/jetbrains/CrossPlatformExec.groovy b/buildSrc/src/main/groovy/org/jetbrains/CrossPlatformExec.groovy
deleted file mode 100644
index d3973a8a..00000000
--- a/buildSrc/src/main/groovy/org/jetbrains/CrossPlatformExec.groovy
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.jetbrains
-
-import org.gradle.api.tasks.AbstractExecTask
-import org.gradle.api.tasks.TaskAction
-import org.gradle.internal.os.OperatingSystem
-
-import java.nio.file.Files
-import java.nio.file.Path
-import java.nio.file.Paths
-
-class CrossPlatformExec extends AbstractExecTask {
- private static final def windowsExtensions = ['bat', 'cmd', 'exe'];
- private static final def unixExtensions = [null, 'sh'];
-
- private boolean windows;
-
- public CrossPlatformExec() {
- super(CrossPlatformExec.class);
- windows = OperatingSystem.current().windows;
- }
-
- @Override
- @TaskAction
- protected void exec() {
- List<String> commandLine = this.getCommandLine();
-
- if (!commandLine.isEmpty()) {
- commandLine[0] = findCommand(commandLine[0], windows);
- }
-
- if (windows) {
- if (!commandLine.isEmpty() && commandLine[0]) {
- commandLine
- }
- commandLine.add(0, '/c');
- commandLine.add(0, 'cmd');
- }
-
- this.setCommandLine(commandLine);
-
- super.exec();
- }
-
- private static String findCommand(String command, boolean windows) {
- command = normalizeCommandPaths(command);
- def extensions = windows ? windowsExtensions : unixExtensions;
-
- return extensions.findResult(command) { extension ->
- Path commandFile
- if (extension) {
- commandFile = Paths.get(command + '.' + extension);
- } else {
- commandFile = Paths.get(command);
- }
-
- return resolveCommandFromFile(commandFile, windows);
- };
- }
-
- private static String resolveCommandFromFile(Path commandFile, boolean windows) {
- if (!Files.isExecutable(commandFile)) {
- return null;
- }
-
- return commandFile.toAbsolutePath().normalize();
- }
-
- private static String normalizeCommandPaths(String command) {
- // need to escape backslash so it works with regex
- String backslashSeparator = '\\\\';
-
- String forwardSlashSeparator = '/';
-
- // escape separator if it's a backslash
- char backslash = '\\';
- String separator = File.separatorChar == backslash ? backslashSeparator : File.separator
-
- return command
- // first replace all of the backslashes with forward slashes
- .replaceAll(backslashSeparator, forwardSlashSeparator)
- // then replace all forward slashes with whatever the separator actually is
- .replaceAll(forwardSlashSeparator, separator);
- }
-} \ No newline at end of file
diff --git a/buildSrc/src/main/groovy/org/jetbrains/DependenciesVersionGetter.groovy b/buildSrc/src/main/groovy/org/jetbrains/DependenciesVersionGetter.groovy
deleted file mode 100644
index 194f11af..00000000
--- a/buildSrc/src/main/groovy/org/jetbrains/DependenciesVersionGetter.groovy
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.jetbrains
-
-import org.gradle.api.Project
-
-class DependenciesVersionGetter {
- static Properties getVersions(Project project, String artifactVersionSelector) {
- def dep = project.dependencies.create(group: 'teamcity', name: 'dependencies', version: artifactVersionSelector, ext: 'properties')
- def file = project.configurations.detachedConfiguration(dep).resolve().first()
-
- def prop = new Properties()
- prop.load(new FileReader(file))
- return prop
- }
-}
diff --git a/buildSrc/src/main/groovy/org/jetbrains/PluginXmlTransformer.groovy b/buildSrc/src/main/groovy/org/jetbrains/PluginXmlTransformer.groovy
deleted file mode 100644
index e711388f..00000000
--- a/buildSrc/src/main/groovy/org/jetbrains/PluginXmlTransformer.groovy
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.jetbrains
-
-import com.github.jengelman.gradle.plugins.shadow.relocation.RelocateClassContext
-import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator
-import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer
-import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
-import groovy.xml.XmlUtil
-import org.gradle.api.file.FileTreeElement
-import shadow.org.apache.tools.zip.ZipEntry
-import shadow.org.apache.tools.zip.ZipOutputStream
-
-public class PluginXmlTransformer implements Transformer {
- private Map<String, Node> transformedPluginXmlFiles = new HashMap<>();
-
- @Override
- boolean canTransformResource(FileTreeElement fileTreeElement) {
- return fileTreeElement.relativePath.segments.contains("META-INF") && fileTreeElement.name.endsWith(".xml")
- }
-
- @Override
- void transform(TransformerContext context) {
- def path = context.path
- def inputStream = context.is
- System.out.println(path)
- Node node = new XmlParser().parse(inputStream)
- relocateXml(node, context)
- transformedPluginXmlFiles.put(path, node)
- }
-
- @Override
- boolean hasTransformedResource() {
- return !transformedPluginXmlFiles.isEmpty()
- }
-
- @Override
- void modifyOutputStream(ZipOutputStream zipOutputStream) {
- for (Map.Entry<String, Node> entry : transformedPluginXmlFiles.entrySet()) {
- zipOutputStream.putNextEntry(new ZipEntry(entry.key))
- XmlUtil.serialize(entry.value, zipOutputStream)
- }
- }
-
- private static void relocateXml(Node node, TransformerContext context) {
- Map attributes = node.attributes()
- RelocateClassContext relocateClassContext = new RelocateClassContext()
- relocateClassContext.stats = context.stats
- for (Map.Entry entry : attributes.entrySet()) {
- relocateClassContext.setClassName((String) entry.getValue())
- entry.setValue(relocateClassName(relocateClassContext, context))
- }
- List<String> localText = node.localText()
- if (localText.size() == 1) {
- relocateClassContext.setClassName(localText[0])
- node.setValue(relocateClassName(relocateClassContext, context))
- }
- node.children().each {
- if (it instanceof Node) {
- relocateXml((Node) it, context)
- }
- }
- }
-
- private static String relocateClassName(RelocateClassContext relocateContext, TransformerContext context) {
- for (Relocator relocator : context.relocators) {
- if (relocator.canRelocateClass(relocateContext)) {
- return relocator.relocateClass(relocateContext)
- }
- }
- return relocateContext.className
- }
-} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/org/jetbrains/CrossPlatformExec.kt b/buildSrc/src/main/kotlin/org/jetbrains/CrossPlatformExec.kt
new file mode 100644
index 00000000..e02bdd61
--- /dev/null
+++ b/buildSrc/src/main/kotlin/org/jetbrains/CrossPlatformExec.kt
@@ -0,0 +1,63 @@
+package org.jetbrains
+
+import org.gradle.api.tasks.AbstractExecTask
+import org.gradle.internal.os.OperatingSystem
+import java.io.File
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.Paths
+
+open class CrossPlatformExec : AbstractExecTask<CrossPlatformExec>(CrossPlatformExec::class.java) {
+ private val windowsExtensions = listOf(".bat", ".cmd", ".exe")
+ private val unixExtensions = listOf("", ".sh")
+
+ private val isWindows = OperatingSystem.current().isWindows
+
+ override fun exec() {
+ val commandLine: MutableList<String> = this.commandLine
+
+ if (commandLine.isNotEmpty()) {
+ commandLine[0] = findCommand(commandLine[0])
+ }
+
+ if (isWindows && commandLine.isNotEmpty() && commandLine[0].isNotBlank()) {
+ this.commandLine = listOf("cmd", "/c") + commandLine
+ } else {
+ this.commandLine = commandLine
+ }
+
+ super.exec()
+ }
+
+ private fun findCommand(command: String): String {
+ val command = normalizeCommandPaths(command)
+ val extensions = if (isWindows) windowsExtensions else unixExtensions
+
+ return extensions.map { extension ->
+ resolveCommandFromFile(Paths.get("$command$extension"))
+ }.firstOrNull { it.isNotBlank() } ?: command
+ }
+
+ private fun resolveCommandFromFile(commandFile: Path) =
+ if (!Files.isExecutable(commandFile)) {
+ ""
+ } else {
+ commandFile.toAbsolutePath().normalize().toString()
+ }
+
+
+ private fun normalizeCommandPaths(command: String): String {
+ // need to escape backslash so it works with regex
+ val backslashSeparator = "\\"
+ val forwardSlashSeparator = "/"
+
+ // get the actual separator
+ val separator = if (File.separatorChar == '\\') backslashSeparator else File.separator
+
+ return command
+ // first replace all of the backslashes with forward slashes
+ .replace(backslashSeparator, forwardSlashSeparator)
+ // then replace all forward slashes with whatever the separator actually is
+ .replace(forwardSlashSeparator, separator)
+ }
+} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/org/jetbrains/DokkaVersion.kt b/buildSrc/src/main/kotlin/org/jetbrains/DokkaVersion.kt
new file mode 100644
index 00000000..2a5c21a7
--- /dev/null
+++ b/buildSrc/src/main/kotlin/org/jetbrains/DokkaVersion.kt
@@ -0,0 +1,26 @@
+package org.jetbrains
+
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.extra
+import org.gradle.kotlin.dsl.provideDelegate
+
+fun Project.configureDokkaVersion(): String {
+ var dokka_version: String? by this.extra
+ if (dokka_version == null) {
+ val dokka_version_base: String by this
+ dokka_version = dokkaVersionFromBase(dokka_version_base)
+ }
+ return checkNotNull(dokka_version)
+}
+
+private fun dokkaVersionFromBase(baseVersion: String): String {
+ val buildNumber = System.getenv("BUILD_NUMBER")
+ val forceSnapshot = System.getenv("FORCE_SNAPSHOT") != null
+ if (forceSnapshot || buildNumber == null) {
+ return "$baseVersion-SNAPSHOT"
+ }
+ return "$baseVersion-$buildNumber"
+}
+
+val Project.dokkaVersion: String
+ get() = configureDokkaVersion()
diff --git a/buildSrc/src/main/kotlin/org/jetbrains/SetupMaven.kt b/buildSrc/src/main/kotlin/org/jetbrains/SetupMaven.kt
new file mode 100644
index 00000000..4ef26a73
--- /dev/null
+++ b/buildSrc/src/main/kotlin/org/jetbrains/SetupMaven.kt
@@ -0,0 +1,48 @@
+package org.jetbrains
+
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.Sync
+import org.gradle.kotlin.dsl.creating
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getValue
+import java.io.File
+
+@Suppress("LeakingThis")
+open class SetupMaven : Sync() {
+ @get:Input
+ var mavenVersion = "3.5.0"
+
+ @get:Input
+ var mavenPluginToolsVersion = "3.5.2"
+
+ @get:Input
+ var aetherVersion = "1.1.0"
+
+ @get:Internal
+ val mavenBuildDir = "${project.buildDir}/maven"
+
+ @get:Internal
+ val mavenBinDir = "${project.buildDir}/maven-bin"
+
+ @get:Internal
+ val mvn = File(mavenBinDir, "apache-maven-$mavenVersion/bin/mvn")
+
+ private val mavenBinaryConfiguration: Configuration by project.configurations.creating {
+ project.dependencies {
+ this@creating.invoke(
+ group = "org.apache.maven",
+ name = "apache-maven",
+ version = mavenVersion,
+ classifier = "bin", ext = "zip"
+ )
+ }
+ }
+
+ init {
+ from(mavenBinaryConfiguration.map { file -> project.zipTree(file) })
+ into(mavenBinDir)
+ }
+
+}
diff --git a/buildSrc/src/main/kotlin/org/jetbrains/ValidatePublications.kt b/buildSrc/src/main/kotlin/org/jetbrains/ValidatePublications.kt
new file mode 100644
index 00000000..84c48b96
--- /dev/null
+++ b/buildSrc/src/main/kotlin/org/jetbrains/ValidatePublications.kt
@@ -0,0 +1,79 @@
+package org.jetbrains
+
+import com.jfrog.bintray.gradle.BintrayExtension
+import org.gradle.api.DefaultTask
+import org.gradle.api.GradleException
+import org.gradle.api.Project
+import org.gradle.api.artifacts.ProjectDependency
+import org.gradle.api.publish.PublishingExtension
+import org.gradle.api.publish.maven.MavenPublication
+import org.gradle.api.tasks.TaskAction
+import org.gradle.kotlin.dsl.findByType
+import org.gradle.kotlin.dsl.provideDelegate
+
+open class ValidatePublications : DefaultTask() {
+ class MissingBintrayPublicationException(project: Project, publication: MavenPublication) : GradleException(
+ "Project ${project.path} has publication ${publication.name} that is not configured for bintray publication"
+ )
+
+ class UnpublishedProjectDependencyException(
+ project: Project, dependencyProject: Project
+ ) : GradleException(
+ "Published project ${project.path} cannot depend on unpublished projed ${dependencyProject.path}"
+ )
+
+
+ @TaskAction
+ fun validatePublicationConfiguration() {
+ @Suppress("LocalVariableName")
+ project.subprojects.forEach { subProject ->
+ val publishing = subProject.extensions.findByType<PublishingExtension>() ?: return@forEach
+ publishing.publications
+ .filterIsInstance<MavenPublication>()
+ .filter { it.version == project.dokkaVersion }
+ .forEach { publication ->
+ checkPublicationIsConfiguredForBintray(subProject, publication)
+ checkProjectDependenciesArePublished(subProject)
+ }
+ }
+ }
+
+ private fun checkPublicationIsConfiguredForBintray(project: Project, publication: MavenPublication) {
+ val bintrayExtension = project.extensions.findByType<BintrayExtension>()
+ ?: throw MissingBintrayPublicationException(project, publication)
+
+ val isPublicationConfiguredForBintray = bintrayExtension.publications.orEmpty()
+ .any { publicationName -> publicationName == publication.name }
+
+ if (!isPublicationConfiguredForBintray) {
+ throw MissingBintrayPublicationException(project, publication)
+ }
+ }
+
+ private fun checkProjectDependenciesArePublished(project: Project) {
+ (project.configurations.findByName("implementation")?.allDependencies.orEmpty() +
+ project.configurations.findByName("api")?.allDependencies.orEmpty())
+ .filterIsInstance<ProjectDependency>()
+ .forEach { projectDependency ->
+ val publishing = projectDependency.dependencyProject.extensions.findByType<PublishingExtension>()
+ ?: throw UnpublishedProjectDependencyException(
+ project = project, dependencyProject = projectDependency.dependencyProject
+ )
+
+ val isPublished = publishing.publications.filterIsInstance<MavenPublication>()
+ .filter { it.version == project.dokkaVersion }
+ .any()
+
+ if (!isPublished) {
+ throw UnpublishedProjectDependencyException(project, projectDependency.dependencyProject)
+ }
+ }
+ }
+
+ init {
+ group = "verification"
+ project.tasks.named("check") {
+ dependsOn(this@ValidatePublications)
+ }
+ }
+}
diff --git a/buildSrc/src/main/kotlin/org/jetbrains/projectUtils.kt b/buildSrc/src/main/kotlin/org/jetbrains/projectUtils.kt
new file mode 100644
index 00000000..46d803a5
--- /dev/null
+++ b/buildSrc/src/main/kotlin/org/jetbrains/projectUtils.kt
@@ -0,0 +1,16 @@
+package org.jetbrains
+
+import org.gradle.api.Project
+
+fun Project.whenEvaluated(action: Project.() -> Unit) {
+ if (state.executed) {
+ action()
+ } else {
+ afterEvaluate { action() }
+ }
+}
+
+fun Project.invokeWhenEvaluated(action: (project: Project) -> Unit) {
+ whenEvaluated { action(this) }
+}
+
diff --git a/buildSrc/src/main/kotlin/org/jetbrains/publication.kt b/buildSrc/src/main/kotlin/org/jetbrains/publication.kt
new file mode 100644
index 00000000..289bd117
--- /dev/null
+++ b/buildSrc/src/main/kotlin/org/jetbrains/publication.kt
@@ -0,0 +1,61 @@
+package org.jetbrains
+
+import com.github.jengelman.gradle.plugins.shadow.ShadowExtension
+import com.jfrog.bintray.gradle.BintrayExtension
+import org.gradle.api.Project
+import org.gradle.api.publish.PublishingExtension
+import org.gradle.api.publish.maven.MavenPublication
+import org.gradle.kotlin.dsl.*
+
+class DokkaPublicationBuilder {
+ enum class Component {
+ Java, Shadow
+ }
+
+ var artifactId: String? = null
+ var component: Component = Component.Java
+}
+
+fun Project.registerDokkaArtifactPublication(publicationName: String, configure: DokkaPublicationBuilder.() -> Unit) {
+ configure<PublishingExtension> {
+ publications {
+ register<MavenPublication>(publicationName) {
+ val builder = DokkaPublicationBuilder().apply(configure)
+ this.artifactId = builder.artifactId
+ when (builder.component) {
+ DokkaPublicationBuilder.Component.Java -> from(components["java"])
+ DokkaPublicationBuilder.Component.Shadow -> run {
+ artifact(tasks["sourcesJar"])
+ extensions.getByType(ShadowExtension::class.java).component(this)
+ }
+ }
+ }
+ }
+ }
+
+ configureBintrayPublication(publicationName)
+}
+
+fun Project.configureBintrayPublication(vararg publications: String) {
+ val dokka_version: String by this
+ val dokka_publication_channel: String by this
+ extensions.configure<BintrayExtension>("bintray") {
+ user = System.getenv("BINTRAY_USER")
+ key = System.getenv("BINTRAY_KEY")
+ dryRun = System.getenv("BINTRAY_DRY_RUN") == "true" ||
+ project.properties["bintray_dry_run"] == "true"
+ pkg = PackageConfig().apply {
+ repo = dokka_publication_channel
+ name = "dokka"
+ userOrg = "kotlin"
+ desc = "Dokka, the Kotlin documentation tool"
+ vcsUrl = "https://github.com/kotlin/dokka.git"
+ setLicenses("Apache-2.0")
+ version = VersionConfig().apply {
+ name = dokka_version
+ }
+ }
+ setPublications(*publications)
+ }
+}
+
diff --git a/buildSrc/src/main/kotlin/org/jetbrains/taskUtils.kt b/buildSrc/src/main/kotlin/org/jetbrains/taskUtils.kt
new file mode 100644
index 00000000..ef9c5e6a
--- /dev/null
+++ b/buildSrc/src/main/kotlin/org/jetbrains/taskUtils.kt
@@ -0,0 +1,13 @@
+package org.jetbrains
+
+import org.gradle.api.Task
+
+fun Task.dependsOnMavenLocalPublication() {
+ project.rootProject.allprojects.forEach { otherProject ->
+ otherProject.invokeWhenEvaluated { evaluatedProject ->
+ evaluatedProject.tasks.findByName("publishToMavenLocal")?.let { publishingTask ->
+ this.dependsOn(publishingTask)
+ }
+ }
+ }
+}