Skip to content

Load Eclipse configuration from JAR classpath. #744

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

Closed
budjb opened this issue Dec 4, 2020 · 6 comments
Closed

Load Eclipse configuration from JAR classpath. #744

budjb opened this issue Dec 4, 2020 · 6 comments
Labels

Comments

@budjb
Copy link

budjb commented Dec 4, 2020

I've looked at another issue that was reported here regarding this topic, but I don't think there's a clear answer of how to include an Eclipse configuration from a JAR.

I am specifically trying to create a standard code formatting posture as a Gradle plugin that we can include in projects. The custom Gradle plugin will configure spotless and include a custom Eclipse config and a license header template. I've given options for consumers of the plugin to define their own custom configuration files, but if that configuration is not given, I want to use the default versions I've bundled in the plugin, which would come from the classpath.

I am not quite sure how to provide the default files included in the JAR as configuration to spotless. Is there a known way to do this, or is this even supported?

@budjb
Copy link
Author

budjb commented Dec 4, 2020

This is what I am currently trying to configure eclipse:

java {
    eclipse().configFile project.resources.text.fromUri(getClass().classLoader.getResource('ilm-format-default-configs/eclipse.xml')).asFile()
}

... which gives me the following error:

Caused by: java.lang.IllegalArgumentException: The file name extension 'txt' is not part of the supported file extensions [[LINE_ORIENTED, XML]].

@nedtwigg
Copy link
Member

nedtwigg commented Dec 4, 2020

Eclipse can store its preferences in two different formats: as an xml file with a .xml extension, or as a java-properties file with any extension. I think Eclipse uses the file extension to decide how to parse it, and it looks like you are taking eclipse.xml, and .asFile() is writing it as a temporary file with .txt extension.

You can probably fix this by taking the File that .asFile() returns and copying or renaming it. I am not a fan of the project.resources API. It clobbers file extensions, creates lots of temporary files and disk I/O on every run, these temp files can break up-to-date checking and buildcache keys, and when it fails it is hard to debug. I have had a lot of success using blowdryer to solve all of these problems, but YMMV.

@budjb
Copy link
Author

budjb commented Dec 4, 2020

So I've also tried to copy that file out of the JAR into the build directory, and pass the path to the resulting file to spotless without problem. That is, unless I clean the project as part of a chain of task targets (such as ./gradlew clean war). I have to copy that file as part of my plugin's configuration phase, as I can't seem to find a spotless task to hook onto before an internal spotless task fails trying to load a file that does not exist (spotlessInternalRegisterDependencies specifically). If there was a task that ran before this one, even if it was a no-op task, my problem would be solved. Is there some task that exists that I can make depend on my own task that pulls my config files out of the JAR?

I've taken a look at blowdryer, but it seems to be heavily focused on pulling configurations from a web URL, mainly git. Does that plugin support pulling files from JAR files?

@nedtwigg
Copy link
Member

nedtwigg commented Dec 4, 2020

it seems to be heavily focused on pulling configurations from a web URL, mainly git.

  • do you develop your build plugin using git?
  • if so, do you tag releases of your build plugin?
  • if so, then you can use blowdryer, and it won't matter whether it's coming from the jar or from your git host
  • the advantage of this approach is that you don't have to actually publish a jar of your in-house build plugin, just tagging it is good enough.
    • but you can still publish the jar if you want, and that can be useful for adding logic too complex for a single .gradle script
    • if you don't trust that the tagged source code is the same as the content of your jar, that is a problem to be solved quickly :)

If there was a task that ran before this one, even if it was a no-op task, my problem would be solved.

spotlessInternalRegisterDependencies doesn't use the file. Adding another task before spotlessInternalRegisterDependencies will have the same problem. Gradle configures every task which it will need before any of them are executed. And that file is needed at configure time so that Gradle can do up-to-date checks. You can't set these properties as a task output, they have to be set during configure time. That is why project.resources is such an expensive and slow way to get the configuration file. You can do it that way, but it can't be lazy - you have to write and copy a temp file and every single build invocation, whether it will be used or not.

@budjb
Copy link
Author

budjb commented Dec 4, 2020

On the last part, I see!

I've dug a little more into the blowdryer plugin. It looks like it's basically using a simple URL request via HTTP in GitHub's example, but this does not account for auth. In my organization, we're using GitLab cloud with all private repositories, and by policy we aren't able to open up public repositories. I also don't want to force a configuration on every dev's workstation to configure HTTP credentials when we are already using SSH key auth. It should be easy enough to provide the gitlab raw URL with the experimental method, but I'm not quite sure how to account for auth. Does the plugin currently account for this?

I also see mention in the docs for blowdryer around the repo location that defaults to src/main/resources, and how this is ideal so that files can be pulled from JAR files in the future (exactly my use case!). It would be pretty awesome if the plugin supported that! :)

@nedtwigg
Copy link
Member

nedtwigg commented Dec 4, 2020

The issue linked above describes how to add that functionality. Happy to merge a PR for it, but no plans to implement ourselves. Adding support for the local Jar is pretty easy, adding support for http auth is a little harder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants