Parsing cabal file for library

I’m trying to parse a .cabal file to a PackageDescription, but library keeps coming up as Nothing.

Here is the cabal file:

cabal-version: 1.18

-- This file has been generated from package.yaml by hpack version 0.35.2.
--
-- see: https://github.com/sol/hpack

name:           freckle-app
version:        1.10.1.0
synopsis:       Haskell application toolkit used at Freckle
description:    Please see README.md
category:       Utils
homepage:       https://github.com/freckle/freckle-app#readme
bug-reports:    https://github.com/freckle/freckle-app/issues
maintainer:     Freckle Education
license:        MIT
license-file:   LICENSE
build-type:     Simple
extra-source-files:
    package.yaml
extra-doc-files:
    README.md
    CHANGELOG.md

source-repository head
  type: git
  location: https://github.com/freckle/freckle-app

library
  exposed-modules:
      Configuration.Dotenv.Compat
      Freckle.App
      Freckle.App.Aeson
      Freckle.App.Async
      Freckle.App.Bugsnag
      Freckle.App.Bugsnag.MetaData
      Freckle.App.Csv
      Freckle.App.Database
      Freckle.App.Database.XRay
      Freckle.App.Dotenv
      Freckle.App.Ecs
      Freckle.App.Env
      Freckle.App.Ghci
      Freckle.App.GlobalCache
      Freckle.App.Http
      Freckle.App.Http.Paginate
      Freckle.App.Http.Retry
      Freckle.App.Kafka
      Freckle.App.Kafka.Consumer
      Freckle.App.Kafka.Producer
      Freckle.App.Memcached
      Freckle.App.Memcached.CacheKey
      Freckle.App.Memcached.CacheTTL
      Freckle.App.Memcached.Client
      Freckle.App.Memcached.Servers
      Freckle.App.OpenTelemetry
      Freckle.App.Prelude
      Freckle.App.Scientist
      Freckle.App.Stats
      Freckle.App.Stats.Rts
      Freckle.App.Test
      Freckle.App.Test.DocTest
      Freckle.App.Test.Hspec.Runner
      Freckle.App.Test.Properties.JSON
      Freckle.App.Test.Properties.PathPiece
      Freckle.App.Test.Yesod
      Freckle.App.Wai
      Freckle.App.Yesod
      Freckle.App.Yesod.Routes
      Network.HTTP.Link.Compat
      Network.Wai.Middleware.Cors
      Network.Wai.Middleware.OpenTelemetry
      Network.Wai.Middleware.Stats
      Yesod.Core.Lens
  other-modules:
      Paths_freckle_app
  hs-source-dirs:
      library
  default-extensions:
      BangPatterns
      DataKinds
      DeriveAnyClass
      DeriveFoldable
      DeriveFunctor
      DeriveGeneric
      DeriveLift
      DeriveTraversable
      DerivingStrategies
      FlexibleContexts
      FlexibleInstances
      GADTs
      GeneralizedNewtypeDeriving
      LambdaCase
      MultiParamTypeClasses
      NoImplicitPrelude
      NoMonomorphismRestriction
      OverloadedStrings
      RankNTypes
      RecordWildCards
      ScopedTypeVariables
      StandaloneDeriving
      TypeApplications
      TypeFamilies
  ghc-options: -fignore-optim-changes -Weverything -Wno-all-missed-specialisations -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missing-local-signatures -Wno-monomorphism-restriction -Wno-safe -Wno-unsafe
  build-depends:
      Blammo
    , Glob
    , MonadRandom
    , aeson
    , aws-xray-client-persistent
    , aws-xray-client-wai
    , base
    , bcp47
    , bugsnag
    , bytestring
    , case-insensitive
    , cassava
    , conduit
    , conduit-extra
    , containers
    , cookie
    , datadog
    , doctest
    , dotenv
    , ekg-core
    , envparse
    , errors
    , exceptions
    , extra
    , filepath
    , hashable
    , hs-opentelemetry-api
    , hs-opentelemetry-instrumentation-persistent
    , hs-opentelemetry-instrumentation-wai
    , hs-opentelemetry-propagator-datadog
    , hs-opentelemetry-sdk
    , hspec >=2.8.1
    , hspec-core >=2.8.1
    , hspec-expectations-lifted
    , hspec-junit-formatter >=1.1.0.1
    , http-client
    , http-conduit >=2.3.5
    , http-link-header
    , http-types
    , hw-kafka-client <5.0.0
    , immortal
    , lens
    , memcache
    , monad-control
    , monad-validate
    , mtl
    , network-uri
    , nonempty-containers
    , path-pieces
    , persistent
    , persistent-postgresql
    , postgresql-simple
    , primitive
    , resource-pool >=0.4.0.0
    , resourcet
    , retry >=0.8.1.0
    , safe
    , scientist
    , semigroupoids
    , template-haskell
    , text
    , time
    , transformers
    , transformers-base
    , typed-process
    , unliftio
    , unliftio-core
    , unordered-containers
    , vector
    , wai
    , wai-extra
    , yaml
    , yesod-core
    , yesod-test
  default-language: Haskell2010
  if impl(ghc >= 9.2)
    ghc-options: -Wno-missing-kind-signatures
  if impl(ghc >= 8.10)
    ghc-options: -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module
  if impl(ghc >= 8.8)
    ghc-options: -fwrite-ide-info

