Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move custom gradle configs into custom plugins #721

Merged
merged 7 commits into from
Nov 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
bin/
bin_test/
buildSrc/build
buildSrc/.gradle
/.idea/*.iws
/.idea/tasks.xml
/.idea/workspace.xml
Expand Down
2 changes: 2 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 13 additions & 49 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,16 @@ buildscript
}

plugins {
id "de.monkeyworks.buildmonkey.mavenizer.MavenizerPlugin" version "0.4.2"
id 'com.gradle.build-scan' version '2.4.1'
}

// avoid that the buildmonkey plugin triggers verbose ant logging
ant.lifecycleLogLevel = "ERROR"

// Use gradle scan plugin and service in order to visualize build/test failures
buildScan {
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
termsOfServiceAgree = 'yes'
publishOnFailure()
}

// Configuration that leads to the conversion of the eclipse home dir
// (which is also a P2 repository) to a maven repository.
mavenize {
mavenizeTask {
useP2MirrorOutput = false
sourceP2Repository = System.getenv('ECLIPSE_HOME')
targetDir = rootProject.file('build/maven')
groupId = 'eclipse-deps'
}
}

// Adjust Intellij module configuration for all sub-projects
configure(subprojects) {projectToConf->
Expand All @@ -47,21 +33,16 @@ configure(subprojects) {projectToConf->


ext.projectsToConfigure = subprojects - project(':saros.picocontainer')

// Configurations that are specific to all subprojects
configure(projectsToConfigure) { projectToConf ->

apply plugin: 'eclipse'
apply plugin: 'java' // default java build plugin
apply plugin: 'jacoco' // code coverage tool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this now defined somewhere else? Or did you just remove it as it never was configured correctly?

apply plugin: 'saros.gradle.eclipse.plugin'
tobous marked this conversation as resolved.
Show resolved Hide resolved

repositories {
// general purpose repository
mavenCentral()
// repositories for specific artifacts
maven {
url 'http://maven-eclipse.github.io/maven'
content { includeGroup 'org.eclipse.swt' }
}
}

configurations {
Expand All @@ -76,6 +57,7 @@ configure(projectsToConfigure) { projectToConf ->

// Exclude test suites if property is set. Otherwise tests are executed multiple times
// in the ci server (via test class and suite).
// see gradle.properties for default values
if (projectToConf.hasProperty('skipTestSuites') && skipTestSuites.equalsIgnoreCase("true")) {
exclude '**/*TestSuite*'
}
Expand All @@ -89,6 +71,7 @@ configure(projectsToConfigure) { projectToConf ->
exclude 'saros/stf/test/stf/*'
}

// Don't execute abstract test classes
exclude '**/Abstract*'

