staversion 0.1.1.0 → 0.1.2.0
raw patch · 14 files changed
+263/−55 lines, 14 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Staversion.Internal.BuildPlan: parseVersionText :: Text -> Maybe Version
+ Staversion.Internal.BuildPlan: instance GHC.Base.Monoid Staversion.Internal.BuildPlan.BuildPlan
+ Staversion.Internal.BuildPlan.Hackage: data RegisteredVersions
+ Staversion.Internal.BuildPlan.Hackage: fetchPreferredVersions :: Manager -> PackageName -> IO (Either ErrorMsg RegisteredVersions)
+ Staversion.Internal.BuildPlan.Hackage: instance Data.Aeson.Types.FromJSON.FromJSON Staversion.Internal.BuildPlan.Hackage.RegisteredVersions
+ Staversion.Internal.BuildPlan.Hackage: instance GHC.Classes.Eq Staversion.Internal.BuildPlan.Hackage.RegisteredVersions
+ Staversion.Internal.BuildPlan.Hackage: instance GHC.Classes.Ord Staversion.Internal.BuildPlan.Hackage.RegisteredVersions
+ Staversion.Internal.BuildPlan.Hackage: instance GHC.Show.Show Staversion.Internal.BuildPlan.Hackage.RegisteredVersions
+ Staversion.Internal.BuildPlan.Hackage: latestVersion :: RegisteredVersions -> Maybe Version
+ Staversion.Internal.BuildPlan.Hackage: parsePreferredVersionsJSON :: ByteString -> Either ErrorMsg RegisteredVersions
+ Staversion.Internal.BuildPlan.Version: VersionJSON :: Version -> VersionJSON
+ Staversion.Internal.BuildPlan.Version: [unVersionJSON] :: VersionJSON -> Version
+ Staversion.Internal.BuildPlan.Version: instance Data.Aeson.Types.FromJSON.FromJSON Staversion.Internal.BuildPlan.Version.VersionJSON
+ Staversion.Internal.BuildPlan.Version: instance GHC.Classes.Eq Staversion.Internal.BuildPlan.Version.VersionJSON
+ Staversion.Internal.BuildPlan.Version: instance GHC.Classes.Ord Staversion.Internal.BuildPlan.Version.VersionJSON
+ Staversion.Internal.BuildPlan.Version: instance GHC.Show.Show Staversion.Internal.BuildPlan.Version.VersionJSON
+ Staversion.Internal.BuildPlan.Version: newtype VersionJSON
+ Staversion.Internal.BuildPlan.Version: parseVersionText :: Text -> Maybe Version
+ Staversion.Internal.Query: SourceHackage :: PackageSource
- Staversion.Internal.BuildPlan: loadBuildPlan :: BuildPlanManager -> PackageSource -> IO (Either ErrorMsg BuildPlan)
+ Staversion.Internal.BuildPlan: loadBuildPlan :: BuildPlanManager -> [PackageName] -> PackageSource -> IO (Either ErrorMsg BuildPlan)
Files
- ChangeLog.md +4/−0
- README.md +14/−6
- src/Staversion/Internal/BuildPlan.hs +35/−19
- src/Staversion/Internal/BuildPlan/Hackage.hs +51/−0
- src/Staversion/Internal/BuildPlan/Version.hs +30/−0
- src/Staversion/Internal/Command.hs +11/−7
- src/Staversion/Internal/Exec.hs +7/−3
- src/Staversion/Internal/Query.hs +2/−0
- staversion.cabal +8/−3
- test/NetworkTest.hs +56/−6
- test/Staversion/Internal/BuildPlan/HackageSpec.hs +22/−0
- test/Staversion/Internal/BuildPlan/VersionSpec.hs +21/−0
- test/Staversion/Internal/BuildPlanSpec.hs +1/−11
- test/data/aeson_preferred.json +1/−0
ChangeLog.md view
@@ -1,5 +1,9 @@ # Revision history for staversion +## 0.1.2.0 -- 2016-11-10++* New option `--hackage`, which searches hackage for the latest version number.+ ## 0.1.1.0 -- 2016-11-03 * Now staversion fetches build plan YAML files over network, if necessary.
README.md view
@@ -2,7 +2,7 @@  -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 is a command-line tool to look for version numbers of Haskell packages. It mainly focuses on package versions in stackage, i.e. 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@@ -15,21 +15,29 @@ ------ lts-7.0 conduit ==1.2.7 - $ staversion --resolver lts-4.2 --resolver lts-7.0 conduit base+ $ staversion --resolver lts-4.2 --resolver lts-6 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+ ------ lts-6+ conduit ==1.2.8,+ base ==4.8.2.0 staversion first reads build plan YAML files that are stored locally in your computer, then it tries to fetch them over network. +You can also look up the latest version numbers hosted on hackage. + $ staversion --hackage conduit base+ ------ latest in hackage+ conduit ==1.2.8,+ base ==4.9.0.0++See `--help` message for detail.++ ## TODO -- 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. - Cache build plans in some local storage (SQLite?)
src/Staversion/Internal/BuildPlan.hs view
@@ -4,6 +4,7 @@ -- Maintainer: Toshio Ito <debug.ito@gmail.com> -- -- __This is an internal module. End-users should not use it.__+{-# LANGUAGE GeneralizedNewtypeDeriving #-} module Staversion.Internal.BuildPlan ( -- * Entry APIs BuildPlan,@@ -13,7 +14,6 @@ loadBuildPlan, -- * Low-level APIs loadBuildPlanYAML,- parseVersionText, -- * For tests _setDisambiguator ) where@@ -22,22 +22,21 @@ import Control.Exception (throwIO, catchJust, IOException, catch) import Control.Monad.Trans.Except (runExceptT, ExceptT(..)) import Control.Monad.IO.Class (liftIO)+import Control.Monad (mapM) import Data.Aeson (FromJSON(..), (.:), Value(..), Object) import Data.ByteString (ByteString) import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as BSL import qualified Data.HashMap.Strict as HM import Data.IORef (IORef, newIORef, readIORef, writeIORef)-import Data.Maybe (listToMaybe)-import Data.Monoid ((<>))+import Data.Monoid (Monoid, (<>), mconcat) import Data.Text (Text, unpack) import Data.Traversable (Traversable(traverse))-import Data.Version (Version, parseVersion)+import Data.Version (Version) import qualified Data.Yaml as Yaml import System.FilePath ((</>), (<.>)) import qualified System.IO.Error as IOE import Text.Read (readMaybe)-import Text.ParserCombinators.ReadP (readP_to_S) import Staversion.Internal.Log ( Logger, logDebug, logWarn@@ -47,6 +46,10 @@ ( PackageName, PackageSource(..), ErrorMsg, Resolver )+import Staversion.Internal.BuildPlan.Hackage+ ( RegisteredVersions, latestVersion,+ fetchPreferredVersions+ ) import Staversion.Internal.BuildPlan.Stackage ( Disambiguator, fetchDisambiguator,@@ -55,25 +58,25 @@ PartialResolver(..), ExactResolver, fetchBuildPlanYAML )+import Staversion.Internal.BuildPlan.Version (unVersionJSON) -- | A data structure that keeps a map between package names and their -- versions.-newtype BuildPlan = BuildPlan (HM.HashMap PackageName Version)+newtype BuildPlan = BuildPlan (HM.HashMap PackageName Version) deriving (Monoid) 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 (Object o) = traverse (\v -> unVersionJSON <$> 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 (Object o) = unVersionJSON <$> (o .: "version") parsePackageObject _ = empty- versionParser = maybe empty return . parseVersionText parseJSON _ = empty -- | Stateful manager for 'BuildPlan's.@@ -117,18 +120,31 @@ maybeToLoadM :: ErrorMsg -> Maybe a -> LoadM a maybeToLoadM msg = ExceptT . return . maybe (Left msg) Right +httpManagerM :: BuildPlanManager -> LoadM Manager+httpManagerM = maybeToLoadM "It is not allowed to access network." . manHttpManager+ httpExceptionToLoadM :: String -> LoadM a -> LoadM a httpExceptionToLoadM context action = ExceptT $ (runExceptT action) `catch` handler where handler :: OurHttpException -> IO (Either ErrorMsg a) handler e = return $ Left (context ++ ": " ++ show e) -loadBuildPlan :: BuildPlanManager -> PackageSource -> IO (Either ErrorMsg BuildPlan)-loadBuildPlan man (SourceStackage resolver) = runExceptT impl where+loadBuildPlan :: BuildPlanManager+ -> [PackageName] -- ^ package names whose versions the user is interested in.+ -> PackageSource -> IO (Either ErrorMsg BuildPlan)+loadBuildPlan man _ (SourceStackage resolver) = runExceptT impl where impl = loadBuildPlan_stackageLocalFile man resolver `loggedElse'` do e_resolver <- tryDisambiguate man =<< getPresolver loadBuildPlan_stackageLocalFile man (formatResolverString $ PartialExact e_resolver) `loggedElse'` loadBuildPlan_stackageNetwork man e_resolver getPresolver = maybeToLoadM ("Invalid resolver format for stackage.org: " ++ resolver) $ parseResolverString resolver loggedElse' = loggedElse $ manLogger man+loadBuildPlan man names SourceHackage = runExceptT impl where+ impl = do+ http_man <- httpManagerM man+ (mconcat . zipWith registeredVersionToBuildPlan names) <$> mapM (doFetch http_man) names+ logDebug' msg = liftIO $ logDebug (manLogger man) msg+ doFetch http_man name = do+ logDebug' ("Ask hackage for the latest version of " ++ unpack name)+ ExceptT $ fetchPreferredVersions http_man name loadBuildPlan_stackageLocalFile :: BuildPlanManager -> Resolver -> LoadM BuildPlan loadBuildPlan_stackageLocalFile man resolver = ExceptT $ catchJust handleIOError doLoad (return . Left) where@@ -153,7 +169,7 @@ case m_disam of Just d -> return d Nothing -> do- http_man <- maybeToLoadM "It is not allowed to access network." $ manHttpManager bp_man+ http_man <- httpManagerM bp_man logDebug' "Fetch resolver disambiguator from network..." got_d <- ExceptT $ fetchDisambiguator http_man logDebug' "Successfully fetched resolver disambiguator."@@ -163,7 +179,7 @@ loadBuildPlan_stackageNetwork :: BuildPlanManager -> ExactResolver -> LoadM BuildPlan loadBuildPlan_stackageNetwork man e_resolver = do- http_man <- maybeToLoadM "It is not allowed to access network." $ manHttpManager man+ http_man <- httpManagerM man liftIO $ logDebug (manLogger man) ("Fetch build plan from network: resolver = " ++ show e_resolver) yaml_data <- httpExceptionToLoadM ("Downloading build plan failed: " ++ show e_resolver) $ liftIO $ fetchBuildPlanYAML http_man e_resolver ExceptT $ return $ parseBuildPlanYAML $ BSL.toStrict yaml_data@@ -179,11 +195,11 @@ 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 == "")- _setDisambiguator :: BuildPlanManager -> Maybe Disambiguator -> IO () _setDisambiguator bp_man = writeIORef (manDisambiguator bp_man)++registeredVersionToBuildPlan :: PackageName -> RegisteredVersions -> BuildPlan+registeredVersionToBuildPlan name rvers = BuildPlan $ HM.fromList $ pairs where+ pairs = case latestVersion rvers of+ Nothing -> []+ Just v -> [(name, v)]
+ src/Staversion/Internal/BuildPlan/Hackage.hs view
@@ -0,0 +1,51 @@+-- |+-- Module: Staversion.Internal.BuildPlan.Hackage+-- Description: (virtual) BuildPlan expressing the latest Hackage+-- Maintainer: Toshio Ito <debug.ito@gmail.com>+--+-- __This is an internal module. End-users should not use it.__+module Staversion.Internal.BuildPlan.Hackage+ ( -- * entry API+ RegisteredVersions,+ fetchPreferredVersions,+ latestVersion,+ -- * low-level API+ parsePreferredVersionsJSON+ ) where++import Control.Applicative ((<$>), empty)+import qualified Control.Exception as Exception+import Data.Aeson (FromJSON(..), Value(..), (.:), eitherDecode)+import qualified Data.ByteString.Lazy as BSL+import Data.List (sort, reverse)+import Data.Text (unpack)+import Data.Version (Version)++import Staversion.Internal.BuildPlan.Version (unVersionJSON)+import Staversion.Internal.Query (ErrorMsg, PackageName)+import Staversion.Internal.HTTP (Manager, fetchURL, OurHttpException)++data RegisteredVersions = RegisteredVersions { regPreferredVersions :: [Version]+ -- ^ Sorted list of preferred versions of the package.+ -- The head is the latest.+ }+ deriving (Show,Eq,Ord)++instance FromJSON RegisteredVersions where+ parseJSON (Object o) = (RegisteredVersions . reverse . sort . map unVersionJSON) <$> (o .: "normal-version")+ parseJSON _ = empty++parsePreferredVersionsJSON :: BSL.ByteString -> Either ErrorMsg RegisteredVersions+parsePreferredVersionsJSON = either (\e -> Left ("Decoding preferred versions error: " ++ e)) Right . eitherDecode++latestVersion :: RegisteredVersions -> Maybe Version+latestVersion rvers = case regPreferredVersions rvers of+ [] -> Nothing+ (v : _) -> Just v++fetchPreferredVersions :: Manager -> PackageName -> IO (Either ErrorMsg RegisteredVersions)+fetchPreferredVersions man text_name = Exception.handle handler $ parsePreferredVersionsJSON <$> fetchURL man url where+ name = unpack text_name+ url = "http://hackage.haskell.org/package/" ++ name ++ "/preferred.json"+ handler :: OurHttpException -> IO (Either ErrorMsg a)+ handler e = return $ Left ("HTTP error while fetching versions of " ++ name ++ " in hackage: " ++ show e)
+ src/Staversion/Internal/BuildPlan/Version.hs view
@@ -0,0 +1,30 @@+-- |+-- Module: Staversion.Internal.BuildPlan.Version+-- Description: parsing Version+-- Maintainer: Toshio Ito <debug.ito@gmail.com>+--+-- __This is an internal module. End-users should not use it.__+module Staversion.Internal.BuildPlan.Version+ ( parseVersionText,+ VersionJSON(..)+ ) where++import Control.Applicative (empty, pure)+import Data.Aeson (FromJSON(..), Value(..))+import Data.Maybe (listToMaybe)+import Data.Text (Text, unpack)+import Data.Version (Version, parseVersion)+import Text.ParserCombinators.ReadP (readP_to_S)++-- | 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 == "")++-- | a wrapper around 'Version' for JSON I/F+newtype VersionJSON = VersionJSON { unVersionJSON :: Version } deriving (Show,Eq,Ord)++instance FromJSON VersionJSON where+ parseJSON (String t) = maybe empty pure $ fmap VersionJSON $ parseVersionText t+ parseJSON _ = empty
src/Staversion/Internal/Command.hs view
@@ -9,7 +9,7 @@ parseCommandArgs ) where -import Control.Applicative ((<$>), (<*>), optional, some)+import Control.Applicative ((<$>), (<*>), optional, some, (<|>)) import Data.Monoid (mconcat) import Data.Text (pack) import Data.Version (showVersion)@@ -64,19 +64,23 @@ ] 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.help "Directory where build plan YAML files are stored.", Opt.metavar "DIR",- Opt.value (defBuildPlanDir def_comm)+ Opt.value (defBuildPlanDir def_comm),+ Opt.showDefault ]- sources = some $ SourceStackage <$> resolver- resolver = Opt.strOption+ sources = some $ resolver <|> hackage+ resolver = fmap SourceStackage $ Opt.strOption $ mconcat [ Opt.long "resolver", Opt.short 'r', Opt.help "Stackage resolver to search. e.g. \"lts-6.15\"", Opt.metavar "RESOLVER_NAME" ]+ hackage = Opt.flag' SourceHackage+ $ mconcat [ Opt.long "hackage",+ Opt.short 'H',+ Opt.help "Search hackage.org for the latest version."+ ] queries = some $ QueryName <$> package package = fmap pack $ Opt.strArgument $ mconcat [ Opt.help "Name of package whose version you want to check.",
src/Staversion/Internal/Exec.hs view
@@ -11,7 +11,7 @@ import Control.Applicative ((<$>)) import Data.Function (on)-import Data.List (groupBy)+import Data.List (groupBy, nub) import Data.Text (unpack) import qualified Data.Text.Lazy.IO as TLIO @@ -25,7 +25,7 @@ import Staversion.Internal.Format (formatResultsCabal) import Staversion.Internal.Log (logDebug, logError) import Staversion.Internal.Query- ( Query(..), Result(..), PackageSource(..),+ ( Query(..), Result(..), PackageSource(..), PackageName, resultVersionsFromList, ResultVersions, ErrorMsg )@@ -42,8 +42,9 @@ fmap concat $ mapM (processQueriesIn bp_man) $ commSources comm logger = commLogger comm processQueriesIn bp_man source = do+ queried_names <- fmap (nub . concat) $ mapM getQueriedPackageNames $ commQueries comm logDebug logger ("Retrieve package source " ++ show source)- e_build_plan <- loadBuildPlan bp_man source+ e_build_plan <- loadBuildPlan bp_man queried_names 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@@ -57,3 +58,6 @@ searchVersions :: BuildPlan -> Query -> ResultVersions searchVersions build_plan (QueryName package_name) = resultVersionsFromList [(package_name, packageVersion build_plan package_name)]++getQueriedPackageNames :: Query -> IO [PackageName]+getQueriedPackageNames (QueryName n) = return [n]
src/Staversion/Internal/Query.hs view
@@ -28,6 +28,7 @@ -- | Source of packages. data PackageSource = SourceStackage Resolver -- ^ stackage.+ | SourceHackage -- ^ hackage (latest) deriving (Show,Eq,Ord) -- | Query for package version(s).@@ -56,3 +57,4 @@ -- | description of a 'PackageSource'. sourceDesc :: PackageSource -> Text sourceDesc (SourceStackage r) = pack r+sourceDesc SourceHackage = "latest in hackage"
staversion.cabal view
@@ -1,5 +1,5 @@ name: staversion-version: 0.1.1.0+version: 0.1.2.0 author: Toshio Ito <debug.ito@gmail.com> maintainer: Toshio Ito <debug.ito@gmail.com> license: BSD3@@ -15,7 +15,8 @@ test/data/lts-7.0_conpact.yaml, test/data/lts-4.2.yaml, test/data/lts-2.22_conpact.yaml,- test/data/snapshots.json+ test/data/snapshots.json,+ test/data/aeson_preferred.json homepage: https://github.com/debug-ito/staversion bug-reports: https://github.com/debug-ito/staversion/issues@@ -25,9 +26,11 @@ hs-source-dirs: src ghc-options: -Wall -fno-warn-unused-imports default-extensions: OverloadedStrings- other-extensions: CPP, DeriveDataTypeable+ other-extensions: CPP, DeriveDataTypeable, GeneralizedNewtypeDeriving exposed-modules: Staversion.Internal.BuildPlan, Staversion.Internal.BuildPlan.Stackage,+ Staversion.Internal.BuildPlan.Hackage,+ Staversion.Internal.BuildPlan.Version, Staversion.Internal.Query, Staversion.Internal.Command, Staversion.Internal.Log,@@ -71,6 +74,8 @@ -- other-extensions: other-modules: Staversion.Internal.BuildPlanSpec, Staversion.Internal.BuildPlan.StackageSpec,+ Staversion.Internal.BuildPlan.HackageSpec,+ Staversion.Internal.BuildPlan.VersionSpec, Staversion.Internal.ExecSpec, Staversion.Internal.FormatSpec, Staversion.Internal.TestUtil
test/NetworkTest.hs view
@@ -1,5 +1,6 @@ module Main (main,spec) where +import Control.Applicative ((<$>)) import qualified Data.ByteString.Lazy as BSL import Network.HTTP.Client (newManager, Manager) import Network.HTTP.Client.TLS (tlsManagerSettings)@@ -13,13 +14,19 @@ loadBuildPlan, packageVersion )+import Staversion.Internal.BuildPlan.Hackage (fetchPreferredVersions, latestVersion) import Staversion.Internal.BuildPlan.Stackage ( fetchDisambiguator, fetchBuildPlanYAML, PartialResolver(..), ExactResolver(..) )+import Staversion.Internal.Command (Command(..))+import Staversion.Internal.Exec (processCommand) import Staversion.Internal.Log (defaultLogger, Logger(loggerThreshold))-import Staversion.Internal.Query (PackageSource(..))+import Staversion.Internal.Query+ ( PackageSource(..), ErrorMsg, Query(..), Result(..),+ resultVersionsToList+ ) main :: IO () main = hspec spec@@ -28,6 +35,8 @@ spec = do spec_Stackage spec_BuildPlan+ spec_Hackage+ spec_Exec spec_Stackage:: Spec spec_Stackage = describe "BuildPlan.Stackage" $ beforeAll makeManager $ do@@ -48,15 +57,56 @@ makeManager :: IO Manager makeManager = newManager tlsManagerSettings +quietLogger :: Logger+quietLogger = defaultLogger { loggerThreshold = Nothing }++expectRight :: String -> Either ErrorMsg a -> IO a+expectRight msg_head = either (\err -> error $ msg_head ++ err) return++isJustAnd :: Maybe a -> (a -> Bool) -> Bool+isJustAnd m p = maybe False p m+ spec_BuildPlan :: Spec spec_BuildPlan = describe "BuildPlan" $ do describe "loadBuildPlan from Stackage" $ do it "disambiguates LTS version and fetches a valid BuildPlan" $ do- let logger = defaultLogger { loggerThreshold = Nothing }- bp_man <- newBuildPlanManager "." logger True- bp <- loadBuildPlan bp_man (SourceStackage "lts-5") >>= \ret -> case ret of- Right bp -> return bp- Left error_msg -> error ("loadBuildPlan failed: " ++ error_msg)+ bp_man <- newBuildPlanManager "." quietLogger True+ bp <- expectRight "loadBuildPlan failed: " =<< loadBuildPlan bp_man [] (SourceStackage "lts-5") packageVersion bp "base" `shouldBe` Just (ver [4,8,2,0]) packageVersion bp "bytestring" `shouldBe` Just (ver [0,10,6,0]) packageVersion bp "conduit" `shouldBe` Just (ver [1,2,6,6])+ describe "loadBuildPlan from Hackage" $ do+ it "fetches BuildPlan for queried packages" $ do+ bp_man <- newBuildPlanManager "." quietLogger True+ bp <- expectRight "loadBuildPlan failed: " =<< loadBuildPlan bp_man ["base", "lens", "transformers"] SourceHackage+ packageVersion bp "base" `shouldSatisfy` (`isJustAnd` (>= ver [4,9,0,0]))+ packageVersion bp "lens" `shouldSatisfy` (`isJustAnd` (>= ver [4,15,1]))+ packageVersion bp "transformers" `shouldSatisfy` (`isJustAnd` (>= ver [0,5,2,0]))++spec_Hackage :: Spec+spec_Hackage = describe "BuildPlan.Hackage" $ do+ describe "fetchPreferredVersions" $ do+ it "fetches a non-empty latestVersion" $ do+ man <- makeManager+ ret <- fmap latestVersion <$> fetchPreferredVersions man "http-client"+ case ret of+ Right (Just v) -> v `shouldSatisfy` (>= ver [0,5,3,3])+ _ -> expectationFailure ("Unexpected return: " ++ show ret)++spec_Exec :: Spec+spec_Exec = describe "Exec" $ describe "processCommand" $ do+ specify "search hackage" $ do+ let comm = Command { commBuildPlanDir = ".",+ commLogger = quietLogger,+ commSources = [SourceHackage],+ commQueries = [QueryName "base"],+ commAllowNetwork = True+ }+ [ret] <- processCommand comm+ resultIn ret `shouldBe` SourceHackage+ resultFor ret `shouldBe` QueryName "base"+ [(got_name, Just got_version)] <- resultVersionsToList <$> expectRight "processCommand error" (resultVersions ret)+ got_name `shouldBe` "base"+ got_version `shouldSatisfy` (>= ver [4,9,0,0]) + +
+ test/Staversion/Internal/BuildPlan/HackageSpec.hs view
@@ -0,0 +1,22 @@+module Staversion.Internal.BuildPlan.HackageSpec (main,spec) where++import qualified Data.ByteString.Lazy as BSL+import System.FilePath ((</>))+import Test.Hspec++import Staversion.Internal.TestUtil (ver)++import Staversion.Internal.BuildPlan.Hackage+ ( parsePreferredVersionsJSON,+ latestVersion+ )++main :: IO ()+main = hspec spec++spec :: Spec+spec = describe "parsePreferredVersionsJSON" $ do+ it "should parse aeson_preferred.json" $ do+ yaml_data <- BSL.readFile ("test" </> "data" </> "aeson_preferred.json")+ rvers <- either (\e -> error ("parse error: " ++ e)) return $ parsePreferredVersionsJSON yaml_data+ latestVersion rvers `shouldBe` Just (ver [1,0,2,1])
+ test/Staversion/Internal/BuildPlan/VersionSpec.hs view
@@ -0,0 +1,21 @@+module Staversion.Internal.BuildPlan.VersionSpec (main,spec) where++import Data.Text (pack)+import Data.Version (Version(..))+import Test.Hspec++import Staversion.Internal.BuildPlan.Version (parseVersionText)++main :: IO ()+main = hspec spec++spec :: Spec+spec = parseVersionText_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
test/Staversion/Internal/BuildPlanSpec.hs view
@@ -11,7 +11,6 @@ ( BuildPlan, loadBuildPlanYAML, packageVersion,- parseVersionText, BuildPlanManager, newBuildPlanManager, _setDisambiguator,@@ -27,18 +26,9 @@ spec :: Spec spec = do- parseVersionText_spec packageVersion_spec loadBuildPlan_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@@ -83,5 +73,5 @@ let disam (PartialLTSLatest) = Just $ ExactLTS 4 2 disam _ = Nothing bp_man <- mockBuildPlanManager disam- bp <- either (\e -> error ("Error: " ++ e)) return =<< loadBuildPlan bp_man (SourceStackage "lts")+ bp <- either (\e -> error ("Error: " ++ e)) return =<< loadBuildPlan bp_man [] (SourceStackage "lts") packageVersion bp "base" `shouldBe` (Just $ Version [4,8,2,0] [])
+ test/data/aeson_preferred.json view
@@ -0,0 +1,1 @@+{"normal-version":["1.0.2.1","1.0.2.0","1.0.1.0","1.0.0.0","0.11.2.1","0.11.2.0","0.11.1.4","0.11.1.3","0.11.1.2","0.11.1.1","0.11.1.0","0.11.0.0","0.9.0.1","0.9.0.0","0.8.1.1","0.8.1.0","0.8.0.2","0.7.0.6","0.7.0.4","0.6.2.1","0.6.2.0","0.6.1.0","0.6.0.2","0.6.0.1","0.6.0.0","0.5.0.0","0.4.0.1","0.4.0.0","0.3.2.14","0.3.2.13","0.3.2.12","0.3.2.11","0.3.2.10","0.3.2.9","0.3.2.8","0.3.2.7","0.3.2.6","0.3.2.5","0.3.2.4","0.3.2.3","0.3.2.2","0.3.2.1","0.3.2.0","0.3.1.1","0.3.1.0","0.3.0.0","0.2.0.0","0.1.0.0"],"deprecated-version":["0.10.0.0","0.8.0.1","0.8.0.0","0.7.0.5","0.7.0.3","0.7.0.2","0.7.0.1","0.7.0.0"]}