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

Add support for Eclipse 4.8 test source sets in the classpath file #4802

Open
danielkaneider opened this Issue Mar 22, 2018 · 6 comments

Comments

Projects
None yet
5 participants
@danielkaneider

danielkaneider commented Mar 22, 2018

Eclipse 4.8 M5 added support for test sources (https://www.eclipse.org/eclipse/news/4.8/M5/#JDT). It would be nice if gradle eclipse generation could mark the corresponding entries in the .classpath files as such. This could be done among others for source folders, output folders and referenced libraries.

@danielkaneider danielkaneider changed the title from Add support for Eclipse test source sets in the classpath file to Add support for Eclipse 4.8 test source sets in the classpath file Mar 22, 2018

@howlger

This comment has been minimized.

Show comment
Hide comment
@howlger

howlger Jun 11, 2018

The following build.gradle snippet works for me as a workaround for this issue in Eclipse Photon RC2:

apply plugin: 'eclipse'
eclipse.classpath.file.whenMerged {

	// separate output folders required to set the 'test' attribute
	entries.find { it.path == 'src/main/java' }.output = 'bin/main'
	def testSrc = entries.find { it.path == 'src/test/java' }
	testSrc.output = 'bin/test'
	testSrc.entryAttributes['test'] = 'true'

	// libraries visible for test sources only?
	entries.forEach { entry ->
		def entryIn = { it.find { file(entry.path).equals(it) } }
		if (entry.kind == 'lib') {
			entry.entryAttributes['test'] =
				entryIn(configurations.testRuntimeClasspath) &&
				!entryIn(configurations.runtimeClasspath)
		}
	}

}

howlger commented Jun 11, 2018

The following build.gradle snippet works for me as a workaround for this issue in Eclipse Photon RC2:

apply plugin: 'eclipse'
eclipse.classpath.file.whenMerged {

	// separate output folders required to set the 'test' attribute
	entries.find { it.path == 'src/main/java' }.output = 'bin/main'
	def testSrc = entries.find { it.path == 'src/test/java' }
	testSrc.output = 'bin/test'
	testSrc.entryAttributes['test'] = 'true'

	// libraries visible for test sources only?
	entries.forEach { entry ->
		def entryIn = { it.find { file(entry.path).equals(it) } }
		if (entry.kind == 'lib') {
			entry.entryAttributes['test'] =
				entryIn(configurations.testRuntimeClasspath) &&
				!entryIn(configurations.runtimeClasspath)
		}
	}

}
@eric-milles

This comment has been minimized.

Show comment
Hide comment
@eric-milles

eric-milles Jul 25, 2018

Current gradle/eclipse plug-in is separating output paths and so I was able to accomplish the same with:

eclipse.classpath.file.whenMerged {
  entries.findAll { entry ->
    entry.class.name in [
      'org.gradle.plugins.ide.eclipse.model.Library',
      'org.gradle.plugins.ide.eclipse.model.SourceFolder'
    ]
  }.each { entry ->
    if (entry.entryAttributes['gradle_used_by_scope'] == 'test') {
      entry.entryAttributes['test'] = 'true'
    }
  }
}

eric-milles commented Jul 25, 2018

Current gradle/eclipse plug-in is separating output paths and so I was able to accomplish the same with:

eclipse.classpath.file.whenMerged {
  entries.findAll { entry ->
    entry.class.name in [
      'org.gradle.plugins.ide.eclipse.model.Library',
      'org.gradle.plugins.ide.eclipse.model.SourceFolder'
    ]
  }.each { entry ->
    if (entry.entryAttributes['gradle_used_by_scope'] == 'test') {
      entry.entryAttributes['test'] = 'true'
    }
  }
}
@liblit

This comment has been minimized.

Show comment
Hide comment
@liblit

liblit Jul 25, 2018

@eric-milles, which specific Gradle version, Eclipse version, and Eclipse Buildship plug-in version are you using?

I tried your suggestion with Gradle 4.9, Eclipse 4.8.0 (Photon), and Buildship 2.2.1.v20180125-1441. I am working with a complex Gradle-based project that includes many subprojects, so I wrapped your entire Gradle fragment inside an allprojects { ... } block to include those many subprojects:

allprojects {
  eclipse.classpath.file.whenMerged {
    entries.findAll { entry ->
      entry.class.name in [
        'org.gradle.plugins.ide.eclipse.model.Library',
        'org.gradle.plugins.ide.eclipse.model.SourceFolder'
      ]
    }.each { entry ->
      if (entry.entryAttributes['gradle_used_by_scope'] == 'test') {
        entry.entryAttributes['test'] = 'true'
      }
    }
  }
}

Unfortunately, this did not do anything useful. Every entry considered by entries.findAll had dynamic type org.gradle.plugins.ide.eclipse.model.Output. There were no Library or SourceFolder entries, which therefore left nothing for the .each { ... } stage to operate on, so nothing was marked as being test code.

liblit commented Jul 25, 2018

@eric-milles, which specific Gradle version, Eclipse version, and Eclipse Buildship plug-in version are you using?

I tried your suggestion with Gradle 4.9, Eclipse 4.8.0 (Photon), and Buildship 2.2.1.v20180125-1441. I am working with a complex Gradle-based project that includes many subprojects, so I wrapped your entire Gradle fragment inside an allprojects { ... } block to include those many subprojects:

allprojects {
  eclipse.classpath.file.whenMerged {
    entries.findAll { entry ->
      entry.class.name in [
        'org.gradle.plugins.ide.eclipse.model.Library',
        'org.gradle.plugins.ide.eclipse.model.SourceFolder'
      ]
    }.each { entry ->
      if (entry.entryAttributes['gradle_used_by_scope'] == 'test') {
        entry.entryAttributes['test'] = 'true'
      }
    }
  }
}

Unfortunately, this did not do anything useful. Every entry considered by entries.findAll had dynamic type org.gradle.plugins.ide.eclipse.model.Output. There were no Library or SourceFolder entries, which therefore left nothing for the .each { ... } stage to operate on, so nothing was marked as being test code.

@eric-milles

This comment has been minimized.

Show comment
Hide comment
@eric-milles

eric-milles Jul 25, 2018

@liblit I also have Gradle 4.9, Eclipse 4.8.0, Buildship 2.2.1. My project is very simple and the .classpath looks like this:

<classpath>
	<classpathentry kind="src" output="bin/main" path="src/main/groovy">
		<attributes>
			<attribute name="gradle_scope" value="main"/>
			<attribute name="gradle_used_by_scope" value="main,test"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="src" output="bin/main" path="src/main/java">
		<attributes>
			<attribute name="gradle_scope" value="main"/>
			<attribute name="gradle_used_by_scope" value="main,test"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="src" output="bin/test" path="src/test/java">
		<attributes>
			<attribute name="gradle_scope" value="test"/>
			<attribute name="gradle_used_by_scope" value="test"/>
			<attribute name="test" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
	<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
	<classpathentry kind="output" path="bin/default"/>
</classpath>

eric-milles commented Jul 25, 2018

@liblit I also have Gradle 4.9, Eclipse 4.8.0, Buildship 2.2.1. My project is very simple and the .classpath looks like this:

<classpath>
	<classpathentry kind="src" output="bin/main" path="src/main/groovy">
		<attributes>
			<attribute name="gradle_scope" value="main"/>
			<attribute name="gradle_used_by_scope" value="main,test"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="src" output="bin/main" path="src/main/java">
		<attributes>
			<attribute name="gradle_scope" value="main"/>
			<attribute name="gradle_used_by_scope" value="main,test"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="src" output="bin/test" path="src/test/java">
		<attributes>
			<attribute name="gradle_scope" value="test"/>
			<attribute name="gradle_used_by_scope" value="test"/>
			<attribute name="test" value="true"/>
		</attributes>
	</classpathentry>
	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
	<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
	<classpathentry kind="output" path="bin/default"/>
</classpath>
@liblit

This comment has been minimized.

Show comment
Hide comment
@liblit

liblit Jul 25, 2018

Here is my version of @eric-millesʼs approach that works with subprojects as well:

allprojects {
  apply plugin: 'eclipse'

  eclipse.classpath.file.whenMerged {
    entries.each {
      if (it in org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry && it.entryAttributes['gradle_used_by_scope'] == 'test')
        it.entryAttributes['test'] = true
    }
  }
}

liblit commented Jul 25, 2018

Here is my version of @eric-millesʼs approach that works with subprojects as well:

allprojects {
  apply plugin: 'eclipse'

  eclipse.classpath.file.whenMerged {
    entries.each {
      if (it in org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry && it.entryAttributes['gradle_used_by_scope'] == 'test')
        it.entryAttributes['test'] = true
    }
  }
}
@eric-milles

This comment has been minimized.

Show comment
Hide comment
@eric-milles

eric-milles Jul 25, 2018

I used explicit checks for Library and SourceFolder because I was unsure if Container, Variable and ProjectDependency should have this applied.

eric-milles commented Jul 25, 2018

I used explicit checks for Library and SourceFolder because I was unsure if Container, Variable and ProjectDependency should have this applied.

liblit added a commit to liblit/WALA that referenced this issue Jul 25, 2018

Categorize Eclipse sources as main vs. test
This leverages new Eclipse 4.8 (Photon) features that distinguish main
code from test code:
<https://www.eclipse.org/photon/noteworthy/index.php#test-sources>.
An eventual fix to <gradle/gradle#4802>
might mean that Buildship starts doing this automatically, but for now
we can do it ourselves.

If using an older Eclipse release, this change does nothing useful,
but neither does it cause any harm.

msridhar added a commit to wala/WALA that referenced this issue Jul 30, 2018

Categorize Eclipse sources as main vs. test
This leverages new Eclipse 4.8 (Photon) features that distinguish main
code from test code:
<https://www.eclipse.org/photon/noteworthy/index.php#test-sources>.
An eventual fix to <gradle/gradle#4802>
might mean that Buildship starts doing this automatically, but for now
we can do it ourselves.

If using an older Eclipse release, this change does nothing useful,
but neither does it cause any harm.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment