mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -150,16 +150,21 @@ public class AppMainV2 {
|
||||
|
||||
public static class Agent {
|
||||
public static void premain(String args, Instrumentation i) {
|
||||
try {
|
||||
int p = args.indexOf(':');
|
||||
if (p < 0) throw new IllegalArgumentException("incorrect parameter: " + args);
|
||||
boolean helperLibLoaded = loadHelper(args.substring(p + 1));
|
||||
int portNumber = Integer.parseInt(args.substring(0, p));
|
||||
startMonitor(portNumber, helperLibLoaded);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
System.err.println("Launcher failed - \"Dump Threads\" and \"Exit\" actions are unavailable (" + t.getMessage() + ')');
|
||||
}
|
||||
AppMainV2.premain(args);
|
||||
}
|
||||
}
|
||||
|
||||
// todo[r.sh] inline some time after 2017.1.1 release
|
||||
public static void premain(String args) {
|
||||
try {
|
||||
int p = args.indexOf(':');
|
||||
if (p < 0) throw new IllegalArgumentException("incorrect parameter: " + args);
|
||||
boolean helperLibLoaded = loadHelper(args.substring(p + 1));
|
||||
int portNumber = Integer.parseInt(args.substring(0, p));
|
||||
startMonitor(portNumber, helperLibLoaded);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
System.err.println("Launcher failed - \"Dump Threads\" and \"Exit\" actions are unavailable (" + t.getMessage() + ')');
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
-4
@@ -32,10 +32,8 @@ import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.DataOutputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CompilerBackwardReferenceIndex {
|
||||
private final static Logger LOG = Logger.getInstance(CompilerBackwardReferenceIndex.class);
|
||||
@@ -48,6 +46,7 @@ public class CompilerBackwardReferenceIndex {
|
||||
private final NameEnumerator myNameEnumerator;
|
||||
private final PersistentStringEnumerator myFilePathEnumerator;
|
||||
private final File myIndicesDir;
|
||||
private final boolean myReadOnly;
|
||||
private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -67,6 +66,7 @@ public class CompilerBackwardReferenceIndex {
|
||||
|
||||
public CompilerBackwardReferenceIndex(File buildDir, boolean readOnly) {
|
||||
myIndicesDir = getIndexDir(buildDir);
|
||||
myReadOnly = readOnly;
|
||||
if (!myIndicesDir.exists() && !myIndicesDir.mkdirs()) {
|
||||
throw new RuntimeException("Can't create dir: " + buildDir.getAbsolutePath());
|
||||
}
|
||||
@@ -74,6 +74,8 @@ public class CompilerBackwardReferenceIndex {
|
||||
if (versionDiffers(buildDir)) {
|
||||
saveVersion(buildDir);
|
||||
}
|
||||
if (myReadOnly) logModification("open");
|
||||
|
||||
myFilePathEnumerator = new PersistentStringEnumerator(new File(myIndicesDir, FILE_ENUM_TAB)) {
|
||||
@Override
|
||||
public int enumerate(@Nullable String value) throws IOException {
|
||||
@@ -123,6 +125,7 @@ public class CompilerBackwardReferenceIndex {
|
||||
for (InvertedIndex<?, ?, CompiledFileData> index : myIndices.values()) {
|
||||
close(index, exceptionProc);
|
||||
}
|
||||
if (myReadOnly) logModification("close");
|
||||
final Exception exception = exceptionProc.getFoundValue();
|
||||
if (exception != null) {
|
||||
removeIndexFiles(myIndicesDir);
|
||||
@@ -199,6 +202,20 @@ public class CompilerBackwardReferenceIndex {
|
||||
myRebuildRequestCause = e;
|
||||
}
|
||||
|
||||
private void logModification(String state) {
|
||||
try {
|
||||
File[] files = myIndicesDir.listFiles();
|
||||
if (files != null) {
|
||||
LOG.info("indices state on " +
|
||||
state +
|
||||
": " +
|
||||
Arrays.stream(files).map(f -> f.getName() + ":" + f.lastModified()).collect(Collectors.joining(", ")));
|
||||
}
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static void close(InvertedIndex<?, ?, CompiledFileData> index, CommonProcessors.FindFirstProcessor<Exception> exceptionProcessor) {
|
||||
try {
|
||||
index.dispose();
|
||||
|
||||
@@ -27,19 +27,13 @@ import org.jetbrains.jps.model.module.JpsModule
|
||||
* @author nik
|
||||
*/
|
||||
@CompileStatic
|
||||
abstract class BuildContext {
|
||||
AntBuilder ant
|
||||
BuildMessages messages
|
||||
BuildPaths paths
|
||||
JpsProject project
|
||||
abstract class BuildContext implements CompilationContext {
|
||||
ApplicationInfoProperties applicationInfo
|
||||
JpsGantProjectBuilder projectBuilder
|
||||
ProductProperties productProperties
|
||||
WindowsDistributionCustomizer windowsDistributionCustomizer
|
||||
LinuxDistributionCustomizer linuxDistributionCustomizer
|
||||
MacDistributionCustomizer macDistributionCustomizer
|
||||
ProprietaryBuildTools proprietaryBuildTools
|
||||
BuildOptions options
|
||||
BundledJreManager bundledJreManager
|
||||
|
||||
/**
|
||||
@@ -77,14 +71,8 @@ abstract class BuildContext {
|
||||
|
||||
abstract void notifyArtifactBuilt(String artifactPath)
|
||||
|
||||
abstract File findApplicationInfoInSources()
|
||||
|
||||
abstract JpsModule findApplicationInfoModule()
|
||||
|
||||
abstract JpsModule findRequiredModule(String name)
|
||||
|
||||
abstract JpsModule findModule(String name)
|
||||
|
||||
abstract File findFileInModuleSources(String moduleName, String relativePath)
|
||||
|
||||
abstract void signExeFile(String path)
|
||||
@@ -115,78 +103,3 @@ abstract class BuildContext {
|
||||
|
||||
abstract BuildContext createCopyForProduct(ProductProperties productProperties, String projectHomeForCustomizers)
|
||||
}
|
||||
|
||||
/**
|
||||
* All paths are absolute and use '/' as a separator
|
||||
*/
|
||||
abstract class BuildPaths {
|
||||
/**
|
||||
* Path to a directory where idea/community Git repository is checked out
|
||||
*/
|
||||
String communityHome
|
||||
|
||||
/**
|
||||
* Path to a base directory of the project which will be compiled
|
||||
*/
|
||||
String projectHome
|
||||
|
||||
/**
|
||||
* Path to a directory where build script will store temporary and resulting files
|
||||
*/
|
||||
String buildOutputRoot
|
||||
|
||||
/**
|
||||
* Path to a directory where resulting artifacts will be placed
|
||||
*/
|
||||
String artifacts
|
||||
|
||||
/**
|
||||
* Path to a directory containing distribution files ('bin', 'lib', 'plugins' directories) common for all operating systems
|
||||
*/
|
||||
String distAll
|
||||
|
||||
/**
|
||||
* Path to a directory where temporary files required for a particular build step can be stored
|
||||
*/
|
||||
String temp
|
||||
|
||||
/**
|
||||
* Path to a directory containing JDK (currently Java 8) which is used to compile the project
|
||||
*/
|
||||
String jdkHome
|
||||
}
|
||||
|
||||
interface BuildMessages {
|
||||
void info(String message)
|
||||
void warning(String message)
|
||||
|
||||
/**
|
||||
* Report an error and stop the build process
|
||||
*/
|
||||
void error(String message)
|
||||
|
||||
void error(String message, Throwable cause)
|
||||
|
||||
void progress(String message)
|
||||
def <V> V block(String blockName, Closure<V> body)
|
||||
|
||||
void artifactBuild(String relativeArtifactPath)
|
||||
|
||||
BuildMessages forkForParallelTask(String taskName)
|
||||
|
||||
/**
|
||||
* Must be invoked from the main thread when all forks have been finished
|
||||
*/
|
||||
void onAllForksFinished()
|
||||
|
||||
/**
|
||||
* Must be invoked for the forked instance on the thread where it is executing before the task is started.
|
||||
* It's required to correctly handle messages from Ant tasks.
|
||||
*/
|
||||
void onForkStarted()
|
||||
|
||||
/**
|
||||
* Must be invoked for the forked instance on the thread where it is executing when the task is finished
|
||||
*/
|
||||
void onForkFinished()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.intellij.build
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
@CompileStatic
|
||||
interface BuildMessages {
|
||||
void info(String message)
|
||||
|
||||
void warning(String message)
|
||||
|
||||
/**
|
||||
* Report an error and stop the build process
|
||||
*/
|
||||
void error(String message)
|
||||
|
||||
void error(String message, Throwable cause)
|
||||
|
||||
void progress(String message)
|
||||
|
||||
def <V> V block(String blockName, Closure<V> body)
|
||||
|
||||
void artifactBuild(String relativeArtifactPath)
|
||||
|
||||
BuildMessages forkForParallelTask(String taskName)
|
||||
|
||||
/**
|
||||
* Must be invoked from the main thread when all forks have been finished
|
||||
*/
|
||||
void onAllForksFinished()
|
||||
|
||||
/**
|
||||
* Must be invoked for the forked instance on the thread where it is executing before the task is started.
|
||||
* It's required to correctly handle messages from Ant tasks.
|
||||
*/
|
||||
void onForkStarted()
|
||||
|
||||
/**
|
||||
* Must be invoked for the forked instance on the thread where it is executing when the task is finished
|
||||
*/
|
||||
void onForkFinished()
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.intellij.build
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
/**
|
||||
* All paths are absolute and use '/' as a separator
|
||||
*
|
||||
* @author nik
|
||||
*/
|
||||
@CompileStatic
|
||||
abstract class BuildPaths {
|
||||
/**
|
||||
* Path to a directory where idea/community Git repository is checked out
|
||||
*/
|
||||
String communityHome
|
||||
|
||||
/**
|
||||
* Path to a base directory of the project which will be compiled
|
||||
*/
|
||||
String projectHome
|
||||
|
||||
/**
|
||||
* Path to a directory where build script will store temporary and resulting files
|
||||
*/
|
||||
String buildOutputRoot
|
||||
|
||||
/**
|
||||
* Path to a directory where resulting artifacts will be placed
|
||||
*/
|
||||
String artifacts
|
||||
|
||||
/**
|
||||
* Path to a directory containing distribution files ('bin', 'lib', 'plugins' directories) common for all operating systems
|
||||
*/
|
||||
String distAll
|
||||
|
||||
/**
|
||||
* Path to a directory where temporary files required for a particular build step can be stored
|
||||
*/
|
||||
String temp
|
||||
|
||||
/**
|
||||
* Path to a directory containing JDK (currently Java 8) which is used to compile the project
|
||||
*/
|
||||
String jdkHome
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.intellij.build
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.jps.gant.JpsGantProjectBuilder
|
||||
import org.jetbrains.jps.model.JpsProject
|
||||
import org.jetbrains.jps.model.module.JpsModule
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
@CompileStatic
|
||||
interface CompilationContext {
|
||||
AntBuilder getAnt()
|
||||
BuildOptions getOptions()
|
||||
BuildMessages getMessages()
|
||||
BuildPaths getPaths()
|
||||
JpsProject getProject()
|
||||
JpsGantProjectBuilder getProjectBuilder()
|
||||
|
||||
JpsModule findRequiredModule(String name)
|
||||
|
||||
JpsModule findModule(String name)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.intellij.build
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.intellij.build.impl.CompilationTasksImpl
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
@CompileStatic
|
||||
abstract class CompilationTasks {
|
||||
abstract void compileAllModulesAndTests()
|
||||
|
||||
abstract void compileModules(List<String> moduleNames, List<String> includingTestsInModules = [])
|
||||
|
||||
static CompilationTasks create(CompilationContext context) {
|
||||
return new CompilationTasksImpl(context)
|
||||
}
|
||||
}
|
||||
+64
-164
@@ -26,11 +26,9 @@ import org.jetbrains.jps.model.JpsGlobal
|
||||
import org.jetbrains.jps.model.JpsProject
|
||||
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootProperties
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.jps.model.module.JpsModule
|
||||
import org.jetbrains.jps.model.serialization.JpsModelSerializationDataService
|
||||
import org.jetbrains.jps.model.serialization.JpsProjectLoader
|
||||
import org.jetbrains.jps.util.JpsPathUtil
|
||||
|
||||
import java.util.function.BiFunction
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
@@ -38,61 +36,38 @@ import org.jetbrains.jps.util.JpsPathUtil
|
||||
@CompileStatic
|
||||
class BuildContextImpl extends BuildContext {
|
||||
private final JpsGlobal global
|
||||
private final CompilationContextImpl compilationContext
|
||||
|
||||
static BuildContextImpl create(AntBuilder ant, JpsGantProjectBuilder projectBuilder, JpsProject project, JpsGlobal global,
|
||||
String communityHome, String projectHome, ProductProperties productProperties,
|
||||
ProprietaryBuildTools proprietaryBuildTools, BuildOptions options) {
|
||||
BuildMessages messages = BuildMessagesImpl.create(projectBuilder, ant.project)
|
||||
communityHome = toCanonicalPath(communityHome)
|
||||
if (["platform/build-scripts", "bin/log.xml", "build.txt"].any { !new File(communityHome, it).exists() }) {
|
||||
messages.error("communityHome ($communityHome) doesn't point to a directory containing IntelliJ Community sources")
|
||||
}
|
||||
|
||||
projectHome = toCanonicalPath(projectHome)
|
||||
def jdk8Home = toCanonicalPath(JdkUtils.computeJdkHome(messages, "jdk8Home", "$projectHome/build/jdk/1.8", "JDK_18_x64"))
|
||||
|
||||
WindowsDistributionCustomizer windowsDistributionCustomizer = productProperties.createWindowsCustomizer(projectHome)
|
||||
LinuxDistributionCustomizer linuxDistributionCustomizer = productProperties.createLinuxCustomizer(projectHome)
|
||||
MacDistributionCustomizer macDistributionCustomizer = productProperties.createMacCustomizer(projectHome)
|
||||
|
||||
if (project.modules.isEmpty()) {
|
||||
loadProject(communityHome, projectHome, jdk8Home, project, global, messages)
|
||||
}
|
||||
else {
|
||||
//todo[nik] currently we need this to build IDEA CE from IDEA UI build scripts. It would be better to create a separate JpsProject instance instead
|
||||
messages.info("Skipping loading project because it's already loaded")
|
||||
}
|
||||
|
||||
def context = new BuildContextImpl(ant, messages, communityHome, projectHome, jdk8Home, project, global, projectBuilder, productProperties,
|
||||
def compilationContext = CompilationContextImpl.create(ant, projectBuilder, project, global, communityHome, projectHome,
|
||||
createBuildOutputRootEvaluator(projectHome, productProperties), options)
|
||||
def context = new BuildContextImpl(compilationContext, productProperties,
|
||||
windowsDistributionCustomizer, linuxDistributionCustomizer, macDistributionCustomizer,
|
||||
proprietaryBuildTools, options)
|
||||
context.prepareForBuild()
|
||||
proprietaryBuildTools)
|
||||
return context
|
||||
}
|
||||
|
||||
private BuildContextImpl(AntBuilder ant, BuildMessages messages, String communityHome, String projectHome, String jdk8Home,
|
||||
JpsProject project, JpsGlobal global, JpsGantProjectBuilder projectBuilder, ProductProperties productProperties,
|
||||
private BuildContextImpl(CompilationContextImpl compilationContext, ProductProperties productProperties,
|
||||
WindowsDistributionCustomizer windowsDistributionCustomizer,
|
||||
LinuxDistributionCustomizer linuxDistributionCustomizer,
|
||||
MacDistributionCustomizer macDistributionCustomizer,
|
||||
ProprietaryBuildTools proprietaryBuildTools,
|
||||
BuildOptions options) {
|
||||
this.ant = ant
|
||||
this.messages = messages
|
||||
this.project = project
|
||||
this.global = global
|
||||
this.projectBuilder = projectBuilder
|
||||
ProprietaryBuildTools proprietaryBuildTools) {
|
||||
this.compilationContext = compilationContext
|
||||
this.global = compilationContext.global
|
||||
this.productProperties = productProperties
|
||||
this.proprietaryBuildTools = proprietaryBuildTools
|
||||
this.options = options
|
||||
this.windowsDistributionCustomizer = windowsDistributionCustomizer
|
||||
this.linuxDistributionCustomizer = linuxDistributionCustomizer
|
||||
this.macDistributionCustomizer = macDistributionCustomizer
|
||||
|
||||
def appInfoFile = findApplicationInfoInSources()
|
||||
def appInfoFile = findApplicationInfoInSources(project, productProperties, messages)
|
||||
applicationInfo = new ApplicationInfoProperties(appInfoFile.absolutePath)
|
||||
String buildOutputRoot = options.outputRootPath ?: "$projectHome/out/${productProperties.getOutputDirectoryName(applicationInfo)}"
|
||||
paths = new BuildPathsImpl(communityHome, projectHome, buildOutputRoot, jdk8Home)
|
||||
bundledJreManager = new BundledJreManager(this, paths.buildOutputRoot)
|
||||
|
||||
buildNumber = options.buildNumber ?: readSnapshotBuildNumber()
|
||||
@@ -102,109 +77,23 @@ class BuildContextImpl extends BuildContext {
|
||||
bootClassPathJarNames = ["bootstrap.jar", "extensions.jar", "util.jar", "jdom.jar", "log4j.jar", "trove4j.jar", "jna.jar"]
|
||||
}
|
||||
|
||||
private static void loadProject(String communityHome, String projectHome, String jdkHome, JpsProject project, JpsGlobal global,
|
||||
BuildMessages messages) {
|
||||
def bundledKotlinPath = "$communityHome/build/kotlinc"
|
||||
if (!new File(bundledKotlinPath, "lib/kotlin-runtime.jar").exists()) {
|
||||
messages.error("Could not find Kotlin runtime at $bundledKotlinPath/lib/kotlin-runtime.jar: run download_kotlin.gant script to download Kotlin JARs")
|
||||
}
|
||||
JpsModelSerializationDataService.getOrCreatePathVariablesConfiguration(global).addPathVariable("KOTLIN_BUNDLED", bundledKotlinPath)
|
||||
|
||||
JdkUtils.defineJdk(global, "IDEA jdk", JdkUtils.computeJdkHome(messages, "jdkHome", "$projectHome/build/jdk/1.6", "JDK_16_x64"))
|
||||
JdkUtils.defineJdk(global, "1.8", jdkHome)
|
||||
|
||||
def pathVariables = JpsModelSerializationDataService.computeAllPathVariables(global)
|
||||
JpsProjectLoader.loadProject(project, pathVariables, projectHome)
|
||||
messages.info("Loaded project $projectHome: ${project.modules.size()} modules, ${project.libraryCollection.libraries.size()} libraries")
|
||||
}
|
||||
|
||||
private void prepareForBuild() {
|
||||
checkCompilationOptions()
|
||||
projectBuilder.buildIncrementally = options.incrementalCompilation
|
||||
def dataDirName = options.incrementalCompilation ? ".jps-build-data-incremental" : ".jps-build-data"
|
||||
projectBuilder.dataStorageRoot = new File(paths.buildOutputRoot, dataDirName)
|
||||
def logDir = new File(paths.buildOutputRoot, "log")
|
||||
FileUtil.delete(logDir)
|
||||
projectBuilder.setupAdditionalLogging(new File("$logDir/compilation.log"), System.getProperty("intellij.build.debug.logging.categories", ""))
|
||||
|
||||
def classesDirName = "classes"
|
||||
def classesOutput = "$paths.buildOutputRoot/$classesDirName"
|
||||
List<String> outputDirectoriesToKeep = ["log"]
|
||||
if (options.pathToCompiledClassesArchive != null) {
|
||||
unpackCompiledClasses(messages, ant, classesOutput, options)
|
||||
outputDirectoriesToKeep.add(classesDirName)
|
||||
}
|
||||
if (options.incrementalCompilation) {
|
||||
outputDirectoriesToKeep.add(dataDirName)
|
||||
outputDirectoriesToKeep.add(classesDirName)
|
||||
}
|
||||
if (!options.useCompiledClassesFromProjectOutput) {
|
||||
projectBuilder.targetFolder = classesOutput
|
||||
}
|
||||
else {
|
||||
def outputDir = JpsPathUtil.urlToFile(JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(project).outputUrl)
|
||||
if (!outputDir.exists()) {
|
||||
messages.error("$BuildOptions.USE_COMPILED_CLASSES_PROPERTY is enabled, but the project output directory $outputDir.absolutePath doesn't exist")
|
||||
}
|
||||
}
|
||||
|
||||
suppressWarnings(project)
|
||||
projectBuilder.exportModuleOutputProperties()
|
||||
cleanOutput(outputDirectoriesToKeep)
|
||||
}
|
||||
|
||||
void cleanOutput(List<String> outputDirectoriesToKeep) {
|
||||
messages.block("Clean output") {
|
||||
def outputPath = paths.buildOutputRoot
|
||||
messages.progress("Cleaning output directory $outputPath")
|
||||
new File(outputPath).listFiles()?.each { File file ->
|
||||
if (outputDirectoriesToKeep.contains(file.name)) {
|
||||
messages.info("Skipped cleaning for $file.absolutePath")
|
||||
}
|
||||
else {
|
||||
FileUtil.delete(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@CompileDynamic
|
||||
private static void unpackCompiledClasses(BuildMessages messages, AntBuilder ant, String classesOutput, BuildOptions options) {
|
||||
messages.block("Unpack compiled classes archive") {
|
||||
FileUtil.delete(new File(classesOutput))
|
||||
ant.unzip(src: options.pathToCompiledClassesArchive, dest: classesOutput)
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCompilationOptions() {
|
||||
if (options.useCompiledClassesFromProjectOutput && options.incrementalCompilation) {
|
||||
messages.warning("'${BuildOptions.USE_COMPILED_CLASSES_PROPERTY}' is specified, so 'incremental compilation' option will be ignored")
|
||||
options.incrementalCompilation = false
|
||||
}
|
||||
if (options.pathToCompiledClassesArchive != null && options.incrementalCompilation) {
|
||||
messages.warning("Paths to the compiled project output is specified, so 'incremental compilation' option will be ignored")
|
||||
options.incrementalCompilation = false
|
||||
}
|
||||
if (options.pathToCompiledClassesArchive != null && options.useCompiledClassesFromProjectOutput) {
|
||||
messages.warning("'${BuildOptions.USE_COMPILED_CLASSES_PROPERTY}' is specified, so the archive with compiled project output won't be used")
|
||||
options.pathToCompiledClassesArchive = null
|
||||
}
|
||||
}
|
||||
|
||||
private static void suppressWarnings(JpsProject project) {
|
||||
def compilerOptions = JpsJavaExtensionService.instance.getOrCreateCompilerConfiguration(project).currentCompilerOptions
|
||||
compilerOptions.GENERATE_NO_WARNINGS = true
|
||||
compilerOptions.DEPRECATION = false
|
||||
compilerOptions.ADDITIONAL_OPTIONS_STRING = compilerOptions.ADDITIONAL_OPTIONS_STRING.replace("-Xlint:unchecked", "")
|
||||
}
|
||||
|
||||
private String readSnapshotBuildNumber() {
|
||||
new File(paths.communityHome, "build.txt").text.trim()
|
||||
}
|
||||
|
||||
@Override
|
||||
File findApplicationInfoInSources() {
|
||||
JpsModule module = findApplicationInfoModule()
|
||||
private static BiFunction<JpsProject, BuildMessages, String> createBuildOutputRootEvaluator(String projectHome, ProductProperties productProperties) {
|
||||
return { JpsProject project, BuildMessages messages ->
|
||||
def appInfoFile = findApplicationInfoInSources(project, productProperties, messages)
|
||||
def applicationInfo = new ApplicationInfoProperties(appInfoFile.absolutePath)
|
||||
return "$projectHome/out/${productProperties.getOutputDirectoryName(applicationInfo)}"
|
||||
} as BiFunction<JpsProject, BuildMessages, String>
|
||||
}
|
||||
|
||||
static File findApplicationInfoInSources(JpsProject project, ProductProperties productProperties, BuildMessages messages) {
|
||||
JpsModule module = project.modules.find {it.name == productProperties.applicationInfoModule }
|
||||
if (module == null) {
|
||||
messages.error("Cannot find required '${productProperties.applicationInfoModule}' module")
|
||||
}
|
||||
def appInfoRelativePath = "idea/${productProperties.platformPrefix ?: ""}ApplicationInfo.xml"
|
||||
def appInfoFile = module.sourceRoots.collect { new File(it.file, appInfoRelativePath) }.find { it.exists() }
|
||||
if (appInfoFile == null) {
|
||||
@@ -218,17 +107,43 @@ class BuildContextImpl extends BuildContext {
|
||||
return findRequiredModule(productProperties.applicationInfoModule)
|
||||
}
|
||||
|
||||
@Override
|
||||
AntBuilder getAnt() {
|
||||
compilationContext.ant
|
||||
}
|
||||
|
||||
@Override
|
||||
BuildOptions getOptions() {
|
||||
compilationContext.options
|
||||
}
|
||||
|
||||
@Override
|
||||
BuildMessages getMessages() {
|
||||
compilationContext.messages
|
||||
}
|
||||
|
||||
@Override
|
||||
BuildPaths getPaths() {
|
||||
compilationContext.paths
|
||||
}
|
||||
|
||||
@Override
|
||||
JpsProject getProject() {
|
||||
compilationContext.project
|
||||
}
|
||||
|
||||
@Override
|
||||
JpsGantProjectBuilder getProjectBuilder() {
|
||||
compilationContext.projectBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
JpsModule findRequiredModule(String name) {
|
||||
def module = findModule(name)
|
||||
if (module == null) {
|
||||
messages.error("Cannot find required module '$name' in the project")
|
||||
}
|
||||
return module
|
||||
return compilationContext.findRequiredModule(name)
|
||||
}
|
||||
|
||||
JpsModule findModule(String name) {
|
||||
project.modules.find { it.name == name }
|
||||
return compilationContext.findModule(name)
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -284,9 +199,10 @@ class BuildContextImpl extends BuildContext {
|
||||
BuildContext forkForParallelTask(String taskName) {
|
||||
def ant = new AntBuilder(ant.project)
|
||||
def messages = messages.forkForParallelTask(taskName)
|
||||
def child = new BuildContextImpl(ant, messages, paths.communityHome, paths.projectHome, paths.jdkHome, project, global, projectBuilder, productProperties,
|
||||
def compilationContextCopy = compilationContext.createCopy(ant, messages, options, createBuildOutputRootEvaluator(compilationContext.paths.projectHome, productProperties))
|
||||
def child = new BuildContextImpl(compilationContextCopy, productProperties,
|
||||
windowsDistributionCustomizer, linuxDistributionCustomizer, macDistributionCustomizer,
|
||||
proprietaryBuildTools, options)
|
||||
proprietaryBuildTools)
|
||||
child.paths.artifacts = paths.artifacts
|
||||
child.bundledJreManager.baseDirectoryForJre = bundledJreManager.baseDirectoryForJre
|
||||
return child
|
||||
@@ -300,11 +216,12 @@ class BuildContextImpl extends BuildContext {
|
||||
|
||||
def options = new BuildOptions()
|
||||
options.useCompiledClassesFromProjectOutput = true
|
||||
def copy = new BuildContextImpl(ant, messages, paths.communityHome, paths.projectHome, paths.jdkHome, project, global, projectBuilder, productProperties,
|
||||
windowsDistributionCustomizer, linuxDistributionCustomizer, macDistributionCustomizer, proprietaryBuildTools, options)
|
||||
def compilationContextCopy = compilationContext.createCopy(ant, messages, options, createBuildOutputRootEvaluator(paths.projectHome, productProperties))
|
||||
def copy = new BuildContextImpl(compilationContextCopy, productProperties,
|
||||
windowsDistributionCustomizer, linuxDistributionCustomizer, macDistributionCustomizer, proprietaryBuildTools)
|
||||
copy.paths.artifacts = paths.artifacts
|
||||
copy.bundledJreManager.baseDirectoryForJre = bundledJreManager.baseDirectoryForJre
|
||||
copy.prepareForBuild()
|
||||
copy.compilationContext.prepareForBuild()
|
||||
return copy
|
||||
}
|
||||
|
||||
@@ -362,21 +279,4 @@ class BuildContextImpl extends BuildContext {
|
||||
}
|
||||
messages.artifactBuild(relativePath)
|
||||
}
|
||||
|
||||
private static String toCanonicalPath(String communityHome) {
|
||||
FileUtil.toSystemIndependentName(new File(communityHome).canonicalPath)
|
||||
}
|
||||
}
|
||||
|
||||
class BuildPathsImpl extends BuildPaths {
|
||||
BuildPathsImpl(String communityHome, String projectHome, String buildOutputRoot, String jdkHome) {
|
||||
this.communityHome = communityHome
|
||||
this.projectHome = projectHome
|
||||
this.buildOutputRoot = buildOutputRoot
|
||||
this.jdkHome = jdkHome
|
||||
artifacts = "$buildOutputRoot/artifacts"
|
||||
distAll = "$buildOutputRoot/dist.all"
|
||||
temp = "$buildOutputRoot/temp"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-55
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.intellij.build.BuildContext
|
||||
import org.jetbrains.intellij.build.BuildOptions
|
||||
import org.jetbrains.intellij.build.BuildTasks
|
||||
import org.jetbrains.intellij.build.CompilationTasks
|
||||
import org.jetbrains.intellij.build.ProductModulesLayout
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootType
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||
@@ -182,7 +183,7 @@ idea.fatal.error.notification=disabled
|
||||
}
|
||||
|
||||
File patchApplicationInfo() {
|
||||
def sourceFile = buildContext.findApplicationInfoInSources()
|
||||
def sourceFile = BuildContextImpl.findApplicationInfoInSources(buildContext.project, buildContext.productProperties, buildContext.messages)
|
||||
def targetFile = new File(buildContext.paths.temp, sourceFile.name)
|
||||
def date = ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("uuuuMMddHHmm"))
|
||||
BuildUtils.copyAndPatchFile(sourceFile.path, targetFile.path,
|
||||
@@ -244,8 +245,14 @@ idea.fatal.error.notification=disabled
|
||||
checkProductProperties()
|
||||
def patchedApplicationInfo = patchApplicationInfo()
|
||||
def distributionJARsBuilder = new DistributionJARsBuilder(buildContext, patchedApplicationInfo)
|
||||
compileModules(buildContext.productProperties.productLayout.includedPluginModules + distributionJARsBuilder.platformModules +
|
||||
buildContext.productProperties.additionalModulesToCompile, buildContext.productProperties.modulesToCompileTests)
|
||||
compileModulesForDistribution(distributionJARsBuilder)
|
||||
}
|
||||
|
||||
private compileModulesForDistribution(DistributionJARsBuilder distributionJARsBuilder) {
|
||||
def moduleNames = buildContext.productProperties.productLayout.includedPluginModules + distributionJARsBuilder.platformModules +
|
||||
buildContext.productProperties.additionalModulesToCompile +
|
||||
(buildContext.proprietaryBuildTools.scrambleTool?.additionalModulesToCompile ?: [])
|
||||
compileModules(moduleNames, buildContext.productProperties.modulesToCompileTests)
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -254,8 +261,7 @@ idea.fatal.error.notification=disabled
|
||||
|
||||
def patchedApplicationInfo = patchApplicationInfo()
|
||||
def distributionJARsBuilder = new DistributionJARsBuilder(buildContext, patchedApplicationInfo)
|
||||
compileModules(buildContext.productProperties.productLayout.includedPluginModules + distributionJARsBuilder.platformModules +
|
||||
buildContext.productProperties.additionalModulesToCompile, buildContext.productProperties.modulesToCompileTests)
|
||||
compileModulesForDistribution(distributionJARsBuilder)
|
||||
buildContext.messages.block("Build platform and plugin JARs") {
|
||||
if (buildContext.shouldBuildDistributions()) {
|
||||
distributionJARsBuilder.buildJARs()
|
||||
@@ -410,56 +416,7 @@ idea.fatal.error.notification=disabled
|
||||
|
||||
@Override
|
||||
void compileModules(List<String> moduleNames, List<String> includingTestsInModules = []) {
|
||||
if (buildContext.options.useCompiledClassesFromProjectOutput) {
|
||||
buildContext.messages.info("Compilation skipped, the compiled classes from the project output will be used")
|
||||
return
|
||||
}
|
||||
if (buildContext.options.pathToCompiledClassesArchive != null) {
|
||||
buildContext.messages.info("Compilation skipped, the compiled classes from '${buildContext.options.pathToCompiledClassesArchive}' will be used")
|
||||
return
|
||||
}
|
||||
|
||||
ensureKotlinCompilerAddedToClassPath()
|
||||
|
||||
buildContext.projectBuilder.cleanOutput()
|
||||
try {
|
||||
if (moduleNames == null) {
|
||||
buildContext.projectBuilder.buildProduction()
|
||||
}
|
||||
else {
|
||||
List<String> modulesToBuild = ((moduleNames as Set<String>) +
|
||||
buildContext.proprietaryBuildTools.scrambleTool?.additionalModulesToCompile ?: []) as List<String>
|
||||
List<String> invalidModules = modulesToBuild.findAll {buildContext.findModule(it) == null}
|
||||
if (!invalidModules.empty) {
|
||||
buildContext.messages.warning("The following modules won't be compiled: $invalidModules")
|
||||
}
|
||||
buildContext.projectBuilder.buildModules(modulesToBuild.collect {buildContext.findModule(it)}.findAll {it != null})
|
||||
}
|
||||
for (String moduleName : includingTestsInModules) {
|
||||
buildContext.projectBuilder.makeModuleTests(buildContext.findModule(moduleName))
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
buildContext.messages.error("Compilation failed with exception: $e", e)
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureKotlinCompilerAddedToClassPath() {
|
||||
try {
|
||||
Class.forName("org.jetbrains.kotlin.jps.build.KotlinBuilder")
|
||||
return
|
||||
}
|
||||
catch (ClassNotFoundException ignored) {}
|
||||
|
||||
def kotlinPluginLibPath = "$buildContext.paths.communityHome/build/kotlinc/plugin/Kotlin/lib"
|
||||
if (new File(kotlinPluginLibPath).exists()) {
|
||||
["jps/kotlin-jps-plugin.jar", "kotlin-plugin.jar", "kotlin-runtime.jar", "kotlin-reflect.jar"].each {
|
||||
BuildUtils.addToJpsClassPath("$kotlinPluginLibPath/$it", buildContext.ant)
|
||||
}
|
||||
}
|
||||
else {
|
||||
buildContext.messages.error("Could not find Kotlin JARs at $kotlinPluginLibPath: run download_kotlin.gant script to download them")
|
||||
}
|
||||
CompilationTasks.create(buildContext).compileModules(moduleNames, includingTestsInModules)
|
||||
}
|
||||
|
||||
private <V> List<V> runInParallel(List<BuildTaskRunnable<V>> tasks) {
|
||||
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.intellij.build.impl
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import groovy.transform.CompileDynamic
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.intellij.build.BuildMessages
|
||||
import org.jetbrains.intellij.build.BuildOptions
|
||||
import org.jetbrains.intellij.build.BuildPaths
|
||||
import org.jetbrains.intellij.build.CompilationContext
|
||||
import org.jetbrains.jps.gant.JpsGantProjectBuilder
|
||||
import org.jetbrains.jps.model.JpsGlobal
|
||||
import org.jetbrains.jps.model.JpsProject
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.jps.model.module.JpsModule
|
||||
import org.jetbrains.jps.model.serialization.JpsModelSerializationDataService
|
||||
import org.jetbrains.jps.model.serialization.JpsProjectLoader
|
||||
import org.jetbrains.jps.util.JpsPathUtil
|
||||
|
||||
import java.util.function.BiFunction
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
@CompileStatic
|
||||
class CompilationContextImpl implements CompilationContext {
|
||||
final AntBuilder ant
|
||||
final BuildOptions options
|
||||
final BuildMessages messages
|
||||
final BuildPaths paths
|
||||
final JpsProject project
|
||||
final JpsGlobal global
|
||||
final JpsGantProjectBuilder projectBuilder
|
||||
|
||||
static CompilationContextImpl create(AntBuilder ant, JpsGantProjectBuilder projectBuilder, JpsProject project, JpsGlobal global,
|
||||
String communityHome, String projectHome,
|
||||
BiFunction<JpsProject, BuildMessages, String> buildOutputRootEvaluator, BuildOptions options) {
|
||||
def messages = BuildMessagesImpl.create(projectBuilder, ant.project)
|
||||
communityHome = toCanonicalPath(communityHome)
|
||||
if (["platform/build-scripts", "bin/log.xml", "build.txt"].any { !new File(communityHome, it).exists() }) {
|
||||
messages.error("communityHome ($communityHome) doesn't point to a directory containing IntelliJ Community sources")
|
||||
}
|
||||
|
||||
projectHome = toCanonicalPath(projectHome)
|
||||
def jdk8Home = toCanonicalPath(JdkUtils.computeJdkHome(messages, "jdk8Home", "$projectHome/build/jdk/1.8", "JDK_18_x64"))
|
||||
if (project.modules.isEmpty()) {
|
||||
loadProject(communityHome, projectHome, jdk8Home, project, global, messages)
|
||||
}
|
||||
else {
|
||||
//todo[nik] currently we need this to build IDEA CE from IDEA UI build scripts. It would be better to create a separate JpsProject instance instead
|
||||
messages.info("Skipping loading project because it's already loaded")
|
||||
}
|
||||
|
||||
def context = new CompilationContextImpl(ant, projectBuilder, project, global, communityHome, projectHome, jdk8Home, messages,
|
||||
buildOutputRootEvaluator, options)
|
||||
context.prepareForBuild()
|
||||
return context
|
||||
}
|
||||
|
||||
private CompilationContextImpl(AntBuilder ant, JpsGantProjectBuilder projectBuilder, JpsProject project, JpsGlobal global,
|
||||
String communityHome, String projectHome, String jdk8Home, BuildMessages messages,
|
||||
BiFunction<JpsProject, BuildMessages, String> buildOutputRootEvaluator, BuildOptions options) {
|
||||
this.ant = ant
|
||||
this.project = project
|
||||
this.global = global
|
||||
this.options = options
|
||||
this.projectBuilder = projectBuilder
|
||||
this.messages = messages
|
||||
String buildOutputRoot = options.outputRootPath ?: buildOutputRootEvaluator.apply(project, messages)
|
||||
this.paths = new BuildPathsImpl(communityHome, projectHome, buildOutputRoot, jdk8Home)
|
||||
}
|
||||
|
||||
CompilationContextImpl createCopy(AntBuilder ant, BuildMessages messages, BuildOptions options,
|
||||
BiFunction<JpsProject, BuildMessages, String> buildOutputRootEvaluator) {
|
||||
return new CompilationContextImpl(ant, projectBuilder, project, global, paths.communityHome, paths.projectHome, paths.jdkHome,
|
||||
messages, buildOutputRootEvaluator, options)
|
||||
}
|
||||
|
||||
private static void loadProject(String communityHome, String projectHome, String jdkHome, JpsProject project, JpsGlobal global,
|
||||
BuildMessages messages) {
|
||||
def bundledKotlinPath = "$communityHome/build/kotlinc"
|
||||
if (!new File(bundledKotlinPath, "lib/kotlin-runtime.jar").exists()) {
|
||||
messages.error(
|
||||
"Could not find Kotlin runtime at $bundledKotlinPath/lib/kotlin-runtime.jar: run download_kotlin.gant script to download Kotlin JARs")
|
||||
}
|
||||
JpsModelSerializationDataService.getOrCreatePathVariablesConfiguration(global).addPathVariable("KOTLIN_BUNDLED", bundledKotlinPath)
|
||||
|
||||
JdkUtils.defineJdk(global, "IDEA jdk", JdkUtils.computeJdkHome(messages, "jdkHome", "$projectHome/build/jdk/1.6", "JDK_16_x64"))
|
||||
JdkUtils.defineJdk(global, "1.8", jdkHome)
|
||||
|
||||
def pathVariables = JpsModelSerializationDataService.computeAllPathVariables(global)
|
||||
JpsProjectLoader.loadProject(project, pathVariables, projectHome)
|
||||
messages.info("Loaded project $projectHome: ${project.modules.size()} modules, ${project.libraryCollection.libraries.size()} libraries")
|
||||
}
|
||||
|
||||
void prepareForBuild() {
|
||||
checkCompilationOptions()
|
||||
projectBuilder.buildIncrementally = options.incrementalCompilation
|
||||
def dataDirName = options.incrementalCompilation ? ".jps-build-data-incremental" : ".jps-build-data"
|
||||
projectBuilder.dataStorageRoot = new File(paths.buildOutputRoot, dataDirName)
|
||||
def logDir = new File(paths.buildOutputRoot, "log")
|
||||
FileUtil.delete(logDir)
|
||||
projectBuilder.setupAdditionalLogging(new File("$logDir/compilation.log"), System.getProperty("intellij.build.debug.logging.categories", ""))
|
||||
|
||||
def classesDirName = "classes"
|
||||
def classesOutput = "$paths.buildOutputRoot/$classesDirName"
|
||||
List<String> outputDirectoriesToKeep = ["log"]
|
||||
if (options.pathToCompiledClassesArchive != null) {
|
||||
unpackCompiledClasses(messages, ant, classesOutput, options)
|
||||
outputDirectoriesToKeep.add(classesDirName)
|
||||
}
|
||||
if (options.incrementalCompilation) {
|
||||
outputDirectoriesToKeep.add(dataDirName)
|
||||
outputDirectoriesToKeep.add(classesDirName)
|
||||
}
|
||||
if (!options.useCompiledClassesFromProjectOutput) {
|
||||
projectBuilder.targetFolder = classesOutput
|
||||
}
|
||||
else {
|
||||
def outputDir = JpsPathUtil.urlToFile(JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(project).outputUrl)
|
||||
if (!outputDir.exists()) {
|
||||
messages.error("$BuildOptions.USE_COMPILED_CLASSES_PROPERTY is enabled, but the project output directory $outputDir.absolutePath doesn't exist")
|
||||
}
|
||||
}
|
||||
|
||||
suppressWarnings(project)
|
||||
projectBuilder.exportModuleOutputProperties()
|
||||
cleanOutput(outputDirectoriesToKeep)
|
||||
}
|
||||
|
||||
void cleanOutput(List<String> outputDirectoriesToKeep) {
|
||||
messages.block("Clean output") {
|
||||
def outputPath = paths.buildOutputRoot
|
||||
messages.progress("Cleaning output directory $outputPath")
|
||||
new File(outputPath).listFiles()?.each { File file ->
|
||||
if (outputDirectoriesToKeep.contains(file.name)) {
|
||||
messages.info("Skipped cleaning for $file.absolutePath")
|
||||
}
|
||||
else {
|
||||
FileUtil.delete(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@CompileDynamic
|
||||
private static void unpackCompiledClasses(BuildMessages messages, AntBuilder ant, String classesOutput, BuildOptions options) {
|
||||
messages.block("Unpack compiled classes archive") {
|
||||
FileUtil.delete(new File(classesOutput))
|
||||
ant.unzip(src: options.pathToCompiledClassesArchive, dest: classesOutput)
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCompilationOptions() {
|
||||
if (options.useCompiledClassesFromProjectOutput && options.incrementalCompilation) {
|
||||
messages.warning("'${BuildOptions.USE_COMPILED_CLASSES_PROPERTY}' is specified, so 'incremental compilation' option will be ignored")
|
||||
options.incrementalCompilation = false
|
||||
}
|
||||
if (options.pathToCompiledClassesArchive != null && options.incrementalCompilation) {
|
||||
messages.warning("Paths to the compiled project output is specified, so 'incremental compilation' option will be ignored")
|
||||
options.incrementalCompilation = false
|
||||
}
|
||||
if (options.pathToCompiledClassesArchive != null && options.useCompiledClassesFromProjectOutput) {
|
||||
messages.warning("'${BuildOptions.USE_COMPILED_CLASSES_PROPERTY}' is specified, so the archive with compiled project output won't be used")
|
||||
options.pathToCompiledClassesArchive = null
|
||||
}
|
||||
}
|
||||
|
||||
private static void suppressWarnings(JpsProject project) {
|
||||
def compilerOptions = JpsJavaExtensionService.instance.getOrCreateCompilerConfiguration(project).currentCompilerOptions
|
||||
compilerOptions.GENERATE_NO_WARNINGS = true
|
||||
compilerOptions.DEPRECATION = false
|
||||
compilerOptions.ADDITIONAL_OPTIONS_STRING = compilerOptions.ADDITIONAL_OPTIONS_STRING.replace("-Xlint:unchecked", "")
|
||||
}
|
||||
|
||||
@Override
|
||||
JpsModule findRequiredModule(String name) {
|
||||
def module = findModule(name)
|
||||
if (module == null) {
|
||||
messages.error("Cannot find required module '$name' in the project")
|
||||
}
|
||||
return module
|
||||
}
|
||||
|
||||
JpsModule findModule(String name) {
|
||||
project.modules.find { it.name == name }
|
||||
}
|
||||
|
||||
private static String toCanonicalPath(String communityHome) {
|
||||
FileUtil.toSystemIndependentName(new File(communityHome).canonicalPath)
|
||||
}
|
||||
}
|
||||
|
||||
class BuildPathsImpl extends BuildPaths {
|
||||
BuildPathsImpl(String communityHome, String projectHome, String buildOutputRoot, String jdkHome) {
|
||||
this.communityHome = communityHome
|
||||
this.projectHome = projectHome
|
||||
this.buildOutputRoot = buildOutputRoot
|
||||
this.jdkHome = jdkHome
|
||||
artifacts = "$buildOutputRoot/artifacts"
|
||||
distAll = "$buildOutputRoot/dist.all"
|
||||
temp = "$buildOutputRoot/temp"
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.intellij.build.impl
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.intellij.build.CompilationContext
|
||||
import org.jetbrains.intellij.build.CompilationTasks
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
@CompileStatic
|
||||
class CompilationTasksImpl extends CompilationTasks {
|
||||
private final CompilationContext context
|
||||
|
||||
CompilationTasksImpl(CompilationContext context) {
|
||||
this.context = context
|
||||
}
|
||||
|
||||
@Override
|
||||
void compileModules(List<String> moduleNames, List<String> includingTestsInModules) {
|
||||
if (context.options.useCompiledClassesFromProjectOutput) {
|
||||
context.messages.info("Compilation skipped, the compiled classes from the project output will be used")
|
||||
return
|
||||
}
|
||||
if (context.options.pathToCompiledClassesArchive != null) {
|
||||
context.messages.info("Compilation skipped, the compiled classes from '${context.options.pathToCompiledClassesArchive}' will be used")
|
||||
return
|
||||
}
|
||||
|
||||
ensureKotlinCompilerAddedToClassPath()
|
||||
|
||||
context.projectBuilder.cleanOutput()
|
||||
try {
|
||||
if (moduleNames == null) {
|
||||
if (includingTestsInModules == null) {
|
||||
context.projectBuilder.buildAll()
|
||||
}
|
||||
else {
|
||||
context.projectBuilder.buildProduction()
|
||||
}
|
||||
}
|
||||
else {
|
||||
List<String> invalidModules = moduleNames.findAll { context.findModule(it) == null }
|
||||
if (!invalidModules.empty) {
|
||||
context.messages.warning("The following modules won't be compiled: $invalidModules")
|
||||
}
|
||||
context.projectBuilder.buildModules(moduleNames.collect { context.findModule(it) }.findAll { it != null })
|
||||
}
|
||||
|
||||
if (includingTestsInModules != null) {
|
||||
for (String moduleName : includingTestsInModules) {
|
||||
context.projectBuilder.makeModuleTests(context.findModule(moduleName))
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
context.messages.error("Compilation failed with exception: $e", e)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void compileAllModulesAndTests() {
|
||||
compileModules(null, null)
|
||||
}
|
||||
|
||||
private void ensureKotlinCompilerAddedToClassPath() {
|
||||
try {
|
||||
Class.forName("org.jetbrains.kotlin.jps.build.KotlinBuilder")
|
||||
return
|
||||
}
|
||||
catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
|
||||
def kotlinPluginLibPath = "$context.paths.communityHome/build/kotlinc/plugin/Kotlin/lib"
|
||||
if (new File(kotlinPluginLibPath).exists()) {
|
||||
["jps/kotlin-jps-plugin.jar", "kotlin-plugin.jar", "kotlin-runtime.jar", "kotlin-reflect.jar"].each {
|
||||
BuildUtils.addToJpsClassPath("$kotlinPluginLibPath/$it", context.ant)
|
||||
}
|
||||
}
|
||||
else {
|
||||
context.messages.error("Could not find Kotlin JARs at $kotlinPluginLibPath: run download_kotlin.gant script to download them")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,7 +146,8 @@ public class ClipboardSynchronizer implements ApplicationComponentAdapter, Dispo
|
||||
return ClipboardUtil.handleClipboardSafely(myClipboardHandler::getContents, () -> null);
|
||||
}
|
||||
|
||||
public Object getData(DataFlavor dataFlavor) {
|
||||
@Nullable
|
||||
public Object getData(@NotNull DataFlavor dataFlavor) {
|
||||
return ClipboardUtil.handleClipboardSafely(() -> {
|
||||
try {
|
||||
return myClipboardHandler.getData(dataFlavor);
|
||||
@@ -204,7 +205,8 @@ public class ClipboardSynchronizer implements ApplicationComponentAdapter, Dispo
|
||||
return clipboard == null ? null: clipboard.getContents(this);
|
||||
}
|
||||
|
||||
public Object getData(DataFlavor dataFlavor) throws IOException, UnsupportedFlavorException {
|
||||
@Nullable
|
||||
public Object getData(@NotNull DataFlavor dataFlavor) throws IOException, UnsupportedFlavorException {
|
||||
Clipboard clipboard = getClipboard();
|
||||
return clipboard == null ? null : clipboard.getData(dataFlavor);
|
||||
}
|
||||
@@ -256,7 +258,8 @@ public class ClipboardSynchronizer implements ApplicationComponentAdapter, Dispo
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(DataFlavor dataFlavor) throws IOException, UnsupportedFlavorException {
|
||||
@Nullable
|
||||
public Object getData(@NotNull DataFlavor dataFlavor) throws IOException, UnsupportedFlavorException {
|
||||
if (myFullTransferable == null) return super.getData(dataFlavor);
|
||||
Transferable contents = getContents();
|
||||
return contents == null ? null : contents.getTransferData(dataFlavor);
|
||||
@@ -371,22 +374,12 @@ public class ClipboardSynchronizer implements ApplicationComponentAdapter, Dispo
|
||||
return ClipboardSynchronizer.areDataFlavorsAvailable(currentContent, flavors);
|
||||
}
|
||||
|
||||
try {
|
||||
Collection<DataFlavor> contents = checkContentsQuick();
|
||||
if (contents != null) {
|
||||
return ClipboardSynchronizer.areDataFlavorsAvailable(contents, flavors);
|
||||
}
|
||||
Collection<DataFlavor> contents = checkContentsQuick();
|
||||
if (contents != null) {
|
||||
return ClipboardSynchronizer.areDataFlavorsAvailable(contents, flavors);
|
||||
}
|
||||
|
||||
return super.areDataFlavorsAvailable(flavors);
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
LOG.warn("Java bug #6322854", e);
|
||||
return false;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
LOG.warn("Java bug #7173464", e);
|
||||
return false;
|
||||
}
|
||||
return super.areDataFlavorsAvailable(flavors);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -396,47 +389,28 @@ public class ClipboardSynchronizer implements ApplicationComponentAdapter, Dispo
|
||||
return currentContent;
|
||||
}
|
||||
|
||||
try {
|
||||
final Collection<DataFlavor> contents = checkContentsQuick();
|
||||
if (contents != null && contents.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Collection<DataFlavor> contents = checkContentsQuick();
|
||||
if (contents != null && contents.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return super.getContents();
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
LOG.warn("Java bug #6322854", e);
|
||||
return null;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
LOG.warn("Java bug #7173464", e);
|
||||
return null;
|
||||
}
|
||||
return super.getContents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(DataFlavor dataFlavor) throws IOException, UnsupportedFlavorException {
|
||||
@Nullable
|
||||
public Object getData(@NotNull DataFlavor dataFlavor) throws IOException, UnsupportedFlavorException {
|
||||
Transferable currentContent = myCurrentContent;
|
||||
if (currentContent != null) {
|
||||
return currentContent.getTransferData(dataFlavor);
|
||||
}
|
||||
|
||||
try {
|
||||
final Collection<DataFlavor> contents = checkContentsQuick();
|
||||
if (contents != null && contents.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Collection<DataFlavor> contents = checkContentsQuick();
|
||||
if (contents != null && !contents.contains(dataFlavor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return super.getData(dataFlavor);
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
LOG.warn("Java bug #6322854", e);
|
||||
return null;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
LOG.warn("Java bug #7173464", e);
|
||||
return null;
|
||||
}
|
||||
return super.getData(dataFlavor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -508,7 +482,8 @@ public class ClipboardSynchronizer implements ApplicationComponentAdapter, Dispo
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(DataFlavor dataFlavor) throws IOException, UnsupportedFlavorException {
|
||||
@Nullable
|
||||
public Object getData(@NotNull DataFlavor dataFlavor) throws IOException, UnsupportedFlavorException {
|
||||
return myContent.getTransferData(dataFlavor);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,14 @@ public class ClipboardUtil {
|
||||
else {
|
||||
LOG.warn(e);
|
||||
}
|
||||
return onFail.get();
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
LOG.warn("Java bug #6322854", e);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
LOG.warn("Java bug #7173464", e);
|
||||
}
|
||||
return onFail.get();
|
||||
}
|
||||
|
||||
private static final String USE_LEGACY_MERGE_SORT_PROPERTY_NAME = "java.util.Arrays.useLegacyMergeSort";
|
||||
|
||||
@@ -38,7 +38,6 @@ public class EduNames {
|
||||
public static final String TESTS_FILE = "tests.py";
|
||||
public static final String TEST_HELPER = "test_helper.py";
|
||||
|
||||
public static final String SANDBOX_DIR = "Sandbox";
|
||||
public static final String COURSE_META_FILE = "course.json";
|
||||
public static final String PYCHARM_ADDITIONAL = "PyCharm additional materials";
|
||||
public static final String PYCHARM = "PyCharm";
|
||||
|
||||
-1
@@ -109,7 +109,6 @@ public class StudyGenerator {
|
||||
lesson.setIndex(i);
|
||||
createLesson(lesson, baseDir, resourceRoot, project);
|
||||
}
|
||||
baseDir.createChildDirectory(project, EduNames.SANDBOX_DIR);
|
||||
File[] files = resourceRoot.listFiles(
|
||||
(dir, name) -> !name.contains(EduNames.LESSON) && !name.equals(EduNames.COURSE_META_FILE) && !name.equals(EduNames.HINTS));
|
||||
if (files != null) {
|
||||
|
||||
-3
@@ -43,9 +43,6 @@ public class CourseDirectoryNode extends StudyDirectoryNode {
|
||||
Object value = childNode.getValue();
|
||||
if (value instanceof PsiDirectory) {
|
||||
PsiDirectory directory = (PsiDirectory)value;
|
||||
if (EduNames.SANDBOX_DIR.equals(directory.getName())) {
|
||||
return new SandboxDirectoryNode(myProject, directory, myViewSettings);
|
||||
}
|
||||
Lesson lesson = myCourse.getLesson(directory.getName());
|
||||
return lesson != null ? createChildDirectoryNode(lesson, directory) : null;
|
||||
}
|
||||
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
package com.jetbrains.edu.learning.projectView;
|
||||
|
||||
import com.intellij.ide.projectView.PresentationData;
|
||||
import com.intellij.ide.projectView.ViewSettings;
|
||||
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.courseFormat.StudyItem;
|
||||
import icons.InteractiveLearningIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class SandboxDirectoryNode extends StudyDirectoryNode {
|
||||
public SandboxDirectoryNode(@NotNull Project project,
|
||||
PsiDirectory value,
|
||||
ViewSettings viewSettings) {
|
||||
super(project, value, viewSettings);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AbstractTreeNode modifyChildNode(AbstractTreeNode childNode) {
|
||||
return childNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiDirectoryNode createChildDirectoryNode(StudyItem item, PsiDirectory value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateImpl(PresentationData data) {
|
||||
setPresentation(data, EduNames.SANDBOX_DIR, InteractiveLearningIcons.Sandbox);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWeight() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ public class HtmlCompletionContributor extends CompletionContributor {
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean hasHtmlAttributesCompletion(PsiElement position) {
|
||||
public static boolean hasHtmlAttributesCompletion(PsiElement position) {
|
||||
if (PsiTreeUtil.getParentOfType(position, HtmlTag.class, false) != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user