48

Given a set of cabal packages, is there a way to automatically calculate subset of independent packages? In other words, subset of packages that will be sufficient to install them all.

For [network,parsec] the answer is [network] because it network depends on parsec.

For [network,containers] the answer is [network,containers] because:

  • network does not depend on containers
  • all networks dependencies not depends on containers
  • containers does not depend on network
  • all containerss dependencies not depends on network

It's not hard to find the answer for 2 packages. What is really interesting is to find out independent set for [containers, directory, filepath, lens, xml, http-conduit, regex-posix, monad-control, unordered-containers, glib, hashable, hspec, split, aeson, attoparsec, stm, QuickCheck].


From answer I expect some function based on cabal library like ∷ [Packages] → IO [Packages].

  • 2
    Looks like `Distribution.Client.PackageIndex.dependencyClosure` is what you need. – Mikhail Glushenkov Mar 03 '13 at 17:01
  • Do you mean [`Distribution.Simple.PackageIndex.dependencyClosure`](http://hackage.haskell.org/packages/archive/Cabal/latest/doc/html/Distribution-Simple-PackageIndex.html#v:dependencyClosure)? – ДМИТРИЙ МАЛИКОВ Mar 03 '13 at 17:16
  • 1
    The Git version of cabal-install (`Distribution.Client.*`) is also a library now. – Mikhail Glushenkov Mar 04 '13 at 13:55
  • 1
    `cabal-sort --parallel` will display independently buildable groups of packages (which isn't quite what you want, but related ;) – Conrad Parker Mar 08 '13 at 00:09
  • 3
    There is no unique solution. All you could possibly do is to find one minimal subset whose transitive dependencies span the entire set. For example, you would basically just loop over all packages and iteratively add them to the minimal subset if not already contained in the set of transitive dependencies of the minimal subset. – user1050755 Mar 08 '13 at 01:34
  • @ConradParker what is `cabal-sort`? – ДМИТРИЙ МАЛИКОВ Mar 08 '13 at 07:40
  • Note that this question ignores version ranges, which are key to Cabal's behavior (and makes finding a satisfying assignment clearly NP-complete. – Don Stewart Mar 10 '13 at 13:17
  • @ДМИТРИЙ МАЛИКОВ, If you don't mind my asking, what are you using this for? Is this method you are enquiring about supposed to detect dependency orders on local packages on your hard-drive? Or are you looking for something that interacts with cabal real-time? – eazar001 Mar 12 '13 at 02:29
  • @eazar001 I'm just curious how `cabal install package1 package2 … packageN` decide what it should build first minimizing possible redundant rebuilds. – ДМИТРИЙ МАЛИКОВ Mar 12 '13 at 06:34

1 Answers1

1

Cabal is moving to a more NPM-like model, which will make dependency resolution much simpler. Each installed package will keep a local copy of its dependencies, trading a little disk space for the headache of installing multiple global packages with mutually exclusive package versioning demands.

Under this model, the subset of packages required to install a set of packages == that set. Though one may be a dependency of the other, each installed copy will keep its own local copy of its dependencies, so Cabal won't consider the dependency installed that way any more.

mcandre
  • 22,868
  • 20
  • 88
  • 147
  • Where (a -> b) means `a` depends on `b`. what happens when you install `a` where (a -> b-0.9) and `d` where (d -> b-1.5). `a` and `d` both expose types form b, but the types have changed from b-0.9 to b-1.5? I know how ghc handles this now, they just do not interoperate since they are different types, actually even when they are implemented the same ghc stays safe and treats them as different since they came from different versions. How does NPM handle this problem? – Davorak May 18 '13 at 07:53
  • Hopefully the Haskell data types / Node.js classes involved are only used by low level dependencies, not by the app at large. In Node.js, classes can be defined locally, so this should not be a problem unless the app tries to communicate objects with different libraries with different class definitions. Same goes for Haskell, I believe. – mcandre May 23 '13 at 01:17