cabal-rpm-1.0.3: src/Stackage.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
-- |
-- Module : Stackage
-- Copyright : (C) 2017-2019 Jens Petersen
--
-- Maintainer : Jens Petersen <petersen@fedoraproject.org>
-- Stability : alpha
-- Portability : portable
--
-- Explanation: queries Stackage package versions
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
module Stackage (
latestStackage
) where
#ifdef HTTPS
import qualified Data.ByteString.Char8 as B
import Data.List (isPrefixOf)
import Data.Maybe (mapMaybe)
import Network.HTTP.Client
import Network.HTTP.Client.TLS
import System.FilePath (takeFileName)
import SimpleCmd ((+-+), removePrefix)
#else
#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
#else
import Control.Applicative ((<$>))
#endif
import SimpleCmd ((+-+), cmdMaybe)
import SysCmd (optionalProgram)
#endif
import Distribution.Text (display)
import SimpleCabal (PackageIdentifier(..), PackageName)
import Types
stackageList :: Stream -> PackageName -> IO (Maybe PackageIdentifier)
stackageList stream pkg = do
#ifdef HTTPS
mgr <- newManager tlsManagerSettings
let pkgurl = topurl ++ (show stream) ++ "/package/"
req <- parseRequest $ pkgurl ++ display pkg
hist <- responseOpenHistory req mgr
let redirs = mapMaybe (lookup "Location" . responseHeaders . snd) $ hrRedirects hist
if null redirs
then return Nothing
else do
let loc = B.unpack $ last redirs
if topurl `isPrefixOf` loc
then
let ver = (readVersion . removePrefix (display pkg ++ "-") . takeFileName) loc
in return $ Just (PackageIdentifier pkg ver)
else return Nothing
where
topurl :: String
topurl = "https://www.stackage.org/"
#else
-- check for stackage-query
haveStackage <- optionalProgram "stackage"
if haveStackage
then do
mver <- cmdMaybe "stackage" ["package", show stream, display pkg]
return $ PackageIdentifier pkg . readVersion <$> mver
else do
putStrLn "'cabal install stackage-query' to check against Stackage LTS"
return Nothing
#endif
latestStackage :: Stream -> PackageName -> IO (Maybe PackageIdentifier)
latestStackage stream pkg = do
mpkgid <- stackageList stream pkg
case mpkgid of
Nothing -> return ()
Just pkgid -> putStrLn $ display pkgid +-+ "in Stackage" +-+ show stream
return mpkgid