typelead/gradle-eta

read dependencies from *.cabal

joshsh opened this issue · 7 comments

With etlas, I am able to build a large directory of pure Haskell code, not otherwise configured for use with Eta. In this case, etlas reads dependencies directly from a pre-existing .cabal file. On the other hand, I believe I can also build the project using gradle-eta so long as I specify all dependencies in build.gradle, e.g. compile eta('text:1.2.2.2').

This seems like duplicate work, and it will be easy for my package.yaml and build.gradle to become out of sync. In my case, I need to compile the same code via stack and gradle-eta or a custom build script. Can gradle-eta be configured to read from *.cabal?

The solution suggested by @rahulmutt is to generate a *.gradle file based on the *.cabal; this could then be included in the main build.gradle. This would be a much better solution than redefining dependencies already in the Cabal file (when parts of a project need to remain buildable as pure Haskell).

If this is possible, how difficult would it be to detect the Cabal file and generate the *.gradle at build time, writing it to a standard location in the build directory and including it dynamically? I.e. is it possible to minimize or even eliminate extra configuration in build.gradle?

From Gitter:

Rahul Muttineni @rahulmutt 22:59
@joshsh If etlas generated a build.gradle for you from a .cabal file would that be helpful? And we could expose this as a Gradle task via something like ./gradlew generateEta -Pproject-type=gradle

Joshua Shinavier @joshsh Sep 08 23:20
@rahulmutt I think that would work well. The generated *.gradle would have to be included from the main build.gradle (which will have other config for the pure Java components of the project, if any). I think this can be done using the apply from syntax

Is there any ETA/priority for this (the generated *.gradle if not the dynamic include)? Thanks.

Moving forward, I'm sure this will be pretty useful to a lot of people, but right now we have our hands full.

@jneira Do you think implementing etlas project [component-name] --gradle command is something you'd be interested in working on since you've been doing a lot of work on transforming X -> GenericPackageDescription? This would be the inverse - GenericPackageDescription -> X.

If that's done, adding it to gradle-eta should be straightforward.

Not sure if i fully understand the solution, but it seems the main info that gradle would need from the cabal file are the dependecies. The rest of the GenericPackageDescription info is not essential.
So maybe we could modify etlas deps to output the project dependencies (including eta packages and maven ones). Something like

> etals deps --gradle

compile ('org.bouncycastle:bcprov-jdk15on:1.59')
compile eta('base:[4.8,4.12[')
compile eta('dhall:[1.18.0,1.19[')
compile eta('text:[0.11.1,1.3[')

could it be that output usable in a easy way from gradle plugin?

@jneira Actually, the Gradle DSL supports more than just dependencies - you can specify pretty much everything you could in the .cabal file. Currently, gradle-eta only supports the most frequently used fields, but I'd be happy to support all the fields if this conversion command is implemented.

I imagine etlas project to be a generic querying command for information about the build and etlas project [component] --[format] will output the build component information in the particular format where format can be Gradle DSL, .etlas file, .cabal file, or etlas.dhall file. Will be extremely useful when moving between Haskell/Eta as well as between the different file formats (say you want to migrate from .etlas to etlas.dhall). This command will be incredibly useful in quickly migrating users to the dhall format if they're only had experience with the .cabal format. Given that you have done extensive work on supporting multiple formats, you probably have a better idea of the architecture of how to implement this nicely.

I see, it could be a more general solution to interoperate between formats, i'll try to take a look.
The hard part could be the GenericPackageDescription -> GradleDSL cause it is in pure java/groovy in the gradle plugin, right?
We should implement a builder in haskell for the gradle dsl format, or would be there another option?

@jneira I can handle the GenericPackageDescription -> GradleDSL bit, probably the first iteration will just be concatenating raw Text's. If you can setup the basic framework (basic implementation of the etlas project command), that'll be enough.