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

Add support for gradle file editing #1125

Open
gayanper opened this issue Jun 9, 2020 · 14 comments
Open

Add support for gradle file editing #1125

gayanper opened this issue Jun 9, 2020 · 14 comments

Comments

@gayanper
Copy link

gayanper commented Jun 9, 2020

Today in eclipse buildship team is not providing gradle file editing support pointing this project doesn't support well. I would like to request to have support for gradle file from this project if build ship is not intrested.

From what i understand we need to have a classpath for a give gradle file based on

  1. gradle API
  2. plugin jars in the build script

I think if we can have support to add a custom classpath for a groovy file editor and open it we can achieve some support for gradle file editing.

@eric-milles
Copy link
Member

The classpath issue is the biggest hurdle. You can get some basic editor support by adding "gradleApi()" in your dependencies block. Here are some issues related to that:

eclipse/buildship#547
gradle/gradle#1003
gradle/gradle#6089

You can add a dsld script to your project like this (the is poc/alpha stuff):

package dsld

def isBuildScript = fileExtension('gradle') & (~fileName('settings.gradle'))

contribute(isBuildScript & isThisType()) {
  delegatesTo 'org.gradle.api.Project'

  method name: 'apply', type: void, params: [block: Closure]
  method name: 'apply', type: void, namedParams: [plugin: String, from: Object, to: Object]
  method name: 'apply', type: void, params: [action: 'org.gradle.api.Action<? super org.gradle.api.plugins.ObjectConfigurationAction>']
}

contribute(isBuildScript & enclosingCallName('configurations') & inClosure() & currentType('org.gradle.api.Project')) {
  setDelegateType('org.gradle.api.artifacts.ConfigurationContainer')
}

contribute(isBuildScript & enclosingCallName('dependencies') & inClosure() & currentType('org.gradle.api.Project')) {
  setDelegateType('org.gradle.api.artifacts.dsl.DependencyHandler')
}

contribute(isBuildScript & enclosingCallName('repositories') & inClosure() & currentType('org.gradle.api.Project')) {
  setDelegateType('org.gradle.api.artifacts.dsl.RepositoryHandler')
}

contribute(fileName('settings.gradle') & isThisType()) {
  setDelegateType('org.gradle.api.initialization.Settings')
}



/* https://github.com/gluck/gradle-scripts/blob/master/GradleDSLD.dsld.custom
artifacts 'org.gradle.api.artifacts.dsl.ArtifactHandler'
install, upload  'org.gradle.api.tasks.Upload'
task 'org.gradle.api.Task'
clean 'org.gradle.api.tasks.Delete'

block('org.gradle.api.tasks.Upload', 'repositories') {
  setDelegateType 'org.gradle.api.artifacts.dsl.RepositoryHandler'
  delegatesTo 'org.gradle.api.plugins.MavenRepositoryHandlerConvention'
  collectOuterScope(scope).each {
    delegatesTo it
  }
}
blockSetDelegateType 'org.gradle.api.plugins.MavenRepositoryHandlerConvention', 'mavenInstaller', 'org.gradle.api.artifacts.maven.MavenResolver'
blockSetDelegateType 'org.gradle.api.plugins.MavenRepositoryHandlerConvention', 'mavenDeployer', 'org.gradle.api.artifacts.maven.GroovyMavenDeployer'

rootBlockSetDelegateType 'eclipse'       , 'org.gradle.plugins.ide.eclipse.model.EclipseModel'
blockSetDelegateType 'org.gradle.plugins.ide.eclipse.model.EclipseModel', 'classpath', 'org.gradle.plugins.ide.eclipse.model.EclipseClasspath'
blockSetDelegateType 'org.gradle.plugins.ide.eclipse.model.EclipseClasspath', 'file', 'org.gradle.plugins.ide.api.XmlFileContentMerger'

rootBlockSetDelegateType 'idea'          , 'org.gradle.plugins.ide.idea.model.IdeaModel'

// requires gradle-plugins-1.2.jar & sources
rootBlockSetDelegateType 'javadoc'       ,'org.gradle.api.tasks.javadoc.Javadoc'
rootBlockSetDelegateType 'groovydoc'     ,'org.gradle.api.tasks.javadoc.Groovydoc'

// requires gradle-scala-1.2.jar & sources
rootBlockSetDelegateType 'scaladoc'       ,'org.gradle.api.tasks.scala.ScalaDoc'

// requires gradle-signing-1.2.jar & sources
rootBlockSetDelegateType 'signing'        ,'org.gradle.plugins.signing.SigningExtension'
*/

@gayanper
Copy link
Author

gayanper commented Nov 5, 2020

I was thinking if we can provide virtual project when opening a gradle file in groovy editor and include this dsl and the gradle api dependencies ? Do you think that's possible ?

@eric-milles
Copy link
Member

You can try out the DSLD now by adding it to your ~/.groovy/greclipse/global_dsld_support directory and adding gradleApi() to the dependencies block of your gradle script. If the DSLD gets to a sufficient point of capability, then we can explore how to integrate it and bootstrap its dependencies. I may have tried @Grab within a DLSD to add library references; I can't remember the outcome of the experiment.

@gayanper
Copy link
Author

@eric-milles i tried you suggestion. But it seems like the dsl file isn’t getting loaded. For example blocks like dependencies and properties of dependencies block is not completing. And when i check the dsld settings window I cannot see the global dsld i added either

@eric-milles
Copy link
Member

it seems like the dsl file isn’t getting loaded

If you add a DSLD to the global folder, you need to restart Eclipse or run Window > Preferences > Groovy > DSLD > Recompile Scripts.

@eric-milles
Copy link
Member

Once a DSLD is accepted, you can look at Console view > New toolbar button > Groovy Event Console to see the compiler's logging. If you add log statements in your DSLD this is where you would see them.

@gayanper
Copy link
Author

gayanper commented Nov 25, 2020

@eric-milles i added the file content at ~/.groovy/greclipse/global_dsld_support/gradle.dsld

But this how the eclipse settings look like
Screenshot 2020-11-25 at 20 50 45

And following is my gradle file

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java Library project to get you started.
 * For more details take a look at the Java Libraries chapter in the Gradle
 * User Manual available at https://docs.gradle.org/6.3/userguide/java_library_plugin.html
 */

plugins {
    // Apply the java-library plugin to add support for Java Library
    id 'java-library'
}

repositories {
    // Use jcenter for resolving dependencies.
    // You can declare any Maven/Ivy/file repository here.
    jcenter()
}

dependencies {
	gradleApi()
    // This dependency is exported to consumers, that is to say found on their compile classpath.
    api 'org.apache.commons:commons-math3:3.6.1'

    // This dependency is used internally, and not exposed to consumers on their own compile classpath.
    implementation 'com.google.guava:guava:28.2-jre'

    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'
}

I still don't get gradle specific completions.

@gayanper
Copy link
Author

I even tried converting the project into a groovy project as well. But it didn't work.

@eric-milles
Copy link
Member

eric-milles commented Nov 26, 2020

gradleApi() is a pseudo-dependency (or whatever the term is). You still need to put a specifier in front of it. I would probably use implementation gradleApi(). Your project should also have the Groovy DSL Support classpath container. You can open the Groovy Event Console before you try the Recompile Scripts button to see the compiler's progress when it tries to compile them.

@eric-milles
Copy link
Member

eric-milles commented Nov 26, 2020

For a single project, you can just place the DSLD in a source folder like this:
image

Either way, it will show on the DSLD preference panel when it has been accepted.

Note: I don't think it is required to be in the dsld package. That is more of a convention.

@gayanper
Copy link
Author

Nice it is working now.
But seems like the completions inside the dependency and repository like closures are not working. How can we get those to work ? And how can we add this dsld classpath and groovy nature and gradle api into project classpath when opening a gradle file ? I was hoping if we are capable of having a virtual project with this setup to be used underneath when opening a gradle file.

@eric-milles
Copy link
Member

For now, I'd stick with enhancing the DSLD so that you get the experience you are looking for. If you can't get there, all the bootstrapping is unneeded. Can you show a quick screenshot of what you have and describe what kind of completion proposals you are expecting?

@gayanper
Copy link
Author

In the below i'm expecting to get completions for api and implementation
Screenshot 2020-11-27 at 17 33 12

below i'm expecting for completions of mavenCentral, maven blocks like https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:declaring_multiple_repositories

Screenshot 2020-11-27 at 17 33 48

@eric-milles
Copy link
Member

For dependencies you can hover over and it should display a type or method. This indicates that the DSLDTypeLookup knowns something about it. In terms of code completion within the block, you need to look at org.gradle.api.artifacts.dsl.DependencyHandler (the delegate type according to the DSLD). What fields and methods does it expose? Those should be available within the block.

If there are items you want for completion beyond what the delegate type offers, then more DSLD script will be required. For example, adding "method name:'jcenter', type:void, parameters:[]" inside the "contribute(isBuildScript & enclosingCallName('dependencies') ..." closure would enable the jcenter method.

The DSLD given in the second comment is a skeleton. There will be much more script required to provide for a typical gradle build script.

@groovy groovy deleted a comment from gayanper Nov 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants