Skip to content

Handle apparent package dependency cycles due to test suites / benchmarks #1575

Open
@tibbe

Description

@tibbe

Update by @ezyang: See @edsko's comment at #1575 (comment) we don't actually want to dep solver for each package individually, according to @dcoutts.

Update by @dcoutts: the latest iteration of idea 1 below is as follows:

Suppose for sake of argument we're looking at bytestring which has a test suite that uses tasty, and tasty depends indirectly on bytestring. So the original proposal was to resolve this cycle by building the under-development bytestring and then building tasty against that, and then building the bytestring testsuite against the freshly built tasty package. But actually this is crazy, it means every time I make a small edit to bytestring and want to re-run the tests, cabal has to go and rebuild tasty (and all the other deps of tasty that use bytestring). This would get really annoying really quickly. Also, we don't really want to build tasty against an in-development version of bytestring, we want tasty to use a stable version of bytestring. So much better is to have tasty be built using an existing stable bytestring. Then tasty etc does not need to be rebuilt as we make minor changes to the in-development version of bytestring.

So this requires we have a solution using two different version of bytestring. We already have something like this for dependencies of Setup scripts, which we call "independent" dependencies. So we can treat the dependencies of the test-suite /which it doesn't share with the library/ as independent. See #3422 for a partial implementation of this idea and a discussion of the difficulties.

Idea 2 below would require a different approach. In general it is important to have consistent behaviour of code in one component (e.g. exe) vs another component in the same package. This is what authors generally expect. This means that two exes both use some lib then they need to use the same version of that lib. If authors really want to allow two exes in the same package to use different versions of some dep then this ought to be explicit and we should come up with some mechanism to do so. If we go down this route then we should also consider the case of the same component using two different version of a lib. We might handle that like package qualified module imports, giving each one a different local name. This also relates to backpack.


I think we should create the install plan on a component (i.e. library, executable, test-suite, and benchmark) basis instead of creating one for the whole package.

There are two use cases I can think of:

  1. There's a growing number of packages (anything that's a dependency of either test-frame-work and its related packages or of criterion) that can't have test suite or benchmark sections, as that would create a dependency cycle.
  2. Users have requested being able to build executables (in a single package) that have conflicting dependencies.

I suggest that we treat each component as if it was a "package" with name package-x.y.z.w:component-name, for the purpose of dependency resolution.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions