cabal-rpm 0.11.2 → 0.12
raw patch · 9 files changed
+276/−78 lines, 9 filesdep +bytestringdep +http-clientdep +http-client-tlsdep ~Cabaldep ~time
Dependencies added: bytestring, http-client, http-client-tls, http-conduit
Dependency ranges changed: Cabal, time
Files
- ChangeLog +10/−0
- cabal-rpm.cabal +17/−6
- src/Commands/Refresh.hs +5/−4
- src/Commands/Spec.hs +40/−15
- src/Commands/Update.hs +1/−1
- src/Dependencies.hs +40/−4
- src/Options.hs +19/−3
- src/PackageUtils.hs +70/−45
- src/Stackage.hs +74/−0
ChangeLog view
@@ -1,3 +1,13 @@+* 0.12 (2017-11-17)+- default to querying stackage.org directly via https+- fix stackage-query usage and suggest installing if missing+- run cabal update before cabal commands+- devel packages now provide doc subpackage for forward compatibility+- new --hackage option to get package version from Hackage not Stackage+- do not add .cabal files containing "doc" to docs+- silence mock rpmbuild -bs warnings about undefined %ghc_version+- allow building with ghc-8.2 and Cabal-2.0+ * 0.11.2 (2017-07-31) - fix cblrpm update --subpackage - fix rpm installation when no sudo (#49)
cabal-rpm.cabal view
@@ -1,5 +1,5 @@ Name: cabal-rpm-Version: 0.11.2+Version: 0.12 Synopsis: RPM packaging tool for Haskell Cabal-based packages Description: This package provides a RPM packaging tool for Haskell Cabal-based packages.@@ -9,8 +9,8 @@ and install them. There are commands to list package dependencies and missing dependencies. The diff command compares the current spec file with a freshly generated one, the update command updates the spec file- to latest version from Hackage, and the refresh command updates the- spec file to the current cabal-rpm packaging.+ to latest version from Stackage or Hackage, and the refresh command updates+ the spec file to the current cabal-rpm packaging. Homepage: https://github.com/juhp/cabal-rpm Bug-reports: https://github.com/juhp/cabal-rpm/issues License: GPL-3@@ -23,7 +23,7 @@ Build-type: Simple Extra-source-files: README.md ChangeLog man/cabal-rpm.1.md man/cabal-rpm.1 Cabal-version: >=1.6-Tested-with: GHC == 7.0.4, GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4,+Tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2 source-repository head@@ -32,12 +32,16 @@ Flag old-locale Description: Use old-locale and time < 1.5+ Default: False++Flag https+ Description: Use http to query Stackage Default: True Executable cabal-rpm Main-is: Main.hs Build-depends: base < 5,- Cabal > 1.10 && < 1.25,+ Cabal > 1.10, directory, filepath, process,@@ -46,7 +50,13 @@ Build-Depends: old-locale >= 1 && < 1.1, time >= 1.2 && < 1.5 else- Build-Depends: time >= 1.5 && < 1.7+ Build-Depends: time >= 1.5 && < 1.9+ if flag(https)+ Build-Depends: bytestring,+ http-client,+ http-client-tls,+ http-conduit+ Cpp-options: -DHTTPS Other-modules: Commands.Depends, Commands.Diff,@@ -60,6 +70,7 @@ FileUtils, Options, PackageUtils,+ Stackage, SysCmd Hs-Source-Dirs: src GHC-options: -fwarn-missing-signatures -Wall
src/Commands/Refresh.hs view
@@ -19,7 +19,8 @@ import Commands.Spec (createSpecFile) import FileUtils (withTempDirectory) import Options (RpmFlags (..))-import PackageUtils (PackageData (..), isGitDir, patchSpec, removePrefix)+import PackageUtils (PackageData (..), cabal_, isGitDir, patchSpec,+ removePrefix) import SysCmd (cmd, cmd_, grep_, notNull, optionalProgram) #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2))@@ -83,10 +84,10 @@ haveExe <- doesFileExist $ bindir </> cblrpmver unless haveExe $ withTempDirectory $ \cwd -> do- cmd_ "cabal" ["unpack", cblrpmver]+ cabal_ "unpack" [cblrpmver] setCurrentDirectory cblrpmver- cmd_ "cabal" ["configure"]- cmd_ "cabal" ["build"]+ cabal_ "configure" []+ cabal_ "build" [] createDirectoryIfMissing True bindir let bin = "dist/build/cabal-rpm/cabal-rpm" cmd_ "strip" [bin]
src/Commands/Spec.hs view
@@ -40,15 +40,27 @@ import Data.Maybe (fromMaybe, fromJust) import Data.Time.Clock (getCurrentTime) import Data.Time.Format (formatTime)-import Data.Version (showVersion)+import qualified Data.Version (showVersion) import Distribution.License (License (..)) +import Distribution.PackageDescription (BuildInfo (..), PackageDescription (..),+ Executable (..),+ Library (..), exeName, hasExes, hasLibs,+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)+ unFlagName+#else+ FlagName (..)+#endif+ ) import Distribution.Simple.Utils (notice, warn) -import Distribution.PackageDescription (BuildInfo (..), PackageDescription (..),- Executable (..), FlagName (..),- Library (..), exeName, hasExes, hasLibs)+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)+import Distribution.Types.UnqualComponentName (unUnqualComponentName)+import Distribution.Version (showVersion)+#else+import Data.Version (showVersion)+#endif --import Distribution.Version (VersionRange, foldVersionRange') @@ -77,6 +89,15 @@ rstrip :: (Char -> Bool) -> String -> String rstrip p = reverse . dropWhile p . reverse +#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)+#else+unFlagName :: FlagName -> String+unFlagName (FlagName n) = n++unUnqualComponentName :: String -> String+unUnqualComponentName = id+#endif+ createSpecFile :: PackageData -> RpmFlags -> Maybe FilePath -> IO FilePath createSpecFile pkgdata flags mdest = do@@ -120,7 +141,7 @@ ghcPkg = if binlib then "-n ghc-%{name}" else "" ghcPkgDevel = if binlib then "-n ghc-%{name}-devel" else "devel" - put $ "# generated by cabal-rpm-" ++ showVersion Paths_cabal_rpm.version+ put $ "# generated by cabal-rpm-" ++ Data.Version.showVersion Paths_cabal_rpm.version distro <- fromMaybe detectDistro (return <$> rpmDistribution flags) if distro /= SUSE then put "# https://fedoraproject.org/wiki/Packaging:Haskell"@@ -181,7 +202,7 @@ -- FIXME recursive missingdeps missing <- if rpmSubpackage flags then subPackages (if specAlreadyExists then mspec else Nothing) pkgDesc else return [] subpkgs <-- mapM ((getsubpkgMacro >=>+ mapM ((getsubpkgMacro flags >=> \(m,pv) -> put ("%global" +-+ m +-+ pv) >> return ("%{" ++ m ++ "}")) . stripPkgDevel) missing let hasSubpkgs = notNull subpkgs@@ -278,9 +299,13 @@ _ -> return () unless (distro == SUSE) $ putHdr "Provides" $ (if binlib then "ghc-%{name}" else "%{name}") ++ "-static = %{version}-%{release}"+ when exposesModules $+ putHdr "Provides" $ (if binlib then "ghc-%{name}" else "%{name}") ++ "-doc" +-+ "= %{version}-%{release}"+ put "%if %{defined ghc_version}" putHdr "Requires" "ghc-compiler = %{ghc_version}" putHdr "Requires(post)" "ghc-compiler = %{ghc_version}" putHdr "Requires(postun)" "ghc-compiler = %{ghc_version}"+ put "%endif" when exposesModules $ putHdr "Requires" $ (if binlib then "ghc-%{name}" else "%{name}") ++ isa +-+ "= %{version}-%{release}" unless (null $ clibs ++ pkgcfgs) $ do@@ -314,7 +339,7 @@ when hasSubpkgs $ put "%ghc_libs_build %{subpkgs}" when (distro == SUSE && rpmConfigurationsFlags flags /= []) $ do- let cabalFlags = [ "-f" ++ (if b then "" else "-") ++ n | (FlagName n, b) <- rpmConfigurationsFlags flags ]+ let cabalFlags = [ "-f" ++ (if b then "" else "-") ++ unFlagName n | (n, b) <- rpmConfigurationsFlags flags ] put $ "%define cabal_configure_options " ++ unwords cabalFlags let pkgType = if hasLib then "lib" else "bin" if hasLib && not exposesModules@@ -384,7 +409,7 @@ mapM_ (\ l -> put $ license_macro +-+ l) licensefiles unless (null docs) $ put $ "%doc" +-+ unwords docs- mapM_ (\ p -> put $ "%{_bindir}" </> (if p == name then "%{name}" else p)) execs+ mapM_ ((\ p -> put $ "%{_bindir}" </> (if p == name then "%{name}" else p)) . unUnqualComponentName) execs when (notNull datafiles' && not selfdep) $ put $ "%{_datadir}" </> pkgver @@ -398,7 +423,7 @@ when (distro /= Fedora) $ put "%defattr(-,root,root,-)" mapM_ (\ l -> put $ license_macro +-+ l) licensefiles when (distro == SUSE && not binlib) $- mapM_ (\ p -> put $ "%{_bindir}" </> (if p == name then "%{pkg_name}" else p)) execs+ mapM_ ((\ p -> put $ "%{_bindir}" </> (if p == name then "%{pkg_name}" else p)) . unUnqualComponentName) execs when (notNull datafiles' && (selfdep || not binlib)) $ put $ "%{_datadir}" </> pkgver sectionNewline@@ -409,7 +434,7 @@ unless (null docs) $ put $ "%doc" +-+ unwords docs when (distro /= SUSE && not binlib) $- mapM_ (\ p -> put $ "%{_bindir}" </> (if p == name then "%{pkg_name}" else p)) execs+ mapM_ ((\ p -> put $ "%{_bindir}" </> (if p == name then "%{pkg_name}" else p)) . unUnqualComponentName) execs sectionNewline put "%changelog"@@ -417,7 +442,7 @@ now <- getCurrentTime let date = formatTime defaultTimeLocale "%a %b %e %Y" now put $ "*" +-+ date +-+ "Fedora Haskell SIG <haskell@lists.fedoraproject.org> - " ++ version ++ "-" ++ release- put $ "- spec file generated by cabal-rpm-" ++ showVersion Paths_cabal_rpm.version+ put $ "- spec file generated by cabal-rpm-" ++ Data.Version.showVersion Paths_cabal_rpm.version hClose h return specFile' @@ -440,7 +465,7 @@ "example", "licence", "license", "news", "readme", "todo"] likely name = let lowerName = map toLower name in any (`isPrefixOf` lowerName) names- unlikely name = not $ any (`isSuffixOf` name) ["~"]+ unlikely name = not $ any (`isSuffixOf` name) ["~", ".cabal"] showLicense :: Distro -> License -> String showLicense SUSE (GPL Nothing) = "GPL-1.0+"@@ -509,10 +534,10 @@ paragraphs :: [String] -> [String] paragraphs = map (unlines . filter notNull) . groupBy (const notNull) -getsubpkgMacro :: String -> IO (String, String)-getsubpkgMacro pkg = do+getsubpkgMacro :: RpmFlags -> String -> IO (String, String)+getsubpkgMacro flags pkg = do let name = filter (/= '-') pkg- pkgver <- latestPackage pkg+ pkgver <- latestPackage (rpmHackage flags) pkg let (n,v) = nameVersion pkgver copyTarball n v False "." return (name, pkgver)
src/Commands/Update.hs view
@@ -46,7 +46,7 @@ current = name ++ "-" ++ ver latest <- case mpkgver of Just pv -> return pv- Nothing -> latestPackage name+ Nothing -> latestPackage (rpmHackage flags) name if current == latest then putStrLn $ current +-+ "is already latest version." else do
src/Dependencies.hs view
@@ -37,7 +37,23 @@ import Data.List (delete, isSuffixOf, nub) import Data.Maybe (catMaybes, isNothing) -import Distribution.Package (Dependency (..), PackageName (..))+import Distribution.Package (Dependency (..),+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)+ unPackageName,+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)+ unPkgconfigName+#endif+#else+ PackageName (..)+#endif+ )++#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)+import Distribution.Types.LegacyExeDependency (LegacyExeDependency (..))+import Distribution.Types.PkgconfigDependency (PkgconfigDependency (..))+#else+#endif+ import Distribution.PackageDescription (PackageDescription (..), allBuildInfo, BuildInfo (..),@@ -63,9 +79,29 @@ in (filter excludedPkgs (delete self deps), self `elem` deps && hasExes pkgDesc) +#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)+#else+unPackageName :: PackageName -> String+unPackageName (PackageName n) = n+#endif+ depName :: Dependency -> String-depName (Dependency (PackageName n) _) = n+depName (Dependency n _) = unPackageName n +#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)+exeDepName :: LegacyExeDependency -> String+exeDepName (LegacyExeDependency n _) = n++pkgcfgDepName :: PkgconfigDependency -> String+pkgcfgDepName (PkgconfigDependency n _) = unPkgconfigName n+#else+exeDepName :: Dependency -> String+exeDepName = depName++pkgcfgDepName :: Dependency -> String+pkgcfgDepName = depName+#endif+ showDep :: String -> String showDep p = "ghc-" ++ p ++ "-devel" @@ -76,8 +112,8 @@ let self = packageName $ package pkgDesc (deps, selfdep) = buildDependencies pkgDesc self buildinfo = allBuildInfo pkgDesc- tools = nub $ map depName (concatMap buildTools buildinfo)- pkgcfgs = nub $ map depName $ concatMap pkgconfigDepends buildinfo+ tools = nub $ map exeDepName (concatMap buildTools buildinfo)+ pkgcfgs = nub $ map pkgcfgDepName $ concatMap pkgconfigDepends buildinfo clibs = concatMap extraLibs buildinfo return (deps, tools, nub clibs, pkgcfgs, selfdep)
src/Options.hs view
@@ -28,7 +28,13 @@ import Distribution.Compiler (CompilerId) import Distribution.Text (simpleParse)-import Distribution.PackageDescription (FlagName (..))+import Distribution.PackageDescription (+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)+ FlagName, mkFlagName+#else+ FlagName (..)+#endif+ ) import Distribution.ReadE (readEOrFail) import Distribution.Verbosity (Verbosity, flagToVerbosity, normal, silent)@@ -50,6 +56,7 @@ , rpmBinary :: Bool , rpmStrict :: Bool , rpmSubpackage :: Bool+ , rpmHackage :: Bool , rpmRelease :: Maybe String , rpmCompilerId :: Maybe CompilerId , rpmDistribution :: Maybe Distro@@ -66,6 +73,7 @@ , rpmBinary = False , rpmStrict = False , rpmSubpackage = False+ , rpmHackage = False , rpmRelease = Nothing , rpmCompilerId = Nothing , rpmDistribution = Nothing@@ -84,6 +92,8 @@ "Force Haskell package name to be base package name" , Option "" ["force"] (NoArg (\x -> x { rpmForce = True })) "Overwrite existing spec file."+ , Option "" ["hackage"] (NoArg (\x -> x { rpmHackage = True }))+ "Use Hackage to get package version instead of Stackage." , Option "" ["strict"] (NoArg (\x -> x { rpmStrict = True })) "Fail rather than produce an incomplete spec file." , Option "" ["subpackage"] (NoArg (\x -> x { rpmSubpackage = True }))@@ -102,11 +112,17 @@ "Change build verbosity" ] +#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)+#else+mkFlagName :: String -> FlagName+mkFlagName = FlagName+#endif+ -- Lifted from Distribution.Simple.Setup, since it's not exported. flagList :: String -> [(FlagName, Bool)] flagList = map tagWithValue . words- where tagWithValue ('-':name) = (FlagName (map toLower name), False)- tagWithValue name = (FlagName (map toLower name), True)+ where tagWithValue ('-':name) = (mkFlagName (map toLower name), False)+ tagWithValue name = (mkFlagName (map toLower name), True) printHelp :: Handle -> IO () printHelp h = do
src/PackageUtils.hs view
@@ -15,6 +15,7 @@ module PackageUtils ( bringTarball,+ cabal_, copyTarball, getPkgName, isGitDir,@@ -40,9 +41,11 @@ import FileUtils (filesWithExtension, fileWithExtension, getDirectoryContents_, mktempdir) import Options (RpmFlags (..))-import SysCmd (cmd, cmd_, cmdIgnoreErr, cmdMaybe, cmdSilent, (+-+),+import SysCmd (cmd, cmd_, cmdIgnoreErr, cmdSilent, (+-+), notNull, optionalProgram, requireProgram, sudo, trySystem) +import Stackage (latestStackage)+ #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,2)) #else import Control.Applicative ((<$>))@@ -51,12 +54,16 @@ import Data.Char (isDigit) import Data.List (isPrefixOf, stripPrefix, (\\))-import Data.Maybe (fromMaybe, isJust, fromJust)-import Data.Version (showVersion)+import Data.Maybe (fromMaybe, isJust) import Distribution.Compiler import Distribution.Package (PackageIdentifier (..),- PackageName (..))+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)+ unPackageName+#else+ PackageName (..)+#endif+ ) import Distribution.PackageDescription (PackageDescription (..), hasExes, hasLibs) import Distribution.PackageDescription.Configuration (finalizePackageDescription)@@ -86,6 +93,11 @@ ) import Distribution.System (Platform (..), buildArch, buildOS)+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2,0,0)+import Distribution.Version (showVersion)+#else+import Data.Version (showVersion)+#endif import System.Directory (copyFile, createDirectoryIfMissing,doesDirectoryExist, doesFileExist, getCurrentDirectory,@@ -156,14 +168,14 @@ when (specTime > dirTime) $ do bringTarball namever rpmbuild Prep True Nothing specFile- cabal <- tryFindPackageDesc namever- return (cabal, Nothing)+ cabalfile <- tryFindPackageDesc namever+ return (cabalfile, Nothing) else do tmpdir <- mktempdir bringTarball namever rpmbuild Prep True (Just tmpdir) specFile- cabal <- tryFindPackageDesc $ tmpdir </> namever- return (cabal, Just tmpdir)+ cabalfile <- tryFindPackageDesc $ tmpdir </> namever+ return (cabalfile, Just tmpdir) bringTarball :: FilePath -> IO () bringTarball nv = do@@ -220,9 +232,26 @@ stripPkgDevel :: String -> String stripPkgDevel = removeSuffix "-devel" . removePrefix "ghc-" +cabalUpdate :: IO ()+cabalUpdate = do+ home <- getEnv "HOME"+ let cacheparent = home </> ".cabal" </> "packages"+ pkgsdir <- doesDirectoryExist cacheparent+ unless pkgsdir $+ cmd_ "cabal" ["update"]++cabal :: String -> [String] -> IO [String]+cabal c args = do+ cabalUpdate+ lines <$> cmd "cabal" (c:args)++cabal_ :: String -> [String] -> IO ()+cabal_ c args = do+ cabalUpdate+ cmd_ "cabal" (c:args)+ tryUnpack :: String -> IO (FilePath, Maybe FilePath)-tryUnpack pkg = do- pkgver <- if stripVersion pkg == pkg then latestPackage pkg else return pkg+tryUnpack pkgver = do isdir <- doesDirectoryExist pkgver if isdir then do@@ -232,21 +261,24 @@ cwd <- getCurrentDirectory tmpdir <- mktempdir setCurrentDirectory tmpdir- cmd_ "cabal" ["unpack", "-v0", pkgver]+ cabal_ "unpack" ["-v0", pkgver] pth <- tryFindPackageDesc pkgver setCurrentDirectory cwd return (tmpdir </> pth, Just tmpdir) -latestPackage :: String -> IO String-latestPackage pkg = do- stk <- latestStackage pkg- case stk of- Just pv -> return pv- Nothing -> latestHackage pkg+latestPackage :: Bool -> String -> IO String+latestPackage hackage pkg =+ if hackage+ then latestHackage pkg+ else do+ stk <- latestStackage pkg+ case stk of+ Just pv -> return pv+ Nothing -> latestHackage pkg latestHackage :: String -> IO String latestHackage pkg = do- contains_pkg <- lines <$> cmd "cabal" ["list", "-v0", pkg]+ contains_pkg <- cabal "list" ["-v0", pkg] let top = dropWhile (/= "*" +-+ pkg) contains_pkg if null top then error $ pkg +-+ "hackage not found"@@ -260,22 +292,14 @@ putStrLn $ res +-+ "in Hackage" return res -latestStackage :: String -> IO (Maybe String)-latestStackage pkg = do- -- check for stackage-query- haveStackage <- optionalProgram "stackage"- if haveStackage- then do- let stream = "lts"- mpkg <- cmdMaybe "stackage" ["list", stream, pkg]- when (isJust mpkg) $- putStrLn $ fromJust mpkg +-+ "in Stackage" +-+ stream- return mpkg- else return Nothing+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(1,22,0)+#else+unPackageName :: PackageName -> String+unPackageName (PackageName n) = n+#endif packageName :: PackageIdentifier -> String-packageName pkg = name- where PackageName name = pkgName pkg+packageName = unPackageName . pkgName packageVersion :: PackageIdentifier -> String packageVersion = showVersion . pkgVersion@@ -350,12 +374,10 @@ dest = dir </> tarfile already <- doesFileExist dest unless already $ do+ cabalUpdate home <- getEnv "HOME" let cacheparent = home </> ".cabal" </> "packages" tarpath = n </> v </> tarfile- pkgsdir <- doesDirectoryExist cacheparent- unless pkgsdir $- error $ "Run 'cabal update' to create" +-+ cacheparent remotes <- getDirectoryContents_ cacheparent let paths = map (\ repo -> cacheparent </> repo </> tarpath) remotes -- if more than one tarball, should maybe warn if they are different@@ -364,7 +386,7 @@ then if ranFetch then error $ "No" +-+ tarfile +-+ "found" else do- cmd_ "cabal" ["fetch", "-v0", "--no-dependencies", n ++ "-" ++ v]+ cabal_ "fetch" ["-v0", "--no-dependencies", n ++ "-" ++ v] copyTarball n v True dir else do createDirectoryIfMissing True dir@@ -389,9 +411,9 @@ mspec <- checkForSpecFile mpkg case mspec of Just spec -> do- (cabal, mtmp) <- cabalFromSpec spec- pkgDesc <- simplePackageDescription cabal flags- return $ PackageData mspec cabal pkgDesc mtmp+ (cabalfile, mtmp) <- cabalFromSpec spec+ pkgDesc <- simplePackageDescription cabalfile flags+ return $ PackageData mspec cabalfile pkgDesc mtmp Nothing -> case mpkgver of Nothing -> do@@ -400,13 +422,16 @@ Just pkgmver -> do mcabal <- checkForCabalFile pkgmver case mcabal of- Just cabal -> do- pkgDesc <- simplePackageDescription cabal flags- return $ PackageData Nothing cabal pkgDesc Nothing+ Just cabalfile -> do+ pkgDesc <- simplePackageDescription cabalfile flags+ return $ PackageData Nothing cabalfile pkgDesc Nothing Nothing -> do- (cabal, mtmp) <- tryUnpack pkgmver- pkgDesc <- simplePackageDescription cabal flags- return $ PackageData Nothing cabal pkgDesc mtmp+ pkgver <- if stripVersion pkgmver == pkgmver+ then latestPackage (rpmHackage flags) pkgmver+ else return pkgmver+ (cabalfile, mtmp) <- tryUnpack pkgver+ pkgDesc <- simplePackageDescription cabalfile flags+ return $ PackageData Nothing cabalfile pkgDesc mtmp patchSpec :: Maybe FilePath -> FilePath -> FilePath -> IO () patchSpec mdir oldspec newspec = do
+ src/Stackage.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module : Stackage+-- Copyright : (C) 2017 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+++import Control.Monad (when)+import Data.Maybe (isJust, fromJust)++#ifdef HTTPS+import qualified Data.ByteString.Char8 as B+import Data.List+import Data.Maybe+import Network.HTTP.Client+import Network.HTTP.Client.TLS+import System.FilePath+import SysCmd ((+-+))+#else+import SysCmd ((+-+), cmdMaybe, optionalProgram)+#endif++stackageList :: String -> String -> IO (Maybe String)+stackageList stream pkg = do+#ifdef HTTPS+ mgr <- newManager tlsManagerSettings+ let pkgurl = topurl ++ stream ++ "/package/"+ req <- parseRequest $ pkgurl ++ 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 return $ Just (takeFileName loc)+ else return Nothing+ where+ topurl :: String+ topurl = "https://www.stackage.org/"+#else+ -- check for stackage-query+ haveStackage <- optionalProgram "stackage"+ if haveStackage+ then+ fmap ((pkg ++ "-") ++) <$> cmdMaybe "stackage" ["package", stream, pkg]+ else do+ putStrLn "'cabal install stackage-query' to check against Stackage LTS"+ return Nothing+#endif++latestStackage :: String -> IO (Maybe String)+latestStackage pkg = do+ let stream = "lts"+ mpkg <- stackageList stream pkg+ when (isJust mpkg) $+ putStrLn $ fromJust mpkg +-+ "in Stackage" +-+ stream+ return mpkg+