test-suite doctest
  type: exitcode-stdio-1.0
  main-is: Main.hs
  other-modules:
      Paths_freckle_app
  hs-source-dirs:
      doctest
  default-extensions:
      BangPatterns
      DataKinds
      DeriveAnyClass
      DeriveFoldable
      DeriveFunctor
      DeriveGeneric
      DeriveLift
      DeriveTraversable
      DerivingStrategies
      FlexibleContexts
      FlexibleInstances
      GADTs
      GeneralizedNewtypeDeriving
      LambdaCase
      MultiParamTypeClasses
      NoImplicitPrelude
      NoMonomorphismRestriction
      OverloadedStrings
      RankNTypes
      RecordWildCards
      ScopedTypeVariables
      StandaloneDeriving
      TypeApplications
      TypeFamilies
  ghc-options: -fignore-optim-changes -Weverything -Wno-all-missed-specialisations -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missing-local-signatures -Wno-monomorphism-restriction -Wno-safe -Wno-unsafe
  build-depends:
      base <5
    , freckle-app
  default-language: Haskell2010
  if impl(ghc >= 9.2)
    ghc-options: -Wno-missing-kind-signatures
  if impl(ghc >= 8.10)
    ghc-options: -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module
  if impl(ghc >= 8.8)
    ghc-options: -fwrite-ide-info

test-suite spec
  type: exitcode-stdio-1.0
  main-is: Main.hs
  other-modules:
      Freckle.App.Bugsnag.MetaDataSpec
      Freckle.App.BugsnagSpec
      Freckle.App.CsvSpec
      Freckle.App.HttpSpec
      Freckle.App.Memcached.ServersSpec
      Freckle.App.MemcachedSpec
      Freckle.App.Test.Properties.JSONSpec
      Freckle.App.Test.Properties.PathPieceSpec
      Freckle.App.WaiSpec
      Spec
      Paths_freckle_app
  hs-source-dirs:
      tests
  default-extensions:
      BangPatterns
      DataKinds
      DeriveAnyClass
      DeriveFoldable
      DeriveFunctor
      DeriveGeneric
      DeriveLift
      DeriveTraversable
      DerivingStrategies
      FlexibleContexts
      FlexibleInstances
      GADTs
      GeneralizedNewtypeDeriving
      LambdaCase
      MultiParamTypeClasses
      NoImplicitPrelude
      NoMonomorphismRestriction
      OverloadedStrings
      RankNTypes
      RecordWildCards
      ScopedTypeVariables
      StandaloneDeriving
      TypeApplications
      TypeFamilies
  ghc-options: -fignore-optim-changes -Weverything -Wno-all-missed-specialisations -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missing-local-signatures -Wno-monomorphism-restriction -Wno-safe -Wno-unsafe -threaded -rtsopts "-with-rtsopts=-N"
  build-depends:
      Blammo
    , QuickCheck
    , aeson
    , base <5
    , bugsnag
    , bytestring
    , cassava
    , conduit
    , errors
    , freckle-app
    , hspec
    , http-types
    , lens
    , lens-aeson
    , memcache
    , monad-validate
    , nonempty-containers
    , postgresql-simple
    , unliftio
    , vector
    , wai
    , wai-extra
  default-language: Haskell2010
  if impl(ghc >= 9.2)
    ghc-options: -Wno-missing-kind-signatures
  if impl(ghc >= 8.10)
    ghc-options: -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module
  if impl(ghc >= 8.8)
    ghc-options: -fwrite-ide-info

And here is my code:

{-# LANGUAGE NamedFieldPuns #-}

module Main (main) where

import Distribution.Simple.PackageDescription (readGenericPackageDescription)
import Distribution.Types.GenericPackageDescription
  ( GenericPackageDescription (..)
  )
import Distribution.Verbosity as Verbosity

main :: IO ()
main = do
  GenericPackageDescription {packageDescription} <-
    readGenericPackageDescription Verbosity.verbose "freckle-app.cabal"

  print packageDescription

And here is the output:

PackageDescription {specVersion = CabalSpecV1_18, package = PackageIdentifier {pkgName = PackageName "freckle-app", pkgVersion = mkVersion [1,10,1,0]}, licenseRaw = Right MIT, licenseFiles = [SymbolicPath "LICENSE"], copyright = "", maintainer = "Freckle Education", author = "", stability = "", testedWith = [], homepage = "https://github.com/freckle/freckle-app#readme", pkgUrl = "", bugReports = "https://github.com/freckle/freckle-app/issues", sourceRepos = [SourceRepo {repoKind = RepoHead, repoType = Just (KnownRepoType Git), repoLocation = Just "https://github.com/freckle/freckle-app", repoModule = Nothing, repoBranch = Nothing, repoTag = Nothing, repoSubdir = Nothing}], synopsis = "Haskell application toolkit used at Freckle", description = "Please see README.md", category = "Utils", customFieldsPD = [], buildTypeRaw = Just Simple, setupBuildInfo = Nothing, library = Nothing, subLibraries = [], executables = [], foreignLibs = [], testSuites = [], benchmarks = [], dataFiles = [], dataDir = ".", extraSrcFiles = ["package.yaml"], extraTmpFiles = [], extraDocFiles = ["README.md","CHANGELOG.md"]}

What am I doing wrong? It’s clearly “working”, but it never picks up the actual library section (among others).

2 Likes

Eh, the old “PackageDescription means multiple things” (a configured package, header info for a .cabal file). Sorry you tripped on this too, changing it is feasible but alas laborious.

In any case, try to print GPD and you will find your missing fields!

2 Likes

Ah thanks!

Ultimately, I was hoping to pass this to the haddock function, which wants a PackageDescription (and one with a library). Is there some other GenericPackageDescription -> PackageDescription function that will retain those fields?

1 Like

See Distribution.PackageDescription.Configuration. Ideally you would use finalizePD and resolve a PackageDescription which suits your OS, flags, etc.

The alternative is flattenPackageDescription, which will lead to a PD which most likely is not sensible but may just cut it for your use case.

2 Likes

Perfect, one of those should do it (depending on where my specific needs go). Thanks again!

1 Like