Skip to content

Fine-grained dependencies #2514

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

Merged
merged 20 commits into from
May 21, 2015
Merged

Fine-grained dependencies #2514

merged 20 commits into from
May 21, 2015

Conversation

edsko
Copy link
Contributor

@edsko edsko commented Apr 1, 2015

This PR depends on #2500 and #2504, and it is the last PR before the introduction of setup dependencies proper.

Although we have fine grained dependencies in the .cabal file, and correspondingly in the PackageDescription (and GenericPackageDescription), the distinction between the various kinds of dependencies (dependencies of the library proper as well as the dependencies of the various executables, test-suites and benchmarks) was lost after the solver. In this PR I modify the solver so that it keeps these distinctions, and correspondingly modify ConfiguredPackage, ReadyPackage, and the PackageFixedDeps class to use a new data-structure called ComponentDeps which records dependencies per component.

This distinction will be crucial in the next PR where we want to treat setup dependencies as independent, but will also be very important in subsequent related features, such as treating the dependencies of the test suites as independent.

/cc @kosmikus

dcoutts and others added 19 commits March 27, 2015 15:38
It turns out not to be the right solution for general private
dependencies and is just complicated. However we keep qualified
goals, just much simpler. Now dependencies simply inherit the
qualification of their parent goal. This gets us closer to the
intended behaviour for the --independent-goals feature, and for
the simpler case of private dependencies for setup scripts.

When not using --independent-goals, the solver behaves exactly as
before (tested by comparing solver logs for a hard hackage goal).
When using --independent-goals, now every dep of each independent
goal is qualified, so the dependencies are solved completely
independently (which is actually too much still).
POption annotates a package choice with a "linked to" field. This commit
just introduces the datatype and deals with the immediate fallout, it doesn't
actually use the field for anything.
This is implemented as a separate pass so that it can be understood
independently of the rest of the solver.
In particular, in the definition of dependencyInconsistencies.

One slightly annoying thing is that in order to validate an install plan, we
need to know if the goals are to be considered independent. This means we need
to pass an additional Bool to a few functions; to limit the number of functions
where this is necessary, also recorded whether or not goals are independent as
part of the InstallPlan itself.
Since we didn't really have a unit test setup for the solver yet, this
introduces some basic tests for solver, as well as tests for independent goals
specifically.
I don't know why we we constructed this graph manually here rather than calling
`graphFromEdges`; it doesn't really matter except that we will want to change
the structure of this graph somewhat once we have more fine-grained
dependencies, and then the manual construction becomes a bit more painful;
easier to use the standard construction.
This commit does nothing but rearrange the Modular.Dependency module into a
number of separate sections, so that's a bit clearer to see what's what. No
actual code changes here whatsoever.
The ComponentDeps datatype will give us fine-grained information about the
dependencies of a package's components.  This commit just introduces the
datatype, we don't use it anywhere yet.
The modular solver has its own representation for a package (PInfo). In this
commit we modify PInfo to keep track of the different kinds of dependencies.

This is a bit intricate because the solver also regards top-level goals as
dependencies, but of course those dependencies are not part of any 'component'
as such, unlike "real" dependencies. We model this by adding a type parameter
to FlaggedDeps and go which indicates whether or not we have component
information; crucially, underneath flag choices we _always_ have component
information available.

Consequently, the modular solver itself will not make use of the ComponentDeps
datatype (but only using the Component type, classifying components); we will
use ComponentDeps when we translate out of the results from the modular solver
into cabal-install's main datatypes.

We don't yet _return_ fine-grained dependencies from the solver; this will be
the subject of the next commit.
In this commit we modify the _output_ of the modular solver (CP, the modular's
solver internal version of ConfiguredPackage) to have fine-grained dependency.
This doesn't yet modify the rest of cabal-install, so once we translate from CP
to ConfiguredPackage we still lose the distinctions between different kinds of
dependencies; this will be the topic of the next commit.

In the modular solver (and elsewhere) we use Data.Graph to represent the
dependency graph (and the reverse dependency graph). However, now that we have
more fine-grained dependencies, we really want an _edge-labeled_ graph, which
unfortunately it not available in the `containers` package. Therefore I've
written a very simple wrapper around Data.Graph that supports edge labels; we
don't need many fancy graph algorithms, and can still use Data.Graph on these
edged graphs when we want (by calling them on the underlying unlabeled graph),
so adding a dependency on `fgl` does not seem worth it.
The crucial change in this commit is the change to PackageFixedDeps to return a
ComponentDeps structure, rather than a flat list of dependencies, as long with
corresponding changes in ConfiguredPackage and ReadyPackage to accomodate this.

We don't actually take _advantage_ of these more fine-grained dependencies yet;
any use of

    depends

is now a use of

   CD.flatDeps . depends

but we will :)

Note that I have not updated the top-down solver, so in the output of the
top-down solver we cheat and pretend that all dependencies are library
dependencies.
@23Skidoo
Copy link
Member

23Skidoo commented Apr 5, 2015

Tests fail on Travis for some reason.

@edsko
Copy link
Contributor Author

edsko commented Apr 6, 2015

Something strange is going on here.. I tried to reproduce this (checked out this branch, compiled, ran the tests), tests pass. Ran cabal test, it rebuilt stuff, tests failed. Removed everything, rebuilt from scratch, tried again, tests fail. Not sure what's going on (and on #2515, which I thought doesn't change much with respect to this, the tests pass on Travis?). Will try to see what's going on.

@edsko
Copy link
Contributor Author

edsko commented Apr 6, 2015

Ok, I'm not sure where my false positives where coming from, but i suspect something to do with the fact that I override builddir and this is not taken into account everywhere. Regardless, the test failure was real, although it was fixed in the setup dependencies PR (#2515). I cherry-picked that part from that PR and pushed it here, and I've rebased the setup dependencies pull request.

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

Successfully merging this pull request may close these issues.

3 participants