diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/IntellijModulesPreview.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/IntellijModulesPreview.groovy
new file mode 100644
index 000000000000..9f51681c6f8b
--- /dev/null
+++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/IntellijModulesPreview.groovy
@@ -0,0 +1,124 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package org.jetbrains.intellij.build.impl
+
+
+import groovy.transform.CompileStatic
+import org.jetbrains.intellij.build.BuildContext
+import org.jetbrains.jps.model.module.JpsModule
+import org.jetbrains.jps.model.module.JpsModuleDependency
+
+/**
+ * Publishes specified nightly versions of Intellij modules as a Maven artifacts using the output of {@link org.jetbrains.intellij.build.impl.MavenArtifactsBuilder}.
+ *
+ *
+ * Note: Requires installed `mvn`.
+ *
+ */
+@CompileStatic
+@SuppressWarnings("unused")
+class IntellijModulesPreview {
+ private final BuildContext buildContext
+ private final int uploadRetryCount = 3
+ private final String repositoryId
+ private final String repositoryUrl
+ private final File mavenSettings
+
+ IntellijModulesPreview(BuildContext context) {
+ buildContext = context
+ repositoryId = require('repository.id')
+ repositoryUrl = "${require('repository.publicationUrl')}/;publish=1;"
+ mavenSettings = settingsXml()
+ }
+
+ private String require(String property) {
+ System.getProperty(property) ?: buildContext.messages.error("$property is not specifed")
+ }
+
+ /**
+ * @param modulesOutputDir output of {@link org.jetbrains.intellij.build.impl.MavenArtifactsBuilder}
+ */
+ void publish(List modulesToPublish, File modulesOutputDir) {
+ def modules = new HashSet()
+ modulesToPublish.each {
+ def module = buildContext.findRequiredModule(it)
+ modules << module
+ transitiveModuleDependencies(module, modules)
+ }
+ modules.each {
+ def coordinates = MavenArtifactsBuilder.generateMavenCoordinates(
+ it.name, buildContext.messages, buildContext.buildNumber
+ )
+ def dir = new File(modulesOutputDir, coordinates.directoryPath)
+ def pom = new File(dir, coordinates.getFileName('', 'pom'))
+ def jar = new File(dir, coordinates.getFileName('', 'jar'))
+ def sources = new File(dir, coordinates.getFileName('sources', 'jar'))
+ deployJar(jar, pom)
+ if (sources.exists()) {
+ deploySources(sources, coordinates)
+ }
+ }
+ }
+
+ private def transitiveModuleDependencies(JpsModule module, Collection result) {
+ MavenArtifactsBuilder.scopedDependencies(module)
+ .findAll { it.key instanceof JpsModuleDependency }
+ .each {
+ def dependencyModule = (it.key as JpsModuleDependency).module
+ if (!result.contains(dependencyModule)) {
+ result << dependencyModule
+ transitiveModuleDependencies(dependencyModule, result)
+ }
+ }
+ }
+
+ private def deployJar(File jar, File pom) {
+ deployFile(jar, ["-DpomFile=$pom.absolutePath"])
+ }
+
+ private def deploySources(File sources, MavenArtifactsBuilder.MavenCoordinates coordinates) {
+ deployFile(sources, [
+ "-DgroupId=$coordinates.groupId",
+ "-DartifactId=$coordinates.artifactId",
+ "-Dversion=$coordinates.version",
+ '-Dpackaging=java-source',
+ '-DgeneratePom=false'
+ ])
+ }
+
+ private def deployFile(File file, Collection args) {
+ buildContext.messages.info("Upload of $file.name")
+ def process = ([
+ 'mvn', '--settings', mavenSettings.absolutePath,
+ 'deploy:deploy-file',
+ "-Dfile=$file.absolutePath",
+ "-DrepositoryId=$repositoryId",
+ "-Durl=$repositoryUrl",
+ "-DretryFailedDeploymentCount=$uploadRetryCount"
+ ] + args).execute()
+ def output = process.text
+ def exitCode = process.waitFor()
+ if (exitCode != 0) {
+ buildContext.messages.error("Upload of $file.name failed with exit code $exitCode: $output")
+ }
+ }
+
+ private File settingsXml() {
+ File.createTempFile('settings', '.xml').with {
+ it << """
+
+
+ $repositoryId
+ ${require('repository.user')}
+ ${require('repository.password')}
+
+
+
+ """.stripIndent()
+ it.deleteOnExit()
+ it
+ }
+ }
+}
diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/MavenArtifactsBuilder.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/MavenArtifactsBuilder.groovy
index 711a72282b09..d4869dfb1ccf 100644
--- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/MavenArtifactsBuilder.groovy
+++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/MavenArtifactsBuilder.groovy
@@ -19,6 +19,7 @@ import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.library.JpsLibrary
import org.jetbrains.jps.model.library.JpsMavenRepositoryLibraryDescriptor
import org.jetbrains.jps.model.library.JpsRepositoryLibraryType
+import org.jetbrains.jps.model.module.JpsDependencyElement
import org.jetbrains.jps.model.module.JpsLibraryDependency
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.model.module.JpsModuleDependency
@@ -176,23 +177,10 @@ class MavenArtifactsBuilder {
return results
}
- private MavenArtifactData generateMavenArtifactData(JpsModule module, Map results, Set nonMavenizableModules,
- Set computationInProgress) {
- if (results.containsKey(module)) return results[module]
- if (nonMavenizableModules.contains(module)) return null
- if (!module.name.startsWith("intellij.")) {
- buildContext.messages.debug(" module '$module.name' doesn't belong to IntelliJ project so it cannot be published")
- return null
- }
- def scrambleTool = buildContext.proprietaryBuildTools.scrambleTool
- if (scrambleTool != null && scrambleTool.namesOfModulesRequiredToBeScrambled.contains(module.name)) {
- buildContext.messages.debug(" module '$module.name' must be scrambled so it cannot be published")
- return null
- }
+ enum DependencyScope { COMPILE, RUNTIME }
- boolean mavenizable = true
- computationInProgress << module
- List dependencies = []
+ static Map scopedDependencies(JpsModule module) {
+ Map result = [:]
module.dependenciesList.dependencies.each { dependency ->
def extension = JpsJavaExtensionService.getInstance().getDependencyExtension(dependency)
if (extension == null) return
@@ -213,7 +201,29 @@ class MavenArtifactsBuilder {
default:
return
}
+ result[dependency] = scope
+ }
+ return result
+ }
+ private MavenArtifactData generateMavenArtifactData(JpsModule module, Map results, Set nonMavenizableModules,
+ Set computationInProgress) {
+ if (results.containsKey(module)) return results[module]
+ if (nonMavenizableModules.contains(module)) return null
+ if (!module.name.startsWith("intellij.")) {
+ buildContext.messages.debug(" module '$module.name' doesn't belong to IntelliJ project so it cannot be published")
+ return null
+ }
+ def scrambleTool = buildContext.proprietaryBuildTools.scrambleTool
+ if (scrambleTool != null && scrambleTool.namesOfModulesRequiredToBeScrambled.contains(module.name)) {
+ buildContext.messages.debug(" module '$module.name' must be scrambled so it cannot be published")
+ return null
+ }
+
+ boolean mavenizable = true
+ computationInProgress << module
+ List dependencies = []
+ scopedDependencies(module).each { dependency, scope ->
if (dependency instanceof JpsModuleDependency) {
def depModule = (dependency as JpsModuleDependency).module
if (computationInProgress.contains(depModule)) {
@@ -281,8 +291,6 @@ class MavenArtifactsBuilder {
List dependencies
}
- private enum DependencyScope { COMPILE, RUNTIME }
-
@Immutable
private static class MavenArtifactDependency {
MavenCoordinates coordinates