staversion (empty) → 0.1.0.0
raw patch · 21 files changed
+2070/−0 lines, 21 filesdep +aesondep +basedep +bytestringsetup-changed
Dependencies added: aeson, base, bytestring, directory, filepath, hspec, optparse-applicative, staversion, text, unordered-containers, yaml
Files
- ChangeLog.md +5/−0
- LICENSE +30/−0
- README.md +41/−0
- Setup.hs +2/−0
- app/Main.hs +4/−0
- src/Staversion/Internal/BuildPlan.hs +65/−0
- src/Staversion/Internal/Command.hs +95/−0
- src/Staversion/Internal/Exec.hs +72/−0
- src/Staversion/Internal/Format.hs +62/−0
- src/Staversion/Internal/Log.hs +57/−0
- src/Staversion/Internal/Query.hs +58/−0
- staversion.cabal +72/−0
- test/Spec.hs +1/−0
- test/Staversion/Internal/BuildPlanSpec.hs +58/−0
- test/Staversion/Internal/ExecSpec.hs +81/−0
- test/Staversion/Internal/FormatSpec.hs +84/−0
- test/Staversion/Internal/TestUtil.hs +13/−0
- test/data/conpact_build_plan.yaml +97/−0
- test/data/lts-2.22_conpact.yaml +497/−0
- test/data/lts-4.2.yaml too large to diff
- test/data/lts-7.0_conpact.yaml +676/−0
+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Revision history for staversion++## 0.1.0.0 -- 2016-10-16++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2016, Toshio Ito++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Toshio Ito nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,41 @@+# staversion++++staversion is a command-line tool to look for version numbers for Haskell packages in specific stackage resolvers. It answers to questions like "What version is the package X in stackage lts-Y.ZZ?" It aims to make it easier to write `build-depends` section in YOUR_PACKAGE.cabal.++ $ staversion --resolver lts-4.2 conduit+ ------ lts-4.2+ conduit ==1.2.6.1+ + $ staversion --resolver lts-4.2 --resolver lts-7.0 conduit+ ------ lts-4.2+ conduit ==1.2.6.1+ + ------ lts-7.0+ conduit ==1.2.7+ + $ staversion --resolver lts-4.2 --resolver lts-7.0 conduit base+ ------ lts-4.2+ conduit ==1.2.6.1,+ base ==4.8.2.0+ + ------ lts-7.0+ conduit ==1.2.7,+ base ==4.9.0.0++Currently staversion reads build plan YAML files that are stored locally in your computer.+++## TODO++- Fetch build plan YAML files from github.com+- Cache build plans in some local storage (SQLite?)+- Expand major version resolvers (lts-X) into full resolvers (lts-X.YY)+- Search for the latest version numbers hosted in hackage.+- Read `build-depends` sections .cabal files for package name queries.+- Show version number ranges supported by the given resolvers.++## Author++Toshio Ito <debug.ito@gmail.com>
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ app/Main.hs view
@@ -0,0 +1,4 @@+module Main+ (main) where++import Staversion.Internal.Exec (main)
+ src/Staversion/Internal/BuildPlan.hs view
@@ -0,0 +1,65 @@+-- |+-- Module: Staversion.Internal.BuildPlan+-- Description: Handle build plan YAML files.+-- Maintainer: Toshio Ito <debug.ito@gmail.com>+--+-- __This is an internal module. End-users should not use it.__+module Staversion.Internal.BuildPlan+ ( PackageName,+ BuildPlan,+ loadBuildPlanYAML,+ packageVersion,+ parseVersionText+ ) where++import Control.Applicative (empty, (<$>), (<*>))+import Control.Exception (throwIO)+import Data.Aeson (FromJSON(..), (.:), Value(..), Object)+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import qualified Data.HashMap.Strict as HM+import Data.Maybe (listToMaybe)+import Data.Monoid ((<>))+import Data.Text (Text, unpack)+import Data.Traversable (Traversable(traverse))+import Data.Version (Version, parseVersion)+import qualified Data.Yaml as Yaml+import Text.Read (readMaybe)+import Text.ParserCombinators.ReadP (readP_to_S)++import Staversion.Internal.Query (PackageName)++-- | A data structure that keeps a map between package names and their+-- versions.+newtype BuildPlan = BuildPlan (HM.HashMap PackageName Version)++instance FromJSON BuildPlan where+ parseJSON (Object object) = (\p1 p2 -> BuildPlan $ p1 <> p2) <$> core_packages <*> other_packages where+ core_packages = parseSysInfo =<< (object .: "system-info")+ parseSysInfo (Object o) = parseCorePackages =<< (o .: "core-packages")+ parseSysInfo _ = empty+ parseCorePackages (Object o) = traverse (\v -> versionParser =<< parseJSON v) o+ parseCorePackages _ = empty++ other_packages = parsePackages =<< (object .: "packages")+ parsePackages (Object o) = traverse parsePackageObject o+ parsePackages _ = empty+ parsePackageObject (Object o) = versionParser =<< (o .: "version")+ parsePackageObject _ = empty+ versionParser = maybe empty return . parseVersionText+ parseJSON _ = empty+++-- | Load a 'BuildPlan' from a file.+loadBuildPlanYAML :: FilePath -> IO BuildPlan+loadBuildPlanYAML yaml_file = (toException . Yaml.decodeEither') =<< BS.readFile yaml_file where -- TODO: make it memory-efficient!+ toException = either (throwIO) return++packageVersion :: BuildPlan -> PackageName -> Maybe Version+packageVersion (BuildPlan bp_map) name = HM.lookup name bp_map++-- | Parse a version text. There must not be any trailing characters+-- after a valid version text.+parseVersionText :: Text -> Maybe Version+parseVersionText = extractResult . (readP_to_S parseVersion) . unpack where+ extractResult = listToMaybe . map fst . filter (\pair -> snd pair == "")
+ src/Staversion/Internal/Command.hs view
@@ -0,0 +1,95 @@+-- |+-- Module: Staversion.Internal.Command+-- Description: Command from the user.+-- Maintainer: Toshio Ito <debug.ito@gmail.com>+--+-- __This is an internal module. End-users should not use it.__+module Staversion.Internal.Command+ ( Command(..),+ parseCommandArgs+ ) where++import Control.Applicative ((<$>), (<*>), optional, some)+import Data.Monoid (mconcat)+import Data.Text (pack)+import Data.Version (showVersion)+import qualified Options.Applicative as Opt+import qualified Paths_staversion as MyInfo+import System.Directory (getHomeDirectory)+import System.FilePath ((</>))++import Staversion.Internal.Log+ ( LogLevel(..), Logger(loggerThreshold), defaultLogger+ )+import Staversion.Internal.Query+ ( Resolver,+ PackageName,+ Query(..),+ PackageSource(..)+ )++-- | Command from the user.+data Command =+ Command { commBuildPlanDir :: FilePath,+ -- ^ path to the directory where build plan files are stored.+ commLogger :: Logger,+ -- ^ the logger+ commSources :: [PackageSource],+ -- ^ package sources to search+ commQueries :: [Query]+ -- ^ package queries+ } deriving (Show,Eq)++-- | Default values for 'Command'.+data DefCommand = DefCommand { defBuildPlanDir :: FilePath+ } deriving (Show,Eq,Ord)++defCommand :: IO DefCommand+defCommand = DefCommand <$> def_build_plan_dir where+ def_build_plan_dir = do+ home <- getHomeDirectory+ return $ home </> ".stack" </> "build-plan"+++commandParser :: DefCommand -> Opt.Parser Command+commandParser def_comm = Command <$> build_plan_dir <*> logger <*> sources <*> queries where+ logger = makeLogger <$> is_verbose+ makeLogger True = defaultLogger { loggerThreshold = Just LogDebug }+ makeLogger False = defaultLogger+ is_verbose = Opt.switch $ mconcat [ Opt.long "verbose",+ Opt.short 'v',+ Opt.help "Verbose messages."+ ]+ build_plan_dir = Opt.strOption+ $ mconcat [ Opt.long "build-plan-dir",+ Opt.help ( "Directory where build plan YAML files are stored. Default: "+ ++ defBuildPlanDir def_comm+ ),+ Opt.metavar "DIR",+ Opt.value (defBuildPlanDir def_comm)+ ]+ sources = some $ SourceStackage <$> resolver+ resolver = Opt.strOption+ $ mconcat [ Opt.long "resolver",+ Opt.short 'r',+ Opt.help "Stackage resolver to search. e.g. \"lts-6.15\"",+ Opt.metavar "RESOLVER_NAME"+ ]+ queries = some $ QueryName <$> package+ package = fmap pack $ Opt.strArgument+ $ mconcat [ Opt.help "Name of package whose version you want to check.",+ Opt.metavar "PACKAGE_NAME"+ ]++programDescription :: Opt.Parser a -> Opt.ParserInfo a+programDescription parser =+ Opt.info (Opt.helper <*> parser)+ $ mconcat [ Opt.fullDesc,+ Opt.progDesc ( "Look for version numbers for Haskell packages in specific stackage resolvers"+ ++ " (or possibly other package sources)"+ ),+ Opt.footer ("Version: " ++ (showVersion MyInfo.version))+ ]++parseCommandArgs :: IO Command+parseCommandArgs = Opt.execParser . programDescription . commandParser =<< defCommand
+ src/Staversion/Internal/Exec.hs view
@@ -0,0 +1,72 @@+-- |+-- Module: Staversion.Internal.Exec+-- Description: executable+-- Maintainer: Toshio Ito <debug.ito@gmail.com>+--+-- __This is an internal module. End-users should not use it.__+module Staversion.Internal.Exec+ ( main,+ processCommand+ ) where++import Control.Applicative ((<$>))+import Control.Exception (catchJust, IOException)+import Data.Function (on)+import Data.List (groupBy)+import Data.Text (unpack)+import qualified Data.Text.Lazy.IO as TLIO+import System.FilePath ((</>), (<.>))+import qualified System.IO.Error as IOE++import Staversion.Internal.BuildPlan+ ( BuildPlan, loadBuildPlanYAML, packageVersion+ )+import Staversion.Internal.Command+ ( parseCommandArgs,+ Command(..)+ )+import Staversion.Internal.Format (formatResultsCabal)+import Staversion.Internal.Log (logDebug, logWarn)+import Staversion.Internal.Query+ ( Query(..), Result(..), PackageSource(..),+ resultVersionsFromList, ResultVersions,+ ErrorMsg+ )++main :: IO ()+main = do+ comm <- parseCommandArgs+ (TLIO.putStr . formatResultsCabal) =<< (processCommand comm)++processCommand :: Command -> IO [Result]+processCommand comm = fmap concat $ mapM processQueriesIn $ commSources comm where+ logger = commLogger comm+ processQueriesIn source = do+ logDebug logger ("Retrieve package source " ++ show source)+ e_build_plan <- loadBuildPlan comm source+ logBuildPlanResult e_build_plan+ return $ map (makeResult source e_build_plan) $ commQueries comm+ makeResult source e_build_plan query = case e_build_plan of+ Left error_msg -> Result { resultIn = source, resultFor = query, resultVersions = Left error_msg }+ Right build_plan -> Result { resultIn = source, resultFor = query,+ resultVersions = Right $ searchVersions build_plan query+ }+ logBuildPlanResult (Right _) = logDebug logger ("Successfully retrieved build plan.")+ logBuildPlanResult (Left error_msg) = logWarn logger ("Failed to load build plan: " ++ error_msg)++loadBuildPlan :: Command -> PackageSource -> IO (Either ErrorMsg BuildPlan)+loadBuildPlan comm source@(SourceStackage resolver) = catchJust handleIOError (Right <$> doLoad) (return . Left) where+ yaml_file = commBuildPlanDir comm </> resolver <.> "yaml"+ doLoad = do+ logDebug (commLogger comm) ("Read " ++ yaml_file ++ " for build plan.")+ loadBuildPlanYAML yaml_file+ handleIOError :: IOException -> Maybe ErrorMsg+ handleIOError e | IOE.isDoesNotExistError e = Just $ makeErrorMsg e (yaml_file ++ " not found.")+ | IOE.isPermissionError e = Just $ makeErrorMsg e ("you cannot open " ++ yaml_file ++ ".")+ | otherwise = Just $ makeErrorMsg e ("some error.")+ makeErrorMsg exception body = "Loading build plan for package source " ++ show source ++ " failed: " ++ body ++ "\n" ++ show exception+++searchVersions :: BuildPlan -> Query -> ResultVersions+searchVersions build_plan (QueryName package_name) =+ resultVersionsFromList [(package_name, packageVersion build_plan package_name)]
+ src/Staversion/Internal/Format.hs view
@@ -0,0 +1,62 @@+-- |+-- Module: Staversion.Internal.Format+-- Description: formatting Result output.+-- Maintainer: Toshio Ito <debug.ito@gmail.com>+--+-- __This is an internal module. End-users should not use it.__+module Staversion.Internal.Format+ ( formatResultsCabal+ ) where++import Data.Function (on)+import Data.List (intersperse)+import Data.Monoid (mempty, mconcat, (<>))+import qualified Data.Text.Lazy as TL+import Data.Text.Lazy.Builder (Builder, toLazyText, fromText, fromString)+import Data.Version (showVersion)++import Staversion.Internal.Query+ ( Result(..), Query(..),+ sourceDesc,+ ResultVersions,+ resultVersionsToList+ )++-- | format 'Result's like it's in build-depends in .cabal files.+formatResultsCabal :: [Result] -> TL.Text+formatResultsCabal = toLazyText . mconcat . map formatGroupedResultsCabal . groupAllPreservingOrderBy ((==) `on` resultIn)++groupAllPreservingOrderBy :: (a -> a -> Bool) -> [a] -> [[a]]+groupAllPreservingOrderBy sameGroup = map snd . foldr f [] where+ f item acc = update [] acc where+ update heads [] = (item, [item]) : heads+ update heads (cur@(cur_item, cur_list) : rest) =+ if sameGroup item cur_item+ then heads ++ ( (cur_item, item : cur_list) : rest )+ else update (heads ++ [cur]) rest++formatGroupedResultsCabal :: [Result] -> Builder+formatGroupedResultsCabal [] = mempty+formatGroupedResultsCabal results@(head_ret : _) = header <> (concatLines $ single_result_output =<< results) where+ header = "------ " <> (fromText $ sourceDesc $ resultIn head_ret) <> "\n"+ single_result_output ret = case resultVersions ret of+ Left _ -> [Left $ error_result ret]+ Right versions -> formatVersionsCabal (resultFor ret) versions+ error_result ret = case resultFor ret of+ QueryName query_name -> "-- " <> fromText query_name <> " ERROR"+ concatLines ebuilder_lines = (mconcat $ intersperse "\n" $ map (either id id) $ tailCommas ebuilder_lines) <> "\n\n"+ tailCommas = fst . foldr f ([], False) where+ -- flag: True if it has already encountered the last Right element in the list.+ f eb (ret, flag) = let (next_e, next_flag) = getNext ret flag eb+ in (next_e:ret, next_flag)+ getNext [] flag e@(Left _) = (e, flag)+ getNext _ flag (Left b) = (Left (b <> ","), flag)+ getNext _ False e@(Right _) = (e, True)+ getNext _ True (Right b) = (Right (b <> ","), True)++formatVersionsCabal :: Query -> ResultVersions -> [Either Builder Builder]+formatVersionsCabal (QueryName _) rvers = map format $ resultVersionsToList rvers where+ format (name, mver) = case mver of+ Nothing -> Left $ "-- " <> fromText name <> " N/A"+ Just ver -> Right $ fromText name <> " ==" <> (fromString $ showVersion ver)+
+ src/Staversion/Internal/Log.hs view
@@ -0,0 +1,57 @@+-- |+-- Module: Staversion.Internal.Log+-- Description: types and functions about logging+-- Maintainer: Toshio Ito <debug.ito@gmail.com>+--+-- +module Staversion.Internal.Log+ ( LogLevel(..),+ Logger(loggerThreshold),+ defaultLogger,+ putLog,+ logDebug,+ logInfo,+ logWarn+ ) where++import Control.Monad (when)+import System.IO (Handle, stderr, hPutStrLn)++data LogLevel = LogDebug+ | LogInfo+ | LogWarn+ | LogError+ deriving (Show,Eq,Ord,Enum,Bounded)++data Logger = Logger { loggerThreshold :: Maybe LogLevel,+ -- ^ If 'Nothing', logging is disabled.+ loggerHandle :: Handle+ } deriving (Show,Eq)++defaultLogger :: Logger+defaultLogger = Logger { loggerThreshold = Just LogInfo,+ loggerHandle = stderr+ }++toLabel :: LogLevel -> String+toLabel l = case l of+ LogDebug -> "[debug]"+ LogInfo -> "[info]"+ LogWarn -> "[warn]"+ LogError -> "[error]"++putLog :: Logger -> LogLevel -> String -> IO ()+putLog logger level raw_msg = when (fmap (level >=) mthreshold == Just True) $ hPutStrLn log_handle msg where+ mthreshold = loggerThreshold logger+ log_handle = loggerHandle logger+ msg = toLabel level ++ " " ++ raw_msg++logDebug :: Logger -> String -> IO ()+logDebug = flip putLog $ LogDebug++logInfo :: Logger -> String -> IO ()+logInfo = flip putLog $ LogInfo++logWarn :: Logger -> String -> IO ()+logWarn = flip putLog $ LogWarn+
+ src/Staversion/Internal/Query.hs view
@@ -0,0 +1,58 @@+-- |+-- Module: Staversion.Internal.Query+-- Description: Query, Result and related symbols.+-- Maintainer: Toshio Ito <debug.ito@gmail.com>+--+-- __This is an internal module. End-users should not use it.__+module Staversion.Internal.Query+ ( PackageName,+ Resolver,+ PackageSource(..),+ Query(..),+ ErrorMsg,+ Result(..),+ ResultVersions,+ resultVersionsFromList,+ resultVersionsToList,+ sourceDesc+ ) where++import qualified Data.HashMap.Strict as HM+import Data.Text (Text, pack)+import Data.Version (Version)++type PackageName = Text++-- | Resolver name at stackage like "lts-4.1".+type Resolver = String++-- | Source of packages.+data PackageSource = SourceStackage Resolver -- ^ stackage.+ deriving (Show,Eq,Ord)++-- | Query for package version(s).+data Query = QueryName PackageName+ deriving (Show,Eq,Ord)++type ErrorMsg = String++-- | Result for a query.+data Result = Result { resultIn :: PackageSource,+ resultFor :: Query,+ resultVersions :: Either ErrorMsg ResultVersions+ } deriving (Show,Eq)+++-- | The obtained version map.+newtype ResultVersions = ResultVersions (HM.HashMap PackageName (Maybe Version))+ deriving (Show,Eq)++resultVersionsFromList :: [(PackageName, Maybe Version)] -> ResultVersions+resultVersionsFromList = ResultVersions . HM.fromList++resultVersionsToList :: ResultVersions -> [(PackageName, Maybe Version)]+resultVersionsToList (ResultVersions m) = HM.toList m++-- | description of a 'PackageSource'.+sourceDesc :: PackageSource -> Text+sourceDesc (SourceStackage r) = pack r
+ staversion.cabal view
@@ -0,0 +1,72 @@+name: staversion+version: 0.1.0.0+author: Toshio Ito <debug.ito@gmail.com>+maintainer: Toshio Ito <debug.ito@gmail.com>+license: BSD3+license-file: LICENSE+synopsis: What version is the package X in stackage lts-Y.ZZ?+description: A command-line tool to look for version numbers for Haskell packages in specific stackage resolvers. See README.md+category: Development+cabal-version: >= 1.10+build-type: Simple+extra-source-files: README.md, ChangeLog.md,+ test/data/conpact_build_plan.yaml,+ -- Cabal's wild-card (*) doesn't match periods (.)+ test/data/lts-7.0_conpact.yaml,+ test/data/lts-4.2.yaml,+ test/data/lts-2.22_conpact.yaml+ +homepage: https://github.com/debug-ito/staversion+bug-reports: https://github.com/debug-ito/staversion/issues++library+ default-language: Haskell2010+ hs-source-dirs: src+ ghc-options: -Wall -fno-warn-unused-imports+ default-extensions: OverloadedStrings+ -- other-extensions: + exposed-modules: Staversion.Internal.BuildPlan,+ Staversion.Internal.Query,+ Staversion.Internal.Command,+ Staversion.Internal.Log,+ Staversion.Internal.Exec,+ Staversion.Internal.Format+ other-modules: Paths_staversion+ build-depends: base >=4.6 && <4.10,+ unordered-containers >=0.2.3 && <0.3,+ aeson >=0.8.0 && <1.1,+ text >=0.11.3 && <1.3,+ bytestring >=0.10.0 && <0.11,+ yaml >=0.8.3 && <0.9,+ filepath >=1.3.0 && <1.5,+ directory >=1.2.0 && <1.3,+ optparse-applicative >=0.11.0 && <0.14++executable staversion+ default-language: Haskell2010+ hs-source-dirs: app+ main-is: Main.hs+ ghc-options: -Wall -fno-warn-unused-imports -rtsopts -threaded "-with-rtsopts=-N"+ -- other-modules: + -- default-extensions: + -- other-extensions: + build-depends: base, staversion++test-suite spec+ type: exitcode-stdio-1.0+ default-language: Haskell2010+ hs-source-dirs: test+ ghc-options: -Wall -fno-warn-unused-imports "-with-rtsopts=-M512m"+ main-is: Spec.hs+ default-extensions: OverloadedStrings+ -- other-extensions: + other-modules: Staversion.Internal.BuildPlanSpec,+ Staversion.Internal.ExecSpec,+ Staversion.Internal.FormatSpec,+ Staversion.Internal.TestUtil+ build-depends: base, staversion, text, filepath,+ hspec >=2.1.7 && <2.4+ +source-repository head+ type: git+ location: https://github.com/debug-ito/staversion.git
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ test/Staversion/Internal/BuildPlanSpec.hs view
@@ -0,0 +1,58 @@+module Staversion.Internal.BuildPlanSpec (main,spec) where++import Data.Text (Text, pack)+import Data.Version (Version(..))+import System.FilePath ((</>), (<.>))+import Test.Hspec++import Staversion.Internal.BuildPlan+ ( PackageName,+ BuildPlan, + loadBuildPlanYAML, + packageVersion,+ parseVersionText+ )++main :: IO ()+main = hspec spec++spec :: Spec+spec = do+ parseVersionText_spec+ packageVersion_spec++parseVersionText_spec :: Spec+parseVersionText_spec = describe "parseVersionText" $ do+ spec_v "0.1.0.6" $ Just (Version [0,1,0,6] [])+ spec_v "10.11" $ Just (Version [10,11] [])+ where+ spec_v input_v expected = specify input_v $ do+ parseVersionText (pack input_v) `shouldBe` expected++packageVersion_spec :: Spec+packageVersion_spec = describe "packageVersion" $ do+ forBuildPlan "conpact_build_plan" $ \loader -> do+ specify "drawille -> 0.1.0.6" $ do+ loadVersion "drawille" loader `shouldReturn` Just (Version [0,1,0,6] [])+ specify "unknown -> Nothing" $ do+ loadVersion "unknown" loader `shouldReturn` Nothing+ specify "ghc -> 7.10.3" $ do+ loadVersion "ghc" loader `shouldReturn` Just (Version [7,10,3] [])+ specify "base -> 4.8.2.0" $ do+ loadVersion "base" loader `shouldReturn` Just (Version [4,8,2,0] [])++ forBuildPlan "lts-4.2" $ \loader -> do+ specify "conduit -> 1.2.6.1" $ do+ loadVersion "conduit" loader `shouldReturn` Just (Version [1,2,6,1] [])+ specify "transformers -> 0.4.2.0" $ do+ loadVersion "transformers" loader `shouldReturn` Just (Version [0,4,2,0] [])+++forBuildPlan :: String -> (IO BuildPlan -> Spec) -> Spec+forBuildPlan build_plan_base testWith = describe build_plan_base (testWith loader) where+ loader = loadBuildPlanYAML ("test" </> "data" </> build_plan_base <.> "yaml")++loadVersion :: PackageName -> IO BuildPlan -> IO (Maybe Version)+loadVersion package_name loader = do+ plan <- loader+ return $ packageVersion plan package_name
+ test/Staversion/Internal/ExecSpec.hs view
@@ -0,0 +1,81 @@+module Staversion.Internal.ExecSpec (main,spec) where++import Data.Version (Version(Version))+import System.FilePath ((</>))+import Test.Hspec++import Staversion.Internal.Command (Command(..))+import Staversion.Internal.Exec (processCommand)+import Staversion.Internal.Query+ ( PackageName,+ Query(..),+ PackageSource(..),+ Result(..),+ ResultVersions,+ resultVersionsFromList,+ ErrorMsg+ )+import Staversion.Internal.Log (defaultLogger, Logger(loggerThreshold), LogLevel(LogError))++import Staversion.Internal.TestUtil (ver, rvers)++main :: IO ()+main = hspec spec++spec :: Spec+spec = describe "processCommand" $ do+ specify "QueryName, SourceStackage, hit" $ do+ singleCase (SourceStackage "conpact_build_plan") (QueryName "drawille")+ (Right $ rvers [("drawille", Just $ ver [0,1,0,6])])+ specify "QueryName, SourceStackage, miss" $ do+ singleCase (SourceStackage "conpact_build_plan") (QueryName "unknown")+ (Right $ rvers [("unknown", Nothing)])+ specify "QueryName, SourceStackage, source not found" $ do+ singleCase' (SourceStackage "unknown") (QueryName "drawille") $ \got -> case got of+ Right _ -> expectationFailure "it should fail"+ Left msg -> do+ msg `shouldContain` "unknown.yaml"+ msg `shouldContain` "not found"+ specify "QueryName, SourceStackage, full-mesh" $ do+ let src2 = SourceStackage "lts-2.22_conpact"+ src7 = SourceStackage "lts-7.0_conpact"+ qc = QueryName "conduit"+ qa = QueryName "aeson"+ comm = baseCommand { commSources = [src2, src7], commQueries = [qc, qa] }+ expected = [ Result { resultIn = src2, resultFor = qc,+ resultVersions = Right $ rvers [("conduit", Just $ ver [1,2,5])]+ },+ Result { resultIn = src2, resultFor = qa,+ resultVersions = Right $ rvers [("aeson", Just $ ver [0,8,0,2])]+ },+ Result { resultIn = src7, resultFor = qc,+ resultVersions = Right $ rvers [("conduit", Just $ ver [1,2,7])]+ },+ Result { resultIn = src7, resultFor = qa,+ resultVersions = Right $ rvers [("aeson", Just $ ver [0,11,2,1])]+ }+ ]+ got <- processCommand comm+ got `shouldBe` expected+ ++singleCase :: PackageSource -> Query -> Either ErrorMsg ResultVersions -> IO ()+singleCase src query exp_ret_vers = singleCase' src query (`shouldBe` exp_ret_vers)++singleCase' :: PackageSource -> Query -> (Either ErrorMsg ResultVersions -> IO a) -> IO a+singleCase' src query checker = do+ [got_ret] <- processCommand comm+ resultIn got_ret `shouldBe` src+ resultFor got_ret `shouldBe` query+ checker $ resultVersions got_ret+ where+ comm = baseCommand { commSources = [src],+ commQueries = [query]+ }++baseCommand :: Command+baseCommand = Command { commBuildPlanDir = "test" </> "data",+ commLogger = defaultLogger { loggerThreshold = Nothing },+ commSources = [],+ commQueries = []+ }
+ test/Staversion/Internal/FormatSpec.hs view
@@ -0,0 +1,84 @@+module Staversion.Internal.FormatSpec (main,spec) where++import Data.Monoid ((<>))+import Test.Hspec++import Staversion.Internal.Format (formatResultsCabal)+import Staversion.Internal.Query+ ( Result(..), PackageSource(..), Query(..),+ Resolver, PackageName+ )++import Staversion.Internal.TestUtil (ver, rvers)+ +++main :: IO ()+main = hspec spec++spec :: Spec+spec = describe "formatResultsCabal" $ do+ it "should return empty text for empty list" $ do+ formatResultsCabal [] `shouldBe` ""+ it "should format a Result in a Cabal way" $ do+ let input = [ Result { resultIn = SourceStackage "lts-6.10",+ resultFor = QueryName "hoge",+ resultVersions = Right $ rvers [("hoge", Just $ ver [3,4,5])]+ }+ ]+ expected = ( "------ lts-6.10\n"+ <> "hoge ==3.4.5\n"+ <> "\n"+ )+ formatResultsCabal input `shouldBe` expected+ + it "should group Results by PackageSource with preserved order" $ do+ let input = [ simpleResult "source_c" "hoge" [0,5,7],+ simpleResult "source_a" "hoge" [1,0,0],+ simpleResult "source_b" "foobar" [0,2,5,3],+ simpleResult "source_b" "hoge" [1,2,0],+ simpleResult "source_a" "quux" [300,5],+ simpleResult "source_a" "foobar" [0,3,2],+ simpleResult "source_b" "quux" [299,10]+ ]+ expected = ( "------ source_c\n"+ <> "hoge ==0.5.7\n"+ <> "\n"+ <> "------ source_a\n"+ <> "hoge ==1.0.0,\n"+ <> "quux ==300.5,\n"+ <> "foobar ==0.3.2\n"+ <> "\n"+ <> "------ source_b\n"+ <> "foobar ==0.2.5.3,\n"+ <> "hoge ==1.2.0,\n"+ <> "quux ==299.10\n"+ <> "\n"+ )+ formatResultsCabal input `shouldBe` expected+ it "should not put comma at the last non-N/A entry even if it is followed by N/A entries" $ do+ let input = [ simpleResult "s" "hoge" [1,0,0],+ simpleResult "s" "not-found-1" [],+ simpleResult "s" "foobar" [2,0,0],+ simpleResult "s" "not-found-2" [],+ simpleResult "s" "not-found-3" []+ ]+ expected = ( "------ s\n"+ <> "hoge ==1.0.0,\n"+ <> "-- not-found-1 N/A,\n"+ <> "foobar ==2.0.0\n"+ <> "-- not-found-2 N/A,\n"+ <> "-- not-found-3 N/A\n"+ <> "\n"+ )+ formatResultsCabal input `shouldBe` expected++simpleResult :: Resolver -> PackageName -> [Int] -> Result+simpleResult res name vs = Result { resultIn = SourceStackage res,+ resultFor = QueryName name,+ resultVersions = Right $ rvers [(name, mversion)]+ }+ where+ mversion = case vs of+ [] -> Nothing+ _ -> Just $ ver vs
+ test/Staversion/Internal/TestUtil.hs view
@@ -0,0 +1,13 @@+module Staversion.Internal.TestUtil+ ( ver, rvers+ ) where++import Data.Version (Version(..))+import Staversion.Internal.Query (PackageName, ResultVersions, resultVersionsFromList)++ver :: [Int] -> Version+ver vs = Version vs []++rvers :: [(PackageName, Maybe Version)] -> ResultVersions+rvers = resultVersionsFromList+
+ test/data/conpact_build_plan.yaml view
@@ -0,0 +1,97 @@+github-users:+ yesodweb:+ - snoyberg+system-info:+ core-packages:+ ghc: '7.10.3'+ hoopl: '3.10.0.2'+ bytestring: '0.10.6.0'+ unix: '2.7.1.0'+ base: '4.8.2.0'+ time: '1.5.0.1'+ hpc: '0.6.0.2'+ filepath: '1.4.0.0'+ process: '1.2.3.0'+ array: '0.5.1.0'+ integer-gmp: '1.0.0.0'+ bin-package-db: '0.0.0.0'+ containers: '0.5.6.2'+ binary: '0.7.5.0'+ ghc-prim: '0.4.0.0'+ transformers: '0.4.2.0'+ deepseq: '1.4.1.1'+ pretty: '1.1.2.0'+ template-haskell: '2.10.0.0'+ directory: '1.2.2.0'+ ghc-version: '7.10.3'+ os: linux+ core-executables:+ - ghc+ - ghc-7.10.3+ - ghc-pkg+ - ghc-pkg-7.10.3+ - ghci+ - ghci-7.10.3+ - haddock+ - haddock-ghc-7.10.3+ - hp2ps+ - hpc+ - hsc2hs+ - runghc+ - runghc-7.10.3+ - runhaskell+ arch: x86_64+packages:+ drawille:+ users: []+ constraints:+ library-profiling: true+ flags: {}+ build-benchmarks: true+ skip-build: false+ tests: expect-success+ haddocks: expect-success+ maintainer: Pedro Tacla Yamada <tacla.yamada@gmail.com> @yamadapc+ version-range: ! '>=0.1.0.6 && <0.2'+ version: '0.1.0.6'+ github-pings:+ - yamadapc+ description:+ modules:+ - System.Drawille+ provided-exes:+ - image2term+ - senoid+ packages:+ base:+ components:+ - library+ - test-suite+ range: ==4.*+ hspec:+ components:+ - test-suite+ range: ! '>=1.11 && <2.3'+ containers:+ components:+ - library+ - test-suite+ range: ==0.5.*+ QuickCheck:+ components:+ - test-suite+ range: ! '>=2.6 && <3'+ tools: {}+tools:+- name: alex+ version: '3.1.7'+- name: c2hs+ version: '0.27.1'+- name: cpphs+ version: '1.19.3'+- name: happy+ version: '1.19.5'+- name: hsx2hs+ version: '0.13.4'+- name: gtk2hs-buildtools+ version: '0.13.0.5'
+ test/data/lts-2.22_conpact.yaml view
@@ -0,0 +1,497 @@+github-users:+ yesodweb:+ - snoyberg+ silkapp:+ - bergmark+ - hesselink+ elm-lang:+ - JoeyEremondi+ snapframework:+ - mightybyte+ haskell-ro:+ - mihaimaruseac+ faylang:+ - bergmark+ fpco:+ - snoyberg+ diagrams:+ - bergey+ - byorgey+ - fryguybob+ - jeffreyrosenbluth+system-info:+ core-packages:+ ghc: '7.8.4'+ hoopl: '3.10.0.1'+ bytestring: '0.10.4.0'+ unix: '2.7.0.1'+ haskeline: '0.7.1.2'+ Cabal: '1.18.1.5'+ base: '4.7.0.2'+ time: '1.4.2'+ xhtml: '3000.2.1'+ haskell98: '2.0.0.3'+ hpc: '0.6.0.1'+ filepath: '1.3.0.2'+ process: '1.2.0.0'+ array: '0.5.0.0'+ integer-gmp: '0.5.1.0'+ bin-package-db: '0.0.0.0'+ containers: '0.5.5.1'+ haskell2010: '1.1.2.0'+ binary: '0.7.1.0'+ ghc-prim: '0.3.1.0'+ old-time: '1.1.0.2'+ old-locale: '1.0.0.6'+ rts: '1.0'+ terminfo: '0.4.0.0'+ transformers: '0.3.0.0'+ deepseq: '1.3.0.2'+ pretty: '1.1.1.1'+ template-haskell: '2.9.0.0'+ directory: '1.2.1.0'+ ghc-version: '7.8.4'+ os: linux+ core-executables:+ - ghc+ - ghc-7.8.4+ - ghc-pkg+ - ghc-pkg-7.8.4+ - ghci+ - ghci-7.8.4+ - haddock+ - haddock-ghc-7.8.4+ - hp2ps+ - hpc+ - hsc2hs+ - runghc+ - runghc-7.8.4+ - runhaskell+ arch: x86_64+packages:+ conduit:+ users:+ - BlastHTTP+ - MFlow+ - MusicBrainz+ - amazonka+ - amazonka-core+ - authenticate+ - aws+ - binary-conduit+ - bloodhound+ - bzlib-conduit+ - cabal-src+ - cereal-conduit+ - classy-prelude-conduit+ - conduit+ - conduit-combinators+ - conduit-extra+ - cryptohash-conduit+ - csv-conduit+ - esqueleto+ - fb+ - gitlib+ - gitlib-libgit2+ - gitlib-test+ - hOpenPGP+ - hackage-mirror+ - hoogle+ - hopenpgp-tools+ - html-conduit+ - http-conduit+ - http-reverse-proxy+ - imagesize-conduit+ - keter+ - lzma-conduit+ - markdown+ - mime-mail-ses+ - monad-logger+ - network-conduit+ - network-conduit-tls+ - osdkeys+ - pagerduty+ - persistent+ - persistent-mongoDB+ - persistent-mysql+ - persistent-postgresql+ - persistent-sqlite+ - project-template+ - shell-conduit+ - simple-sendfile+ - soap+ - stackage-cli+ - stackage-curator+ - stm-conduit+ - tagstream-conduit+ - wai-conduit+ - wai-middleware-consul+ - xml-conduit+ - yackage+ - yaml+ - yesod-auth+ - yesod-auth-fb+ - yesod-bin+ - yesod-core+ - yesod-eventsource+ - yesod-fb+ - yesod-persistent+ - yesod-sitemap+ - yesod-static+ - yesod-websockets+ constraints:+ library-profiling: true+ flags: {}+ build-benchmarks: true+ skip-build: false+ tests: expect-success+ haddocks: expect-success+ version-range: ! '>=1.2.5 && <1.3'+ version: '1.2.5'+ github-pings:+ - snoyberg+ description:+ modules:+ - Data.Conduit+ - Data.Conduit.Internal+ - Data.Conduit.Internal.Fusion+ - Data.Conduit.Internal.List.Stream+ - Data.Conduit.Lift+ - Data.Conduit.List+ provided-exes: []+ packages:+ exceptions:+ components:+ - library+ - test-suite+ range: ! '>=0.6'+ void:+ components:+ - library+ - test-suite+ range: ! '>=0.5.5'+ mwc-random:+ components:+ - benchmark+ range: -any+ base:+ components:+ - library+ - test-suite+ - benchmark+ range: ! '>=4.3 && <5'+ hspec:+ components:+ - test-suite+ - benchmark+ range: ! '>=1.3'+ kan-extensions:+ components:+ - benchmark+ range: -any+ criterion:+ components:+ - benchmark+ range: -any+ lifted-base:+ components:+ - library+ range: ! '>=0.1'+ conduit:+ components:+ - test-suite+ - benchmark+ range: -any+ containers:+ components:+ - test-suite+ - benchmark+ range: -any+ mtl:+ components:+ - library+ - test-suite+ range: -any+ mmorph:+ components:+ - library+ range: -any+ transformers-base:+ components:+ - library+ range: ! '>=0.4.1 && <0.5'+ transformers:+ components:+ - library+ - test-suite+ - benchmark+ range: ! '>=0.2.2 && <0.5'+ deepseq:+ components:+ - benchmark+ range: -any+ QuickCheck:+ components:+ - test-suite+ range: ! '>=2.5'+ resourcet:+ components:+ - library+ - test-suite+ range: ==1.1.*+ safe:+ components:+ - test-suite+ range: -any+ vector:+ components:+ - benchmark+ range: -any+ tools: {}+ aeson:+ users:+ - HTF+ - MusicBrainz+ - Spock+ - aeson+ - aeson-pretty+ - aeson-qq+ - aeson-utils+ - amazonka-core+ - arbtt+ - authenticate+ - aws+ - bake+ - blank-canvas+ - bloodhound+ - classy-prelude-yesod+ - consul-haskell+ - criterion+ - descriptive+ - ede+ - fay+ - fb+ - generic-aeson+ - gipeda+ - gitson+ - groundhog+ - groundhog-th+ - hOpenPGP+ - haskell-names+ - haskell-packages+ - hasql-postgres+ - hdocs+ - heist+ - hoauth2+ - holy-project+ - hoogle+ - hopenpgp-tools+ - hpc-coveralls+ - hsdev+ - hspec-wai-json+ - ide-backend+ - ide-backend-common+ - jmacro+ - jmacro-rpc+ - jmacro-rpc-happstack+ - jmacro-rpc-snap+ - jose-jwt+ - json-autotype+ - json-schema+ - kansas-comet+ - keter+ - koofr-client+ - lens-aeson+ - mandrill+ - monad-logger-json+ - pagerduty+ - pandoc+ - pandoc-citeproc+ - pandoc-types+ - persistent+ - persistent-mongoDB+ - persistent-mysql+ - persistent-postgresql+ - persistent-sqlite+ - persistent-template+ - pipes-aeson+ - postgresql-simple+ - present+ - quandl-api+ - rest-core+ - rest-gen+ - rest-stringmap+ - rest-types+ - rethinkdb-client-driver+ - scotty+ - servant-client+ - servant-docs+ - servant-jquery+ - servant-server+ - shakespeare+ - snap+ - snaplet-fay+ - sourcemap+ - stackage-build-plan+ - stackage-curator+ - stackage-install+ - stackage-types+ - stackage-upload+ - statistics+ - stylish-haskell+ - thyme+ - tttool+ - users+ - users-postgresql-simple+ - users-test+ - waitra+ - webdriver+ - wreq+ - xml-to-json+ - yaml+ - yesod+ - yesod-auth+ - yesod-auth-deskcom+ - yesod-auth-fb+ - yesod-auth-oauth2+ - yesod-core+ - yesod-fay+ - yesod-fb+ - yesod-form+ - yesod-text-markdown+ constraints:+ library-profiling: true+ flags:+ old-locale: true+ build-benchmarks: true+ skip-build: false+ tests: expect-success+ haddocks: expect-success+ version-range: ! '>=0.8.0.2 && <0.8.1'+ version: '0.8.0.2'+ github-pings:+ - bos+ description:+ modules:+ - Data.Aeson+ - Data.Aeson.Encode+ - Data.Aeson.Generic+ - Data.Aeson.Parser+ - Data.Aeson.TH+ - Data.Aeson.Types+ provided-exes: []+ packages:+ test-framework-hunit:+ components:+ - test-suite+ range: -any+ bytestring:+ components:+ - library+ - test-suite+ range: ! '>=0.10.4.0'+ test-framework:+ components:+ - test-suite+ range: -any+ base:+ components:+ - library+ - test-suite+ range: ==4.*+ time:+ components:+ - library+ - test-suite+ range: <1.5+ unordered-containers:+ components:+ - library+ - test-suite+ range: ! '>=0.2.3.0'+ text:+ components:+ - library+ - test-suite+ range: ! '>=1.1.1.0'+ syb:+ components:+ - library+ range: -any+ test-framework-quickcheck2:+ components:+ - test-suite+ range: -any+ dlist:+ components:+ - library+ range: ! '>=0.2'+ HUnit:+ components:+ - test-suite+ range: -any+ containers:+ components:+ - library+ - test-suite+ range: -any+ ghc-prim:+ components:+ - library+ - test-suite+ range: ! '>=0.2'+ old-locale:+ components:+ - library+ range: -any+ mtl:+ components:+ - library+ range: -any+ hashable:+ components:+ - library+ range: ! '>=1.1.2.0'+ attoparsec:+ components:+ - library+ - test-suite+ range: ! '>=0.11.3.4'+ deepseq:+ components:+ - library+ range: -any+ scientific:+ components:+ - library+ range: ! '>=0.3.1 && <0.4'+ QuickCheck:+ components:+ - test-suite+ range: -any+ aeson:+ components:+ - test-suite+ range: -any+ template-haskell:+ components:+ - library+ - test-suite+ range: ! '>=2.4'+ vector:+ components:+ - library+ - test-suite+ range: ! '>=0.7.1'+ tools: {}+tools:+- name: alex+ version: '3.1.4'+- name: c2hs+ version: '0.25.2'+- name: cpphs+ version: '1.19.2'+- name: happy+ version: '1.19.5'+- name: gtk2hs-buildtools+ version: '0.13.0.4'
+ test/data/lts-4.2.yaml view
file too large to diff
+ test/data/lts-7.0_conpact.yaml view
@@ -0,0 +1,676 @@+all-cabal-hashes-commit: 5d00e91223715777b5551a98a2a0863e72c7fc0f+github-users:+ yesodweb:+ - snoyberg+ telegram-api:+ - klappvisor+ stackbuilders:+ - jpvillaisaza+ - jsantos17+ - jsl+ - mrkkrp+ - sestrella+ silkapp:+ - bergmark+ - hesselink+ Happstack:+ - stepcut+system-info:+ core-packages:+ ghc: '8.0.1'+ hoopl: '3.10.2.1'+ bytestring: '0.10.8.1'+ unix: '2.7.2.0'+ base: '4.9.0.0'+ time: '1.6.0.1'+ hpc: '0.6.0.3'+ filepath: '1.4.1.0'+ process: '1.4.2.0'+ array: '0.5.1.1'+ integer-gmp: '1.0.0.1'+ containers: '0.5.7.1'+ ghc-boot: '8.0.1'+ binary: '0.8.3.0'+ ghc-prim: '0.5.0.0'+ ghci: '8.0.1'+ rts: '1.0'+ transformers: '0.5.2.0'+ deepseq: '1.4.2.0'+ ghc-boot-th: '8.0.1'+ pretty: '1.1.3.3'+ template-haskell: '2.11.0.0'+ directory: '1.2.6.2'+ ghc-version: '8.0.1'+ os: linux+ core-executables:+ - ghc+ - ghc-8.0.1+ - ghc-pkg+ - ghc-pkg-8.0.1+ - ghci+ - ghci-8.0.1+ - haddock+ - haddock-ghc-8.0.1+ - hp2ps+ - hpc+ - hsc2hs+ - runghc+ - runghc-8.0.1+ - runhaskell+ arch: x86_64+packages:+ conduit:+ users:+ - BlastHTTP+ - HTTP+ - MFlow+ - MusicBrainz+ - amazonka+ - amazonka-core+ - amazonka-test+ - atndapi+ - atom-conduit+ - authenticate+ - aws+ - b9+ - binary-conduit+ - bitcoin-api-extra+ - bzlib-conduit+ - cabal-src+ - cassava-conduit+ - cereal-conduit+ - classy-prelude-conduit+ - conduit+ - conduit-combinators+ - conduit-extra+ - conduit-iconv+ - conduit-parse+ - cryptohash-conduit+ - cryptonite-conduit+ - dns+ - editor-open+ - fb+ - fold-debounce-conduit+ - fsnotify-conduit+ - gitlib+ - gitlib-libgit2+ - gitlib-test+ - gogol+ - gogol-core+ - hOpenPGP+ - hackage-mirror+ - haskell-spacegoo+ - haskoin-core+ - hoogle+ - hopenpgp-tools+ - html-conduit+ - http-conduit+ - http-reverse-proxy+ - hw-conduit+ - hw-rankselect+ - hw-succinct+ - imagesize-conduit+ - imm+ - irc-client+ - irc-conduit+ - keter+ - machines+ - markdown+ - mime-mail-ses+ - monad-logger+ - ndjson-conduit+ - network-conduit-tls+ - opml-conduit+ - osdkeys+ - pager+ - pagerduty+ - persistent+ - persistent-postgresql+ - persistent-sqlite+ - project-template+ - rss-conduit+ - sandi+ - serf+ - shell-conduit+ - simple-sendfile+ - soap+ - stack+ - stackage-curator+ - stm-conduit+ - store+ - tagstream-conduit+ - thumbnail-plus+ - twitter-conduit+ - wai-conduit+ - wai-middleware-consul+ - withdependencies+ - xlsior+ - xlsx+ - xml-conduit+ - xml-conduit-parse+ - yackage+ - yaml+ - yesod-auth+ - yesod-bin+ - yesod-core+ - yesod-eventsource+ - yesod-fb+ - yesod-persistent+ - yesod-sitemap+ - yesod-static+ - yesod-websockets+ - zip+ constraints:+ benches: expect-success+ library-profiling: true+ flags: {}+ build-benchmarks: true+ skip-build: false+ tests: expect-success+ haddocks: expect-success+ configure-args: []+ version-range: -any+ version: '1.2.7'+ cabal-file-info:+ size: 4041+ hashes:+ MD5: 3cac157771a3fe620548760f44a27285+ Skein512_512: 70ecee198d5e0281de4163b8ec8f9e06231dd82d1fe8163a0632ea91ed7c0e35313f622cfc4cb250b05fd893d89901b67a7ec4e4fb3c019b6f25a7d23ecc3018+ SHA1: 147aae20b2b1a425833ddf7825580475105b86eb+ SHA512: 888471c06ba9db0a84d7212af48461f33277fa61668391a61cd7c2e8cda95d768c10b7cf8c9f1570249859a05e4eb8c6ab9125ecda37cb3963f63651844fd530+ SHA256: f5e83ea27ee3cc4a6c190336143d38a468c228f53342a49c63d1fac18e4079c7+ GitSHA1: 7750ddac3f1edf2499d37dbbcbcfac37db6a89db+ github-pings:+ - snoyberg+ description:+ cabal-version: '1.8'+ modules:+ - Data.Conduit+ - Data.Conduit.Internal+ - Data.Conduit.Internal.Fusion+ - Data.Conduit.Internal.List.Stream+ - Data.Conduit.Lift+ - Data.Conduit.List+ provided-exes: []+ packages:+ exceptions:+ components:+ - library+ - test-suite+ range: ! '>=0.6'+ mwc-random:+ components:+ - benchmark+ range: -any+ base:+ components:+ - library+ - test-suite+ - benchmark+ range: ! '>=4.5 && <5'+ hspec:+ components:+ - test-suite+ - benchmark+ range: ! '>=1.3'+ kan-extensions:+ components:+ - benchmark+ range: -any+ criterion:+ components:+ - benchmark+ range: -any+ lifted-base:+ components:+ - library+ range: ! '>=0.1'+ conduit:+ components:+ - test-suite+ - benchmark+ range: -any+ containers:+ components:+ - test-suite+ - benchmark+ range: -any+ mtl:+ components:+ - library+ - test-suite+ range: -any+ mmorph:+ components:+ - library+ range: -any+ transformers-base:+ components:+ - library+ range: ! '>=0.4.1 && <0.5'+ transformers:+ components:+ - library+ - test-suite+ - benchmark+ range: ! '>=0.2.2'+ deepseq:+ components:+ - benchmark+ range: -any+ QuickCheck:+ components:+ - test-suite+ range: ! '>=2.7'+ resourcet:+ components:+ - library+ - test-suite+ range: ==1.1.*+ safe:+ components:+ - test-suite+ range: -any+ vector:+ components:+ - benchmark+ range: -any+ tools: {}+ aeson:+ users:+ - HTF+ - MusicBrainz+ - Spock-api+ - Spock-core+ - aeson+ - aeson-better-errors+ - aeson-casing+ - aeson-compat+ - aeson-injector+ - aeson-pretty+ - aeson-qq+ - aeson-utils+ - amazonka-core+ - amazonka-test+ - api-field-json-th+ - arbtt+ - atndapi+ - authenticate+ - aws+ - b9+ - bake+ - base32string+ - base58string+ - bimap-server+ - binary-orphans+ - binary-tagged+ - bitcoin-api+ - bitcoin-payment-channel+ - bitx-bitcoin+ - blank-canvas+ - bloodhound+ - bower-json+ - cabal2nix+ - cacophony+ - cayley-client+ - cheapskate+ - clash-lib+ - classy-prelude-yesod+ - clckwrks+ - clckwrks-plugin-page+ - configuration-tools+ - consul-haskell+ - criterion+ - descriptive+ - distribution-nixpkgs+ - docopt+ - doctest-discover+ - ede+ - ekg+ - ekg-json+ - elm-bridge+ - emailaddress+ - envelope+ - etcd+ - eventstore+ - fast-builder+ - fay+ - fb+ - find-clumpiness+ - forecast-io+ - generic-aeson+ - gipeda+ - giphy-api+ - github-types+ - github-webhook-handler+ - gitson+ - glabrous+ - gogol+ - gogol-core+ - google-cloud+ - graylog+ - hOpenPGP+ - hailgun+ - handwriting+ - happstack-authenticate+ - haskell-names+ - haskell-neo4j-client+ - haskell-packages+ - haskell-spacegoo+ - haskoin-core+ - hasql+ - hexstring+ - hjsonpointer+ - hjsonschema+ - hoauth2+ - holy-project+ - hoogle+ - hopenpgp-tools+ - hpack+ - hpack-convert+ - hpc-coveralls+ - hruby+ - hsebaysdk+ - hspec-expectations-pretty-diff+ - hspec-golden-aeson+ - hspec-wai-json+ - hspec-webdriver+ - htoml+ - http-conduit+ - http-streams+ - http2+ - hworker+ - hworker-ses+ - ical+ - idris+ - imm+ - inline-r+ - insert-ordered-containers+ - jmacro+ - jmacro-rpc+ - jmacro-rpc-happstack+ - jose+ - jose-jwt+ - json-autotype+ - json-rpc-generic+ - json-schema+ - jwt+ - kansas-comet+ - kawhi+ - keter+ - koofr-client+ - kraken+ - language-puppet+ - lens-aeson+ - mandrill+ - microformats2-parser+ - microlens-aeson+ - moesocks+ - monad-logger-json+ - mustache+ - ndjson-conduit+ - octane+ - omnifmt+ - opaleye+ - opensource+ - pagerduty+ - pandoc+ - pandoc-citeproc+ - pandoc-types+ - path+ - persistent+ - persistent-postgresql+ - persistent-redis+ - persistent-sqlite+ - persistent-template+ - pinboard+ - pipes-aeson+ - postgresql-binary+ - postgresql-query+ - postgresql-simple+ - profiteur+ - purescript+ - quantum-random+ - ratel+ - rest-core+ - rest-gen+ - rest-stringmap+ - rest-types+ - rethinkdb+ - rethinkdb-client-driver+ - scotty+ - servant+ - servant-aeson-specs+ - servant-client+ - servant-docs+ - servant-js+ - servant-mock+ - servant-purescript+ - servant-server+ - servant-subscriber+ - servant-swagger+ - servant-swagger-ui+ - servant-yaml+ - serversession+ - shakespeare+ - simple+ - simple-templates+ - slug+ - smoothie+ - smsaero+ - solga+ - sourcemap+ - stache+ - stack+ - stackage-curator+ - stackage-types+ - statistics+ - stratosphere+ - strict-base-types+ - stripe-core+ - strive+ - stylish-haskell+ - swagger+ - swagger2+ - text-region+ - these+ - thyme+ - tttool+ - twitter-conduit+ - twitter-feed+ - twitter-types+ - ua-parser+ - userid+ - users+ - wai-extra+ - wai-middleware-content-type+ - waitra+ - webdriver+ - webdriver-angular+ - werewolf+ - werewolf-slack+ - wreq+ - xlsx-tabular+ - yahoo-finance-api+ - yaml+ - yesod+ - yesod-auth+ - yesod-auth-oauth2+ - yesod-core+ - yesod-fay+ - yesod-fb+ - yesod-form+ - yesod-gitrev+ - yesod-job-queue+ - yesod-static-angular+ constraints:+ benches: expect-success+ library-profiling: true+ flags: {}+ build-benchmarks: true+ skip-build: false+ tests: expect-success+ haddocks: expect-success+ maintainer: Adam Bergmark <adam@bergmark.nl> @bergmark+ configure-args: []+ version-range: <1.0+ version: '0.11.2.1'+ cabal-file-info:+ size: 4634+ hashes:+ MD5: b2b4ef66114e351b788af8df16513df9+ Skein512_512: 2c1a12cacd8bb458c11d2b94125f3fcdc976f81daf2cf7f6d4795a734ea0accbbc950916be70703cd088be646032c1aef3108f3b220baf8c931efd4e6a1dec2d+ SHA1: 92b374f030103c92dbf9ce22240dde0109e28209+ SHA512: 33bc7d601f800354ce5b8087122b4d9cc40d1d62623f5a89e355bf04ea4a2d92688ff3941cb0d8586179bdd01c902e99eb504ca66681540f21cdab1fc00e54d7+ SHA256: 9d08400d818255b7ee068ed6cfe2d4db1270066e4699f8c85afa6efc63787821+ GitSHA1: 06f8123070664e3d80d39baf5e3e8c1f92c3003c+ github-pings:+ - bos+ description:+ cabal-version: '1.10'+ modules:+ - Data.Aeson+ - Data.Aeson.Encode+ - Data.Aeson.Internal+ - Data.Aeson.Internal.Time+ - Data.Aeson.Parser+ - Data.Aeson.TH+ - Data.Aeson.Types+ provided-exes: []+ packages:+ test-framework-hunit:+ components:+ - test-suite+ range: -any+ bytestring:+ components:+ - library+ - test-suite+ range: ! '>=0.10.4.0'+ test-framework:+ components:+ - test-suite+ range: -any+ fail:+ components:+ - library+ range: ==4.9.*+ base:+ components:+ - library+ - test-suite+ range: ! '>=4.5 && <5'+ time:+ components:+ - library+ - test-suite+ range: ! '>=1.5'+ unordered-containers:+ components:+ - library+ - test-suite+ range: ! '>=0.2.5.0'+ text:+ components:+ - library+ - test-suite+ range: ! '>=1.1.1.0'+ syb:+ components:+ - library+ range: -any+ test-framework-quickcheck2:+ components:+ - test-suite+ range: -any+ dlist:+ components:+ - library+ range: ! '>=0.2'+ HUnit:+ components:+ - test-suite+ range: -any+ base-orphans:+ components:+ - test-suite+ range: ! '>=0.5.3 && <0.6'+ tagged:+ components:+ - library+ - test-suite+ range: ! '>=0.8.3 && <0.9'+ containers:+ components:+ - library+ - test-suite+ range: -any+ quickcheck-instances:+ components:+ - test-suite+ range: ! '>=0.3.12'+ ghc-prim:+ components:+ - library+ - test-suite+ range: ! '>=0.2'+ mtl:+ components:+ - library+ range: -any+ hashable:+ components:+ - library+ - test-suite+ range: ! '>=1.1.2.0'+ attoparsec:+ components:+ - library+ - test-suite+ range: ! '>=0.13.0.1'+ transformers:+ components:+ - library+ range: -any+ deepseq:+ components:+ - library+ range: -any+ scientific:+ components:+ - library+ range: ! '>=0.3.1 && <0.4'+ QuickCheck:+ components:+ - test-suite+ range: ! '>=2.7 && <2.10'+ aeson:+ components:+ - test-suite+ range: -any+ template-haskell:+ components:+ - library+ - test-suite+ range: ! '>=2.7'+ vector:+ components:+ - library+ - test-suite+ range: ! '>=0.8'+ tools: {}+tools:+- name: alex+ version: '3.1.7'+- name: c2hs+ version: '0.28.1'+- name: cabal-install+ version: '1.24.0.0'+- name: cpphs+ version: '1.20.2'+- name: happy+ version: '1.19.5'+- name: hsx2hs+ version: '0.13.5'+- name: gtk2hs-buildtools+ version: '0.13.2.1'