hkgr-0.1: Main.hs
{-# LANGUAGE CPP #-}
module Main (main) where
#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0))
#else
import Control.Applicative (pure, (<$>))
#endif
import Control.Exception (bracket_)
import Control.Monad
#if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,11,0))
#else
import Data.Semigroup ((<>))
#endif
import SimpleCabal
import SimpleCmd
import SimpleCmd.Git
import SimpleCmdArgs
import System.Directory
import System.FilePath
import Paths_hkgr (version)
main :: IO ()
main =
simpleCmdArgs (Just version) "HacKaGe Release workflow"
"A tool to help Hackage maintainers with releasing packages" $
subcommands
[ Subcommand "tag" "'git tag' version" $
gitTagCmd <$> forceOpt "Move existing tag"
, Subcommand "dist" "Make tarball from latest tag ('cabal sdist')" $
sdistCmd <$> forceOpt "Overwrite existing dist tarball"
, Subcommand "version" "Show the package version from .cabal file" $
pure showVersionCmd
, Subcommand "upload" "'cabal upload' tarball to Hackage" $ pure $ uploadCmd False
, Subcommand "publish" "Publish to Hackage ('cabal upload --publish')" $
pure $ uploadCmd True
, Subcommand "upload-haddock" "Upload documentation to Hackage" $ pure $ upHaddockCmd False
, Subcommand "publish-haddock" "Upload documentation to Hackage" $ pure $ upHaddockCmd True
, Subcommand "push-tags" "'git push --tags' to origin" $ pure pushCmd
]
where
forceOpt = switchWith 'f' "force"
gitTagCmd :: Bool -> IO ()
gitTagCmd force = do
pkgid <- getPackageId
checkNotPublished pkgid
let tag = packageVersion pkgid
git_ "tag" $ ["--force" | force] ++ [tag]
unless force $ putStrLn tag
checkNotPublished :: PackageIdentifier -> IO ()
checkNotPublished pkgid = do
let published = "dist" </> showPkgId pkgid <.> ".tar.gz" <.> "published"
exists <- doesFileExist published
when exists $ error' $ showPkgId pkgid <> " was already published!!"
sdistCmd :: Bool -> IO ()
sdistCmd force = do
pkgid <- getPackageId
let ver = packageVersion pkgid
let target = "dist" </> showPkgId pkgid <.> ".tar.gz"
checkNotPublished pkgid
haveTarget <- doesFileExist target
if haveTarget
then if force
then removeFile target
else error' $ target <> " exists already!"
else when force $ error' "Target does not exist, please use 'dist' command"
haveTag <- pipeBool ("git", ["tag"]) ("grep",["-q",ver])
unless haveTag $ gitTagCmd False
cwd <- getCurrentDirectory
withTempDirectory "tmp-sdist" $ do
git_ "clone" ["-q", "--no-checkout", "..", "."]
git_ "checkout" ["-q", ver]
cabal_ "check" []
cabal_ "configure" []
-- cabal_ "build" []
cmd_ "hlint" ["."]
cabal_ "sdist" []
renameFile target (cwd </> target)
showVersionCmd :: IO ()
showVersionCmd = do
pkgid <- getPackageId
putStrLn $ packageVersion pkgid
uploadCmd :: Bool -> IO ()
uploadCmd publish = do
pkgid <- getPackageId
checkNotPublished pkgid
let file = "dist" </> showPkgId pkgid <.> ".tar.gz"
cabal_ "upload" $ ["--publish" | publish] ++ [file]
when publish $ do
let tag = packageVersion pkgid
git_ "push" ["origin", tag]
createFileLink file (takeFileName file <.> "published")
pushCmd :: IO ()
pushCmd =
git_ "push" ["--tags"]
upHaddockCmd :: Bool -> IO ()
upHaddockCmd publish =
cabal_ "upload" $ "--documentation" : ["--publish" | publish]
cabal_ :: String -> [String] -> IO ()
cabal_ c args =
cmd_ "cabal" (c:args)
withTempDirectory :: FilePath -> IO a -> IO a
withTempDirectory dir run =
bracket_ (createDirectory dir) (removeDirectoryRecursive dir) $
withCurrentDirectory dir run