Download and determine the digest
This commit is contained in:
@ -27,6 +27,7 @@ data SlackBuilderCommand
|
||||
| CommitCommand Text Text
|
||||
| ExistsCommand Text
|
||||
| ArchiveCommand Text Text String Text
|
||||
| DownloadCommand Text String
|
||||
deriving (Eq, Show)
|
||||
|
||||
data PackagistArguments = PackagistArguments
|
||||
@ -69,6 +70,7 @@ slackBuilderCommand = subparser
|
||||
<> command "commit" (info commitCommand mempty)
|
||||
<> command "exists" (info existsCommand mempty)
|
||||
<> command "archive" (info archiveCommand mempty)
|
||||
<> command "download" (info downloadCommand mempty)
|
||||
where
|
||||
slackBuildCommand = SlackBuildCommand
|
||||
<$> argument str (metavar "PATH")
|
||||
@ -82,3 +84,6 @@ slackBuilderCommand = subparser
|
||||
<*> argument str (metavar "NAME_VERSION")
|
||||
<*> argument str (metavar "TARBALL")
|
||||
<*> argument str (metavar "TAG_PREFIX")
|
||||
downloadCommand = DownloadCommand
|
||||
<$> argument str (metavar "URI")
|
||||
<*> argument str (metavar "TARGET")
|
||||
|
@ -1,11 +1,14 @@
|
||||
module SlackBuilder.Download
|
||||
( cloneAndArchive
|
||||
, commit
|
||||
, download
|
||||
, hostedSources
|
||||
, remoteFileExists
|
||||
, updateSlackBuildVersion
|
||||
) where
|
||||
|
||||
import Data.ByteString (ByteString)
|
||||
import qualified Data.ByteString as ByteString
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as Text
|
||||
import qualified Data.Text.IO as Text.IO
|
||||
@ -15,7 +18,13 @@ import Control.Monad.Trans.Reader (asks)
|
||||
import Control.Monad.IO.Class (MonadIO(liftIO))
|
||||
import System.IO (IOMode(..), withFile)
|
||||
import System.FilePath ((</>), (<.>))
|
||||
import System.Process (CreateProcess(..), StdStream(..), proc, readCreateProcessWithExitCode, callProcess)
|
||||
import System.Process
|
||||
( CreateProcess(..)
|
||||
, StdStream(..)
|
||||
, proc
|
||||
, readCreateProcessWithExitCode
|
||||
, callProcess
|
||||
)
|
||||
import System.Exit (ExitCode(..))
|
||||
import Control.Monad (unless)
|
||||
import Text.URI (URI(..), mkURI)
|
||||
@ -27,10 +36,24 @@ import Network.HTTP.Req
|
||||
, runReq
|
||||
, defaultHttpConfig
|
||||
, ignoreResponse
|
||||
, responseStatusCode, HttpConfig (..)
|
||||
, responseStatusCode
|
||||
, HttpConfig(..)
|
||||
, GET(..)
|
||||
, reqBr
|
||||
)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Data.Functor ((<&>))
|
||||
import Network.HTTP.Client (BodyReader, Response(..), brRead)
|
||||
import Conduit
|
||||
( ConduitT
|
||||
, yield
|
||||
, runConduitRes
|
||||
, sinkFile
|
||||
, (.|)
|
||||
, ZipSink(..)
|
||||
, await
|
||||
)
|
||||
import Crypto.Hash (Digest, MD5, hashInit, hashFinalize, hashUpdate)
|
||||
import Data.Void (Void)
|
||||
|
||||
updateSlackBuildVersion :: Text -> Text -> SlackBuilderT ()
|
||||
updateSlackBuildVersion packagePath version = do
|
||||
@ -123,3 +146,25 @@ cloneAndArchive repo nameVersion tarball tagPrefix = do
|
||||
, nameVersion'
|
||||
]
|
||||
liftIO $ callProcess "rm" ["-rf", nameVersion']
|
||||
|
||||
responseBodySource :: MonadIO m => Response BodyReader -> ConduitT i ByteString m ()
|
||||
responseBodySource = bodyReaderSource . responseBody
|
||||
where
|
||||
bodyReaderSource br = liftIO (brRead br) >>= go br
|
||||
go br bs = unless (ByteString.null bs) $ yield bs >> bodyReaderSource br
|
||||
|
||||
sinkHash :: Monad m => ConduitT ByteString Void m (Digest MD5)
|
||||
sinkHash = sink hashInit
|
||||
where
|
||||
sink ctx = await
|
||||
>>= maybe (pure $ hashFinalize ctx) (sink . hashUpdate ctx)
|
||||
|
||||
download :: Text -> FilePath -> SlackBuilderT (Maybe (Digest MD5))
|
||||
download uri target = SlackBuilderT (liftIO $ mkURI uri)
|
||||
>>= traverse (runReq defaultHttpConfig . go . fst) . useHttpsURI
|
||||
where
|
||||
go uri' = reqBr GET uri' NoReqBody mempty readResponse
|
||||
readResponse :: Response BodyReader -> IO (Digest MD5)
|
||||
readResponse response = runConduitRes
|
||||
$ responseBodySource response
|
||||
.| getZipSink (ZipSink (sinkFile target) *> ZipSink sinkHash)
|
||||
|
@ -36,7 +36,7 @@ import SlackBuilder.CommandLine
|
||||
import SlackBuilder.Trans
|
||||
import qualified Data.Aeson.KeyMap as KeyMap
|
||||
import GHC.Records (HasField(..))
|
||||
import Control.Monad.Trans.Reader (ReaderT(..), asks)
|
||||
import Control.Monad.Trans.Reader (asks)
|
||||
import Control.Monad.IO.Class (MonadIO(..))
|
||||
|
||||
newtype PackagistPackage = PackagistPackage
|
||||
@ -77,7 +77,7 @@ instance Aeson.FromJSON GhData where
|
||||
parseJSON (Aeson.Object keyMap)
|
||||
| Just data' <- KeyMap.lookup "data" keyMap =
|
||||
GhData <$> Aeson.withObject "GhData" (.: "repository") data'
|
||||
parseJSON v = fail "data key not found in the response"
|
||||
parseJSON _ = fail "data key not found in the response"
|
||||
|
||||
data GhVariables = GhVariables
|
||||
{ name :: Text
|
||||
|
Reference in New Issue
Block a user