Distribution/Types/LegacyExeDependency.hs

    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric      #-}
    module Distribution.Types.LegacyExeDependency
      ( LegacyExeDependency(..)
      ) where

    import Distribution.Compat.Prelude
    import Prelude ()

    import Distribution.Parsec.Class
    import Distribution.ParseUtils   (parseMaybeQuoted)
    import Distribution.Pretty
    import Distribution.Text
    import Distribution.Version      (VersionRange, anyVersion)

    import qualified Distribution.Compat.CharParsing as P
    import           Distribution.Compat.ReadP  ((<++))
    import qualified Distribution.Compat.ReadP  as Parse
    import           Text.PrettyPrint           (text, (<+>))

    -- | Describes a legacy `build-tools`-style dependency on an executable
    --
    -- It is "legacy" because we do not know what the build-tool referred to. It
    -- could refer to a pkg-config executable (PkgconfigName), or an internal
    -- executable (UnqualComponentName). Thus the name is stringly typed.
    --
    -- @since 2.0.0.2
    data LegacyExeDependency = LegacyExeDependency
                               String
                               VersionRange
                             deriving (Generic, Read, Show, Eq, Typeable, Data)

    instance Binary LegacyExeDependency
    instance NFData LegacyExeDependency where rnf = genericRnf

    instance Pretty LegacyExeDependency where
      pretty (LegacyExeDependency name ver) =
        text name <+> pretty ver

    instance Parsec LegacyExeDependency where
        parsec = do
            name <- parsecMaybeQuoted nameP
            P.spaces
            verRange <- parsecMaybeQuoted parsec <|> pure anyVersion
            pure $ LegacyExeDependency name verRange
          where
            nameP = intercalate "-" <$> P.sepBy1 component (P.char '-')
            component = do
                cs <- P.munch1 (\c -> isAlphaNum c || c == '+' || c == '_')
                if all isDigit cs then fail "invalid component" else return cs

    instance Text LegacyExeDependency where
      parse = do name <- parseMaybeQuoted parseBuildToolName
                 Parse.skipSpaces
                 ver <- parse <++ return anyVersion
                 Parse.skipSpaces
                 return $ LegacyExeDependency name ver
        where
          -- like parsePackageName but accepts symbols in components
          parseBuildToolName :: Parse.ReadP r String
          parseBuildToolName = do ns <- Parse.sepBy1 component (Parse.char '-')
                                  return (intercalate "-" ns)
            where component = do
                    cs <- Parse.munch1 (\c -> isAlphaNum c || c == '+' || c == '_')
                    if all isDigit cs then Parse.pfail else return cs