testLogging {
Expand All @@ -99,14 +82,16 @@ configure(projectsToConfigure) { projectToConf ->

projectToConf.ext.junitVersion = 'junit:junit:4.12'
projectToConf.ext.log4jVersion = 'log4j:log4j:1.2.15'

dependencies {
compile (log4jVersion) {
projectToConf.ext.addLog4JDependency = { config ->
config.dependencies.add(dependencies.create('log4j:log4j:1.2.15') {
exclude group: 'com.sun.jmx', module: 'jmxri'
exclude group: 'com.sun.jdmk', module: 'jmxtools'
exclude group: 'javax.jms', module: 'jms'
}
})
}

dependencies {
addLog4JDependency(configurations.testConfig)
testConfig junitVersion
testConfig 'org.easymock:easymock:3.5.1'
testConfig 'org.powermock:powermock-core:2.0.0'
Expand All @@ -123,37 +108,17 @@ configure(projectsToConfigure) { projectToConf ->
from projectToConf.configurations.releaseDep
}

projectToConf.ext.eclipseHome = projectToConf.hasProperty('eclipseHome') ? eclipseHome : System.getenv('ECLIPSE_HOME')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that the developer can no longer use the local eclipse version to build/run the plugin? Is this due to complications in the eclipse build process that required the "Mavenize" job in the previous setup?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means that the developers don't have to use a local eclipse installation in order to build the eclipse plugin. You still need a local installation in order to run the plugin (which would be the next step of the infrastructure improvement). This has the advantage that you don't need to install eclipse if you want to build all projects in your ide without problems.
If you want to use a specific eclipse version for build and testing you can set the value:

sarosEclipse {
  eclipseVersion = <version string>
}

Is this due to complications in the eclipse build process that required the "Mavenize" job in the previous setup?

The previous setup was necessary, because the eclipse bundles were not available via maven central, but the bundle are now deployed into maven central (by the eclipse project itself). Therefore, we don't need the weird setup of converting an eclipse installation (more specific the P2 repository) into a local maven repository. The only bundle that is not available via maven central is gef (because it is not part of the default bundles)

Copy link
Member

@tobous tobous Oct 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this also means that I have to download the eclipse libraries even if I just want to develop the core and IntelliJ stuff, doesn't it?

On the other hand, @stefaus was complaining that he had to download the IntelliJ sources when running the new gradle setup. This always takes a while as the download server don't seem to be the best.

Would it maybe be possible to only pull these dependencies when they actually are required (i.e. the first time a job is run that requires them)? This wouldn't really matter for the people that want to use them, as they have to download them anyways, but it avoids developers having to wait a couple of minutes for a download of resources that they don't want or need.

projectToConf.ext.intellijHome = projectToConf.hasProperty('intellijHome') ? intellijHome : System.getenv('INTELLIJ_HOME')

// In order to use the relocated shadowJar of picocontainer it is necessary to replace
// the eclipse classpath entry that points to the sources of saros.picocontainer with
// the reference to the reloacted jar
eclipse.classpath {
file {
whenMerged { classpath ->
classpath.entries.removeAll{ it.path.contains('saros.picocontainer')}
}
withXml {
String jarPath = project(':saros.picocontainer').configurations.getByName('shadow').artifacts.first().file
it.asNode().appendNode('classpathentry', [kind: 'lib', path: jarPath])
.appendNode('attributes')
.appendNode('attribute', [name: 'gradle_used_by_scope', value: 'main,test'])
}
}
}
projectToConf.ext.intellijSandboxDir = System.getenv('SAROS_INTELLIJ_SANDBOX')
}


// remove all build dirs. The frontend package has no build directory
task cleanAll(dependsOn: projectsToConfigure.collect{":${it.name}:clean"} << 'clean')
task cleanAll(dependsOn: projectsToConfigure.collect{":${it.name}:clean"})

ext.projectsToPrepare = projectsToConfigure + project(':saros.picocontainer')
task prepareEclipse(dependsOn: projectsToPrepare.collect { [":${it.name}:cleanEclipseProject", ":${it.name}:cleanEclipseClasspath"] }.flatten() +
projectsToPrepare.collect { [":${it.name}:eclipseProject", ":${it.name}:eclipseClasspath"]}.flatten() +
['mavenizeP2Repository', 'generateLibAll'])

task prepareIntellij(dependsOn: ['mavenizeP2Repository'])
['generateLibAll'])

task cleanGenerateLibAll {
doLast {
Expand All @@ -174,7 +139,6 @@ task generateLibAll(dependsOn:['cleanGenerateLibAll',
':saros.whiteboard:generateLib'])

task sarosEclipse(type: Copy, dependsOn: [
'mavenizeP2Repository',
':saros.picocontainer:test',
':saros.core:test',
':saros.eclipse:test',
Expand Down
37 changes: 37 additions & 0 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
buildscript {
repositories {
mavenCentral()
maven {
url 'https://plugins.gradle.org/m2/'
}
}

}

plugins {
id 'java-gradle-plugin'
}

repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}

dependencies {
compile 'com.diffplug.gradle:goomph:3.18.1'
compile 'gradle.plugin.org.jetbrains.intellij.plugins:gradle-intellij-plugin:0.4.10'
}

gradlePlugin {
plugins {
eclipsePlugin {
id = 'saros.gradle.eclipse.plugin'
implementationClass = 'saros.gradle.eclipse.SarosEclipsePlugin'
}
intellijPlugin {
id = 'saros.gradle.intellij.plugin'
implementationClass = 'saros.gradle.intellij.SarosIntellijPlugin'
}
}
}
100 changes: 100 additions & 0 deletions buildSrc/src/main/java/saros/gradle/eclipse/SarosEclipseExtension.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package saros.gradle.eclipse;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
* Gradle extension that contains the configurable properties of the custom gradle plugin. The
* provided setter and getters are used implicitly by gradle.
*
* <p>Furthermore, the class provides methods in order to perfom common action for osgi bundle
* consumption and creation
*
* <p>Example gradle configuration that uses dependencies defined by a manfiest and excludes some
* dependencies from resultion:
*
* <pre>
* sarosEclipse {
* manifest = "META-INF/MANIFEST.MF" as File // Uses the setManifest(File manifest) method
* excludeManifestDependencies = ["org.eclipse.ui", "saros.core"]
* addDependencies()
* }
* </pre>
*/
public class SarosEclipseExtension {
tobous marked this conversation as resolved.
Show resolved Hide resolved
private File manifest = null;
private String eclipseVersion = "4.6.3";
private List<String> excludeManifestDependencies = new ArrayList<>();
private boolean addDependencies = false;
private boolean addPdeNature = false;
private boolean createBundleJar = false;

public File getManifest() {
tobous marked this conversation as resolved.
Show resolved Hide resolved
return manifest;
}

/**
* Set the manifest file which is required to use createBundleJar (because a manifest is required
* in order to create a valid osgi bundle) and addDependencies (because the dependencies have to
* be specified in the manifest). Therefore, set the manifest before using addDependencies or
* createBundleJar!
*
* @param manifest The java/osgi manifest file of the project
*/
public void setManifest(File manifest) {
tobous marked this conversation as resolved.
Show resolved Hide resolved
this.manifest = manifest;
}

public String getEclipseVersion() {
return eclipseVersion;
}

/**
* Set the eclipse version which is used in order resolve the bundle dependencies during
* addDependencies. Therefore, set the version before using addDependencies if you want to use
* another version than the default version!
*/
public void setEclipseVersion(String eclipseVersion) {
this.eclipseVersion = eclipseVersion;
}

public List<String> getExcludeManifestDependencies() {
return excludeManifestDependencies;
}

/**
* Set an exclude list of bundles which are excluded from the manifest specified by {@code
* setManifest(File manifest)} and resolved by {@code addDependencies()}. Therefore, set the list
* before {@code addDependencies()} if you want to exclude bundles!
*
* @param manifestDepExcludes The list of bundle ids which should be excluded from the manifest.
*/
public void setExcludeManifestDependencies(List<String> manifestDepExcludes) {
this.excludeManifestDependencies = manifestDepExcludes;
}

public boolean isAddDependencies() {
return addDependencies;
}

public void setAddDependencies(boolean addDependencies) {
this.addDependencies = addDependencies;
}

public boolean isAddPdeNature() {
return addPdeNature;
}

public void setAddPdeNature(boolean addPdeNature) {
this.addPdeNature = addPdeNature;
}

public boolean isCreateBundleJar() {
return createBundleJar;
}

public void setCreateBundleJar(boolean createBundleJar) {
this.createBundleJar = createBundleJar;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package saros.gradle.eclipse;

import org.gradle.api.GradleException;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import saros.gradle.eclipse.configurator.EclipseConfigurator;
import saros.gradle.eclipse.configurator.JarConfigurator;
import saros.gradle.eclipse.configurator.OsgiDependencyConfigurator;

/**
* Plugin that provides the default saros specific default configurations of the eclipse plugin and
* provides methods in order to perform common configuration tasks.
*/
public class SarosEclipsePlugin implements Plugin<Project> {
private static final String EXTENSION_NAME = "sarosEclipse";

/**
* Method which is called when the plugin is integrated in a gradle build (e.g. with {@code apply
* plugin: saros.gradle.eclipse.plugin})
*/
@Override
public void apply(Project project) {
// We just configure other plugins and their corresponding tasks. Therefore, we
// don't create custom tasks.
SarosEclipseExtension e =
project.getExtensions().create(EXTENSION_NAME, SarosEclipseExtension.class);
project.afterEvaluate(p -> configureEclipseAfterEvaluate(p, e));
}

/**
* Method that applies the configurations which are configured in the build.gradle file. This
* method has to be executed after the evaluation of the build files is completed. Otherwise an
* intermediate state of the extensions are used.
*/
private void configureEclipseAfterEvaluate(Project p, SarosEclipseExtension e) {
EclipseConfigurator eclipseConfigurator = new EclipseConfigurator(p);
eclipseConfigurator.usePatchedPicocontainer();
if (e.isAddPdeNature()) {
eclipseConfigurator.addPdeNature();
}

if (e.isCreateBundleJar()) {
methodRequiresManifest("createBundleJar", e);
new JarConfigurator(p).createBundleJar(e.getManifest());
}

if (e.isAddDependencies()) {
methodRequiresManifest("addDependencies", e);
new OsgiDependencyConfigurator(p)
.addDependencies(
e.getManifest(), e.getExcludeManifestDependencies(), e.getEclipseVersion());
}
}

private void methodRequiresManifest(String methodName, SarosEclipseExtension e) {
if (e.getManifest() == null)
throw new GradleException(
"Unable to apply method "
+ methodName
+ " as long as no manifest is provided. Please set the manifest before calling "
+ methodName
+ ".");
}
}