
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-Pac...
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