rules_haskell icon indicating copy to clipboard operation
rules_haskell copied to clipboard

Generate cabal files from `haskell_*` rules

Open thufschmitt opened this issue 7 years ago • 14 comments

This might be out of the scope of this repo, but I'm opening this anyways to know whether it has been considered and start a discussion.

The story is that we'd like to open-source some haskell parts of our bazel-built monorepo. Open-sourcing them means releasing them on hackage, which requires writing .cabal files for them, and it would be nice to have a way to partially automate this (so more or less the inverse of Hazel).

This could be eased by the fact that we could write a hpack's package.yaml file instead which means that we can just spit out some json instead of having to write a custom format.

thufschmitt avatar Sep 25 '18 16:09 thufschmitt

Is it really a good idea? Cabal file contains strictly more info than bazel build file. Maybe it's better to maintain such a thing in a separate public repo and treat it as a normal library. There are of course benefits of keeping it in monorepo, but on the other hand if you open source it, I as a contributor I want to see it its own public repo, etc.

mrkkrp avatar Sep 25 '18 16:09 mrkkrp

I think this is a good idea. The extra metadata could be provided using an extra rule. Something like:

haskell_library(
  name = "libA",
  ...
)

haskell_library(
  name = "libB",
  ...
)

cabal_package(
  name = "mypkg",
  deps = [":libA", ":libB"],
  author = "Me, you and them",
  copyright = ...
)

(since Cabal now allows multi-component packages)

@mrkkrp if you make it a public Cabal-only package, then you need Hazel to turn it back into a set of nodes in the global build dependency graph. Whereas if we solve this ticket, Hazel isn't needed. You would have a target to build the .cabal file and generate an sdist that can be uploaded to Hackage. Though the .cabal file would have to be checked-in even though it's generated. Otherwise no one can build your package from a git checkout without first installing Bazel.

Overall this is low-priority, because requiring Hazel is not a sizable cost, I would think.

mboes avatar Sep 26 '18 17:09 mboes

Though the .cabal file would have to be checked-in even though it's generated. Otherwise no one can build your package from a git checkout without first installing Bazel.

So this is the problem I think. As a contributor I'd be confused. If I want to add a new dependency, I can't edit Cabal file as I'm used to, I need to learn Bazel anyway. Just an opinion, but it could be scary for potential contributors who don't care about Bazel and just want to contribute to the open source library. That's why I proposed to make a normal package from it.

mrkkrp avatar Sep 27 '18 04:09 mrkkrp

I think it would be better not to check in the cabal file and just generate it every time, there would be no confusion if contributors have to use bazel. Also, what would cabal be used for apart from uploading to Hackage (or somewhere else).

What about stackage though?

shmish111 avatar Nov 28 '18 09:11 shmish111

So this is the problem I think. As a contributor I'd be confused.

No different from packages that use hpack. Which similarly check-in the .cabal file to obviate forcing hpack on users just to get things done. The strategy used there to avoid confusion is to add a big warning at the top of the Cabal file saying it's an auto-generated file, do not edit.

@shmish111 the common case when checking out from GitHub isn't to contribute. It's to simply build the latest (potentially unreleased) version. Or to report a bug. Stackage just pulls from Hackage, so I'm not sure there's anything special we need to do there.

mboes avatar Nov 28 '18 10:11 mboes

Not checking-out the cabal file would be nice, provided we have a good-enough rule so that we don't have to tweak the generated file. If we have that we could either generate the sdist archive so that uploading a new version to hackage could simply be a matter of bazel run //my/target:upload-sdist

thufschmitt avatar Nov 28 '18 10:11 thufschmitt

@mboes I don't check in cabal files when using hpack

shmish111 avatar Nov 28 '18 10:11 shmish111

Thoughts:

It's easy to provide all the meta data as parameter to a Bazel rule. But the hard thing in a cabal file is putting bounds. I think that the bounds on base are mandatory on Hackage, so we at least need a plan for those. The rest is less useful, at least if the package is slated to be part of a Stackage snapshot.

aspiwack avatar Nov 28 '18 11:11 aspiwack

Checking in the .cabal file benefits package users. As a package maintainer, at code review before checkin, I want to see both hpack source and destination file changes so having them both in source control helps with that. If rules_haskell also generated .cabal files then I'd have another file available to look at for my errors and omissions and I'd have another way to build the package.

Are we considering rules_haskell also generating a cabal.project as part of this feature?

I can think of at least three ways to currently generate .cabal files:

  • From package.yaml to <name>.cabal with hpack.
  • From package.dhall to <name>.cabal with hpack-dhall.
  • From <name>.dhall to <name>.cabal with dhall-to-cabal.

With this feature we'll be adding rules_haskell to <name>.cabal to the above list.

philderbeast avatar Nov 28 '18 11:11 philderbeast

Are we considering rules_haskell also generating a cabal.project as part of this feature?

Hadn't considered that, but I think that would be a great idea. Or at any rate generate freeze files. Is cabal.project the new way to freeze dependendencies, or is that yet another thing?

mboes avatar Nov 28 '18 11:11 mboes

The command cabal new-freeze generates a cabal.project.freeze file with constraints. The uom-plugin has an example. Having used stack2cabal, I've seen that tool put the constraints directly in the cabal.project file.

philderbeast avatar Nov 28 '18 12:11 philderbeast

Putting the cabal.project.freeze into source control is discussed in the cabal user guide.

For end-user executables, it is recommended that you distribute the cabal.project.freeze file in your source repository so that all users see a consistent set of dependencies. For libraries, this is not recommended: users often need to build against different versions of libraries than what you developed against.

I don't know how to apply this advice when the project has both executables and libraries.

philderbeast avatar Nov 28 '18 12:11 philderbeast

Since this issue was created gazelle_cabal came to be. It would allow to keep the .cabal file in sync with the rules_haskell configuration.

facundominguez avatar Jan 11 '23 14:01 facundominguez

There is a similar feature request open on rules_rust: https://github.com/bazelbuild/rules_rust/issues/458 Sharing for reference as it may be interesting to see what approach rules_rust takes. Thanks @k1nkreet for the pointer!

aherrmann avatar Apr 26 '23 11:04 aherrmann