Dependencies from .cabal files

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Tue Jun 30 17:48:03 EDT 2009


On Tue, 2009-06-30 at 21:41 +1000, Erik de Castro Lopo wrote:
> Hi all,
> 
> I hope this is the right list to ask this. Please direct me to the
> right place if not.
> 
> Anyway, I'm using functionality in the Distribution.* namespace to
> parse .cabal files retrieved from Hackage. The problem is that 
> after using flattenPackageDescription, the buildDepends of the
> PackageDescription structure seems to be a flat list which seems
> to lose information that was in the original .cabal file.

Yes, that's what flatten does.

>From the docs:

        flattenPackageDescription
          :: GenericPackageDescription -> PackageDescription
        
        Flatten a generic package description by ignoring all conditions
        and just join the field descriptors into on package description.
        Note, however, that this may lead to inconsistent field values,
        since all values are joined into one field, which may not be
        possible in the original package description, due to the use of
        exclusive choices (if ... else ...).

It sounds like you want to select a particular valid configuration in
which case you should use finalizePackageDescription.

http://www.haskell.org/ghc/docs/latest/html/libraries/Cabal/Distribution-PackageDescription-Configuration.html

> Should the conversion from .cabal file to Dependency list be lossy?

The conversion from GenericPackageDescription to PackageDescription is
necessarily lossy because the latter is simply a smaller data type.

GenericPackageDescription represents a .cabal file, conditionals and
all. A PackageDescription represents a specific configuration that you
could actually build on a specific machine (ie all conditionals
resolved).

So the conversion is necessarily lossy, the question is what you loose.
When you use flattenPackageDescription you smash everything together so
all the field values are there but you don't know which configurations
they came from and the overall result can be inconsistent.

When you use finalizePackageDescription you are selecting a particular
configuration for a specific set of flags. You then get a valid
configuration but of course you loose any values that were for other
configurations. The only way not to loose information is not to convert
to a PackageDescription but stick with a GenericPackageDescription.

So you are trying to extract dependencies. So you need to decide what
you really mean. You give the example:

> build-depends: parsec, filepath, safe, uniplate, mtl, time
> if flag(splitBase)
>   build-depends: base >= 3, directory, process,
>                  containers, array, bytestring
> else
>   build-depends: base < 3

If you flatten then as you found you get both base >= 3 and base < 3. If
you use finalizePackageDescription and select splitBase then you get
base >= 3 and directory etc. Conversely if you select -splitBase you'd
get base < 3. In both you of course get parsec, filepath etc.

So you need to decide what you mean by getting dependencies. The method
you use depends crucially on your purpose with the data.

Duncan



More information about the cabal-devel mailing list