Improve IntelliJ IDE integration (#53747)
This commit makes a number of improvements when importing the Elasticsearch project into IntelliJ IDEA. Specifically: - Contributing documentation has been updated to reflect that the 'idea' task should no long be used and Gradle project import is instead the officially supported way of setting up the project. - Attempts to run the 'idea' task will result in a failure with a message directing folks to our CONTRIBUTING.md document. - The project JDK is explicit set rather that using whatever JAVA_HOME is. - Gradle build operation delegation is disabled, and test execution is configured to 'choose per test'. - Gradle is configured to inherit the project JDK. - Some code style conventions are automatically configured. - File encoding is explicitly set to UTF-8. - Parallel module compilation is enabled and deprecated feature warnings are disabled. - A remote debug run configuration using listen mode is created. - JUnit runner is configured with required system properties. - License headers are configured such that Apache 2 is the default notice added to all source files with exception of source in /x-pack which will use the Elastic license.
This commit is contained in:
parent
d846ea43f4
commit
3b2b564c91
|
@ -5,6 +5,12 @@
|
|||
*.ipr
|
||||
*.iws
|
||||
build-idea/
|
||||
out/
|
||||
|
||||
# include shared intellij config
|
||||
!.idea/scopes/x_pack.xml
|
||||
!.idea/inspectionProfiles/Project_Default.xml
|
||||
|
||||
# These files are generated in the main tree by IntelliJ
|
||||
benchmarks/src/main/generated/*
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="GroovyPointlessBoolean" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="PointlessBooleanExpression" enabled="false" level="WARNING" enabled_by_default="false">
|
||||
<option name="m_ignoreExpressionsContainingConstants" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
|
@ -0,0 +1,3 @@
|
|||
<component name="DependencyValidationManager">
|
||||
<scope name="x-pack" pattern="file[*.x-pack]:*/||file[*.x-pack*]:*//*" />
|
||||
</component>
|
|
@ -107,56 +107,34 @@ and `JAVA11_HOME`, and `JAVA12_HOME` available so that the tests can pass.
|
|||
`jrunscript` for jdk distributions.
|
||||
|
||||
Elasticsearch uses the Gradle wrapper for its build. You can execute Gradle
|
||||
using the wrapper via the `gradlew` script on Unix systems or `gradlew.bat`
|
||||
using the wrapper via the `gradlew` script on Unix systems or `gradlew.bat`
|
||||
script on Windows in the root of the repository. The examples below show the
|
||||
usage on Unix.
|
||||
|
||||
We support development in the Eclipse and IntelliJ IDEs.
|
||||
For Eclipse, the minimum version that we support is [4.13][eclipse].
|
||||
For IntelliJ, the minimum version that we support is [IntelliJ 2017.2][intellij].
|
||||
We support development in IntelliJ versions IntelliJ 2019.2 and
|
||||
onwards. We would like to support Eclipse, but few of us use it and has fallen
|
||||
into [disrepair][eclipse].
|
||||
|
||||
### Configuring IDEs And Running Tests
|
||||
[Docker](https://docs.docker.com/install/) is required for building some Elasticsearch artifacts and executing certain test suites. You can run Elasticsearch without building all the artifacts with:
|
||||
|
||||
Eclipse users can automatically configure their IDE: `./gradlew eclipse`
|
||||
then `File: Import: Gradle : Existing Gradle Project`.
|
||||
Additionally you will want to ensure that Eclipse is using 2048m of heap by modifying
|
||||
`eclipse.ini` accordingly to avoid GC overhead and OOM errors.
|
||||
./gradlew :run
|
||||
|
||||
IntelliJ users can automatically configure their IDE: `./gradlew idea`
|
||||
then `File->New Project From Existing Sources`. Point to the root of
|
||||
the source directory, select
|
||||
`Import project from external model->Gradle`, enable
|
||||
`Use auto-import`. In order to run tests directly from
|
||||
IDEA 2017.2 and above, it is required to disable the IDEA run launcher in order to avoid
|
||||
`idea_rt.jar` causing "jar hell". This can be achieved by adding the
|
||||
`-Didea.no.launcher=true` [JVM
|
||||
option](https://intellij-support.jetbrains.com/hc/en-us/articles/206544869-Configuring-JVM-options-and-platform-properties).
|
||||
Alternatively, `idea.no.launcher=true` can be set in the
|
||||
[`idea.properties`](https://www.jetbrains.com/help/idea/file-idea-properties.html)
|
||||
file which can be accessed under Help > Edit Custom Properties (this will require a
|
||||
restart of IDEA). For IDEA 2017.3 and above, in addition to the JVM option, you will need to go to
|
||||
`Run->Edit Configurations->...->Defaults->JUnit` and verify that the `Shorten command line` setting is set to
|
||||
`user-local default: none`. You may also need to [remove `ant-javafx.jar` from your
|
||||
classpath](https://github.com/elastic/elasticsearch/issues/14348) if that is
|
||||
reported as a source of jar hell.
|
||||
You can access Elasticsearch with:
|
||||
|
||||
To run an instance of elasticsearch from the source code run `./gradlew run`
|
||||
curl -u elastic:password localhost:9200
|
||||
|
||||
The Elasticsearch codebase makes heavy use of Java `assert`s and the
|
||||
test runner requires that assertions be enabled within the JVM. This
|
||||
can be accomplished by passing the flag `-ea` to the JVM on startup.
|
||||
### Importing the project into IntelliJ IDEA
|
||||
|
||||
For IntelliJ, go to
|
||||
`Run->Edit Configurations...->Defaults->JUnit->VM options` and input
|
||||
`-ea`.
|
||||
Elasticsearch builds using Java 13. Before importing into IntelliJ you will need
|
||||
to define an appropriate SDK. The convention is that **this SDK should be named
|
||||
"13"** so that the project import will detect it automatically. For more details
|
||||
on defining an SDK in IntelliJ please refer to [their documentation](https://www.jetbrains.com/help/idea/sdk.html#define-sdk).
|
||||
|
||||
For Eclipse, go to `Preferences->Java->Installed JREs` and add `-ea` to
|
||||
`VM Arguments`.
|
||||
You can import the Elasticsearch project into IntelliJ IDEA via:
|
||||
|
||||
Some tests related to locale testing also require the flag
|
||||
`-Djava.locale.providers` to be set. Set the VM options/VM arguments for
|
||||
IntelliJ or Eclipse like describe above to use
|
||||
`-Djava.locale.providers=SPI,COMPAT`.
|
||||
- Select **File > Open**
|
||||
- In the subsequent dialog navigate to the root `build.gradle` file
|
||||
- In the subsequent dialog select **Open as Project**
|
||||
|
||||
### Java Language Formatting Guidelines
|
||||
|
||||
|
@ -188,14 +166,7 @@ Please follow these formatting guidelines:
|
|||
part of a file. Please format such sections sympathetically with the rest
|
||||
of the code, while keeping lines to maximum length of 76 characters.
|
||||
* Wildcard imports (`import foo.bar.baz.*`) are forbidden and will cause
|
||||
the build to fail. This can be done automatically by your IDE:
|
||||
* Eclipse: `Preferences->Java->Code Style->Organize Imports`. There are
|
||||
two boxes labeled "`Number of (static )? imports needed for .*`". Set
|
||||
their values to 99999 or some other absurdly high value.
|
||||
* IntelliJ: `Preferences/Settings->Editor->Code Style->Java->Imports`.
|
||||
There are two configuration options: `Class count to use import with
|
||||
'*'` and `Names count to use static import with '*'`. Set their values
|
||||
to 99999 or some other absurdly high value.
|
||||
the build to fail.
|
||||
* If *absolutely* necessary, you can disable formatting for regions of code
|
||||
with the `// tag::NAME` and `// end::NAME` directives, but note that
|
||||
these are intended for use in documentation, so please make it clear what
|
||||
|
@ -277,26 +248,9 @@ It is important that the only code covered by the Elastic licence is contained
|
|||
within the top-level `x-pack` directory. The build will fail its pre-commit
|
||||
checks if contributed code does not have the appropriate license headers.
|
||||
|
||||
You may find it helpful to configure your IDE to automatically insert the
|
||||
appropriate license header depending on the part of the project to which you are
|
||||
contributing.
|
||||
|
||||
#### IntelliJ: Copyright & Scope Profiles
|
||||
|
||||
To have IntelliJ insert the correct license, it is necessary to create to copyright profiles.
|
||||
These may potentially be called `apache2` and `commercial`. These can be created in
|
||||
`Preferences/Settings->Editor->Copyright->Copyright Profiles`. To associate these profiles to
|
||||
their respective directories, two "Scopes" will need to be created. These can be created in
|
||||
`Preferences/Settings->Appearances & Behavior->Scopes`. When creating scopes, be sure to choose
|
||||
the `shared` scope type. Create a scope, `apache2`, with
|
||||
the associated pattern of `!file[group:x-pack]:*/`. This pattern will exclude all the files contained in
|
||||
the `x-pack` directory. The other scope, `commercial`, will have the inverse pattern of `file[group:x-pack]:*/`.
|
||||
The two scopes, together, should account for all the files in the project. To associate the scopes
|
||||
with their copyright-profiles, go into `Preferences/Settings->Editor>Copyright` and use the `+` to add
|
||||
the associations `apache2/apache2` and `commercial/commercial`.
|
||||
|
||||
Configuring these options in IntelliJ can be quite buggy, so do not be alarmed if you have to open/close
|
||||
the settings window and/or restart IntelliJ to see your changes take effect.
|
||||
> **NOTE:** If you have imported the project into IntelliJ IDEA the project will
|
||||
> be automatically configured to add the correct license header to new source
|
||||
> files based on the source location.
|
||||
|
||||
### Creating A Distribution
|
||||
|
||||
|
@ -309,7 +263,7 @@ cd elasticsearch/
|
|||
To build a darwin-tar distribution, run this command:
|
||||
|
||||
```sh
|
||||
./gradlew -p distribution/archives/darwin-tar assemble --parallel
|
||||
./gradlew -p distribution/archives/darwin-tar assemble
|
||||
```
|
||||
|
||||
You will find the distribution under:
|
||||
|
@ -319,9 +273,12 @@ To create all build artifacts (e.g., plugins and Javadocs) as well as
|
|||
distributions in all formats, run this command:
|
||||
|
||||
```sh
|
||||
./gradlew assemble --parallel
|
||||
./gradlew assemble
|
||||
```
|
||||
|
||||
> **NOTE:** Running the task above will fail if you don't have a available
|
||||
> Docker installation.
|
||||
|
||||
The package distributions (Debian and RPM) can be found under:
|
||||
`./distribution/packages/(deb|rpm|oss-deb|oss-rpm)/build/distributions/`
|
||||
|
||||
|
@ -455,10 +412,6 @@ known as "transitive" dependencies".</dd>
|
|||
should not be shipped with the project because it is "provided" by the runtime
|
||||
somehow. Elasticsearch plugins use this configuration to include dependencies
|
||||
that are bundled with Elasticsearch's server.</dd>
|
||||
<dt>`bundle`</dt><dd>Only available in projects with the shadow plugin,
|
||||
dependencies with this configuration are bundled into the jar produced by the
|
||||
build. Since IDEs do not understand this configuration we rig them to treat
|
||||
dependencies in this configuration as `compile` dependencies.</dd>
|
||||
<dt>`testCompile`</dt><dd>Code that is on the classpath for compiling tests
|
||||
that are part of this project but not production code. The canonical example
|
||||
of this is `junit`.</dd>
|
||||
|
|
|
@ -20,9 +20,9 @@ To create a platform-specific build including the x-pack modules, use the
|
|||
following depending on your operating system:
|
||||
|
||||
-----------------------------
|
||||
./gradlew :distribution:archives:linux-tar:assemble --parallel
|
||||
./gradlew :distribution:archives:darwin-tar:assemble --parallel
|
||||
./gradlew :distribution:archives:windows-zip:assemble --parallel
|
||||
./gradlew :distribution:archives:linux-tar:assemble
|
||||
./gradlew :distribution:archives:darwin-tar:assemble
|
||||
./gradlew :distribution:archives:windows-zip:assemble
|
||||
-----------------------------
|
||||
|
||||
=== Running Elasticsearch from a checkout
|
||||
|
@ -51,6 +51,10 @@ recommended to configure the IDE to initiate multiple listening attempts. In cas
|
|||
is called "Auto restart" and needs to be checked. In case of Eclipse, "Connection limit" setting
|
||||
needs to be configured with a greater value (ie 10 or more).
|
||||
|
||||
NOTE: If you have imported the project into IntelliJ according to the instructions in
|
||||
link:/CONTRIBUTING.md#importing-the-project-into-intellij-idea[CONTRIBUTING.md] then a debug run configuration
|
||||
named "Debug Elasticsearch" will be created for you and configured appropriately.
|
||||
|
||||
==== Distribution
|
||||
|
||||
By default a node is started with the zip distribution.
|
||||
|
|
32
build.gradle
32
build.gradle
|
@ -43,6 +43,7 @@ apply plugin: 'nebula.info-scm'
|
|||
apply from: 'gradle/build-scan.gradle'
|
||||
apply from: 'gradle/build-complete.gradle'
|
||||
apply from: 'gradle/runtime-jdk-provision.gradle'
|
||||
apply from: 'gradle/ide.gradle'
|
||||
|
||||
// common maven publishing configuration
|
||||
allprojects {
|
||||
|
@ -181,7 +182,6 @@ allprojects {
|
|||
System.getProperty("eclipse.application") != null || // Detects gradle launched from the Eclipse compiler server
|
||||
gradle.startParameter.taskNames.contains('eclipse') || // Detects gradle launched from the command line to do eclipse stuff
|
||||
gradle.startParameter.taskNames.contains('cleanEclipse')
|
||||
isIdea = System.getProperty("idea.active") != null || gradle.startParameter.taskNames.contains('idea') || gradle.startParameter.taskNames.contains('cleanIdea')
|
||||
|
||||
// for BWC testing
|
||||
bwcVersions = versions
|
||||
|
@ -357,36 +357,6 @@ gradle.projectsEvaluated {
|
|||
}
|
||||
}
|
||||
|
||||
// intellij configuration
|
||||
allprojects {
|
||||
apply plugin: 'idea'
|
||||
|
||||
if (isIdea) {
|
||||
project.buildDir = file('build-idea')
|
||||
}
|
||||
idea {
|
||||
module {
|
||||
inheritOutputDirs = false
|
||||
outputDir = file('build-idea/classes/main')
|
||||
testOutputDir = file('build-idea/classes/test')
|
||||
|
||||
// also ignore other possible build dirs
|
||||
excludeDirs += file('build')
|
||||
excludeDirs += file('build-eclipse')
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named('cleanIdea') {
|
||||
delete 'build-idea'
|
||||
}
|
||||
}
|
||||
|
||||
idea {
|
||||
project {
|
||||
vcs = 'Git'
|
||||
}
|
||||
}
|
||||
|
||||
// eclipse configuration
|
||||
allprojects {
|
||||
apply plugin: 'eclipse'
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
import org.jetbrains.gradle.ext.Remote
|
||||
import org.jetbrains.gradle.ext.JUnit
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath "gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:0.7"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: org.jetbrains.gradle.ext.IdeaExtPlugin
|
||||
|
||||
allprojects {
|
||||
apply plugin: 'idea'
|
||||
|
||||
tasks.named('idea') {
|
||||
doFirst { throw new GradleException("Use of the 'idea' task has been deprecated. For details on importing into IntelliJ see CONTRIBUTING.md.") }
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('configureIdeaGradleJvm') {
|
||||
group = 'ide'
|
||||
description = 'Configures the appropriate JVM for Gradle'
|
||||
|
||||
doLast {
|
||||
modifyXml('.idea/gradle.xml') { xml ->
|
||||
def gradleSettings = xml.component.find { it.'@name' == 'GradleSettings' }.option[0].GradleProjectSettings
|
||||
// Remove configured JVM option to force IntelliJ to use the project JDK for Gradle
|
||||
gradleSettings.option.findAll { it.'@name' == 'gradleJvm' }.each { it.parent().remove(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('configureIdeaRunConfigs') {
|
||||
group = 'ide'
|
||||
description = 'Configures default run configuration settings'
|
||||
|
||||
doLast {
|
||||
modifyXml('.idea/workspace.xml') { xml ->
|
||||
def runManager = xml.component.find { it.'@name' == 'RunManager' }
|
||||
if (runManager == null) {
|
||||
throw new GradleException("IntelliJ 'RunManager' configuration is missing from workspace.xml. You may need to refresh your Gradle project.")
|
||||
}
|
||||
|
||||
def debugConfig = runManager.configuration.find { it.'@name' == 'Debug Elasticsearch' }
|
||||
// Enable "auto restart" on remote debug run configuration
|
||||
if (debugConfig.option.any { it.'@name' == 'AUTO_RESTART' && it.'@value' == 'true'} == false) {
|
||||
def restart = new NodeBuilder().option(name: 'AUTO_RESTART', value: 'true')
|
||||
debugConfig.append(restart)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
idea {
|
||||
project {
|
||||
vcs = 'Git'
|
||||
jdkName = '13'
|
||||
|
||||
settings {
|
||||
delegateActions {
|
||||
delegateBuildRunToGradle = false
|
||||
testRunner = 'choose_per_test'
|
||||
}
|
||||
taskTriggers {
|
||||
afterSync tasks.named('configureIdeaGradleJvm'), tasks.named('configureIdeaRunConfigs')
|
||||
}
|
||||
codeStyle {
|
||||
java {
|
||||
classCountToUseImportOnDemand = 999
|
||||
}
|
||||
}
|
||||
encodings {
|
||||
encoding = 'UTF-8'
|
||||
}
|
||||
compiler {
|
||||
parallelCompilation = true
|
||||
javac {
|
||||
generateDeprecationWarnings = false
|
||||
}
|
||||
}
|
||||
runConfigurations {
|
||||
'Debug Elasticsearch'(Remote) {
|
||||
mode = 'listen'
|
||||
host = 'localhost'
|
||||
port = 5005
|
||||
}
|
||||
defaults(JUnit) {
|
||||
vmParameters = '-Djava.locale.providers=SPI,COMPAT'
|
||||
}
|
||||
}
|
||||
copyright {
|
||||
useDefault = 'Apache'
|
||||
scopes = ['x-pack': 'Elastic']
|
||||
profiles {
|
||||
Apache {
|
||||
keyword = 'Licensed to Elasticsearch under one or more contributor'
|
||||
notice = '''\
|
||||
Licensed to Elasticsearch under one or more contributor
|
||||
license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright
|
||||
ownership. Elasticsearch licenses this file to you 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.'''.stripIndent()
|
||||
}
|
||||
Elastic {
|
||||
keyword = 'Licensed under the Elastic License'
|
||||
notice = '''\
|
||||
Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
or more contributor license agreements. Licensed under the Elastic License;
|
||||
you may not use this file except in compliance with the Elastic License.'''.stripIndent()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a given XML file, applies a set of changes, and writes those changes back to the original file.
|
||||
*
|
||||
* @param path Path to existing XML file
|
||||
* @param action Action to perform on parsed XML document
|
||||
*/
|
||||
void modifyXml(Object path, Action<? super Node> action) {
|
||||
File xmlFile = project.file(path)
|
||||
Node xml = new XmlParser().parse(xmlFile)
|
||||
action.execute(xml)
|
||||
|
||||
xmlFile.withPrintWriter { writer ->
|
||||
new XmlNodePrinter(writer).print(xml)
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ apply plugin: 'nebula.maven-scm'
|
|||
archivesBaseName = 'elasticsearch-core'
|
||||
|
||||
// we want to keep the JDKs in our IDEs set to JDK 8 until minimum JDK is bumped to 9 so we do not include this source set in our IDEs
|
||||
if (!isEclipse && !isIdea) {
|
||||
if (!isEclipse) {
|
||||
sourceSets {
|
||||
java9 {
|
||||
java {
|
||||
|
@ -82,7 +82,7 @@ dependencies {
|
|||
testCompile "junit:junit:${versions.junit}"
|
||||
testCompile "org.hamcrest:hamcrest:${versions.hamcrest}"
|
||||
|
||||
if (!isEclipse && !isIdea) {
|
||||
if (!isEclipse) {
|
||||
java9Compile sourceSets.main.output
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ publishing {
|
|||
archivesBaseName = 'elasticsearch'
|
||||
|
||||
// we want to keep the JDKs in our IDEs set to JDK 8 until minimum JDK is bumped to 9 so we do not include this source set in our IDEs
|
||||
if (!isEclipse && !isIdea) {
|
||||
if (!isEclipse) {
|
||||
sourceSets {
|
||||
java9 {
|
||||
java {
|
||||
|
@ -82,7 +82,7 @@ dependencies {
|
|||
compile project(":libs:elasticsearch-geo")
|
||||
|
||||
compileOnly project(':libs:elasticsearch-plugin-classloader')
|
||||
testRuntime project(':libs:elasticsearch-plugin-classloader')
|
||||
testRuntimeOnly project(':libs:elasticsearch-plugin-classloader')
|
||||
|
||||
// lucene
|
||||
compile "org.apache.lucene:lucene-core:${versions.lucene}"
|
||||
|
@ -123,7 +123,7 @@ dependencies {
|
|||
// repackaged jna with native bits linked against all elastic supported platforms
|
||||
compile "org.elasticsearch:jna:${versions.jna}"
|
||||
|
||||
if (!isEclipse && !isIdea) {
|
||||
if (!isEclipse) {
|
||||
java9Compile sourceSets.main.output
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue