Implement clone command in the binary

This commit is contained in:
Eugen Wissner 2023-08-25 10:30:24 +02:00
parent 6983304b9d
commit 2126488066
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
4 changed files with 38 additions and 61 deletions

View File

@ -13,6 +13,7 @@ import qualified Toml
import qualified Data.Text as Text import qualified Data.Text as Text
import Control.Monad.Trans.Reader (ReaderT(..)) import Control.Monad.Trans.Reader (ReaderT(..))
import SlackBuilder.Download import SlackBuilder.Download
import Text.URI (mkURI)
main :: IO () main :: IO ()
main = do main = do
@ -38,8 +39,12 @@ main = do
<$> remoteFileExists urlPath <$> remoteFileExists urlPath
ArchiveCommand repo nameVersion tarball tagPrefix -> ArchiveCommand repo nameVersion tarball tagPrefix ->
cloneAndArchive repo nameVersion tarball tagPrefix >> pure Nothing cloneAndArchive repo nameVersion tarball tagPrefix >> pure Nothing
DownloadCommand url target -> fmap (Text.pack . show) DownloadCommand url target
<$> download url target | Just uri <- mkURI url -> fmap (Text.pack . show)
<$> download uri target
| otherwise -> pure Nothing
CloneCommand repo tarball tagPrefix -> fmap (Text.pack . show)
<$> clone repo tarball tagPrefix
chooseTransformFunction (Just "php") = phpTransform chooseTransformFunction (Just "php") = phpTransform
chooseTransformFunction (Just "rdiff-backup") = Text.stripPrefix "v" chooseTransformFunction (Just "rdiff-backup") = Text.stripPrefix "v"
chooseTransformFunction _ = stripPrefix "v" chooseTransformFunction _ = stripPrefix "v"

View File

@ -28,6 +28,7 @@ data SlackBuilderCommand
| ExistsCommand Text | ExistsCommand Text
| ArchiveCommand Text Text String Text | ArchiveCommand Text Text String Text
| DownloadCommand Text String | DownloadCommand Text String
| CloneCommand Text Text Text
deriving (Eq, Show) deriving (Eq, Show)
data PackagistArguments = PackagistArguments data PackagistArguments = PackagistArguments
@ -71,6 +72,7 @@ slackBuilderCommand = subparser
<> command "exists" (info existsCommand mempty) <> command "exists" (info existsCommand mempty)
<> command "archive" (info archiveCommand mempty) <> command "archive" (info archiveCommand mempty)
<> command "download" (info downloadCommand mempty) <> command "download" (info downloadCommand mempty)
<> command "clone" (info cloneCommand mempty)
where where
slackBuildCommand = SlackBuildCommand slackBuildCommand = SlackBuildCommand
<$> argument str (metavar "PATH") <$> argument str (metavar "PATH")
@ -87,3 +89,7 @@ slackBuilderCommand = subparser
downloadCommand = DownloadCommand downloadCommand = DownloadCommand
<$> argument str (metavar "URI") <$> argument str (metavar "URI")
<*> argument str (metavar "TARGET") <*> argument str (metavar "TARGET")
cloneCommand = CloneCommand
<$> argument str (metavar "REPO")
<*> argument str (metavar "TARBALL")
<*> argument str (metavar "TAG_PREFIX")

View File

@ -1,5 +1,6 @@
module SlackBuilder.Download module SlackBuilder.Download
( cloneAndArchive ( clone
, cloneAndArchive
, commit , commit
, download , download
, hostedSources , hostedSources
@ -17,7 +18,7 @@ import SlackBuilder.Trans
import Control.Monad.Trans.Reader (asks) import Control.Monad.Trans.Reader (asks)
import Control.Monad.IO.Class (MonadIO(liftIO)) import Control.Monad.IO.Class (MonadIO(liftIO))
import System.IO (IOMode(..), withFile) import System.IO (IOMode(..), withFile)
import System.FilePath ((</>), (<.>)) import System.FilePath ((</>), (<.>), takeBaseName, splitPath, joinPath)
import System.Process import System.Process
( CreateProcess(..) ( CreateProcess(..)
, StdStream(..) , StdStream(..)
@ -51,6 +52,7 @@ import Conduit
, (.|) , (.|)
, ZipSink(..) , ZipSink(..)
, await , await
, sourceFile
) )
import Crypto.Hash (Digest, MD5, hashInit, hashFinalize, hashUpdate) import Crypto.Hash (Digest, MD5, hashInit, hashFinalize, hashUpdate)
import Data.Void (Void) import Data.Void (Void)
@ -159,12 +161,29 @@ sinkHash = sink hashInit
sink ctx = await sink ctx = await
>>= maybe (pure $ hashFinalize ctx) (sink . hashUpdate ctx) >>= maybe (pure $ hashFinalize ctx) (sink . hashUpdate ctx)
download :: Text -> FilePath -> SlackBuilderT (Maybe (Digest MD5)) download :: URI -> FilePath -> SlackBuilderT (Maybe (Digest MD5))
download uri target = SlackBuilderT (liftIO $ mkURI uri) download uri target = traverse (runReq defaultHttpConfig . go . fst)
>>= traverse (runReq defaultHttpConfig . go . fst) . useHttpsURI $ useHttpsURI uri
where where
go uri' = reqBr GET uri' NoReqBody mempty readResponse go uri' = reqBr GET uri' NoReqBody mempty readResponse
readResponse :: Response BodyReader -> IO (Digest MD5) readResponse :: Response BodyReader -> IO (Digest MD5)
readResponse response = runConduitRes readResponse response = runConduitRes
$ responseBodySource response $ responseBodySource response
.| getZipSink (ZipSink (sinkFile target) *> ZipSink sinkHash) .| getZipSink (ZipSink (sinkFile target) *> ZipSink sinkHash)
clone :: Text -> Text -> Text -> SlackBuilderT (Maybe (Digest MD5))
clone repo tarball tagPrefix = do
let tarballPath = Text.unpack tarball
nameVersion = Text.pack $ takeBaseName tarballPath
remotePath = Text.pack $ joinPath $ ("/" :) $ drop 1 $ splitPath tarballPath
localPath = "slackbuilds" </> tarballPath
remoteFileExists' <- remoteFileExists remotePath
if remoteFileExists'
then
hostedSources remotePath >>= flip download localPath
else
let go = sourceFile localPath .| sinkHash
in cloneAndArchive repo nameVersion tarballPath tagPrefix
>> uploadCommand tarball remotePath
>> liftIO (runConduitRes go) <&> Just

View File

@ -15,20 +15,7 @@ module SlackBuilder
extend Rake::FileUtilsExt extend Rake::FileUtilsExt
def self.clone(repo, tarball, tag_prefix = 'v') def self.clone(repo, tarball, tag_prefix = 'v')
name_version = File.basename tarball, '.tar.xz' `./bin/slackbuilder clone #{repo} #{tarball} #{tag_prefix}`
remote_path = tarball[tarball.index('/')..]
if remote_file_exists?(remote_path)
uri = URI hosted_sources(remote_path)
return download(uri, "slackbuilds/#{tarball}").hexdigest
end
clone_and_archive repo, name_version, tarball, tag_prefix
sh(*upload_command(tarball, remote_path))
Digest::MD5.hexdigest File.read("slackbuilds/#{tarball}")
end end
def self.download(uri, target) def self.download(uri, target)
@ -56,46 +43,6 @@ module SlackBuilder
checksum.hexdigest checksum.hexdigest
end end
private_class_method def self.redirect_download(location, target)
puts 'redirecting...'
new_location = URI location
download new_location, target
end
private_class_method def self.write_chunk(response, checksum, progressbar, io)
response.read_body do |chunk|
progressbar.progress += chunk.length
io << chunk
checksum << chunk
end
end
private_class_method def self.write_download(target, response)
checksum = Digest::MD5.new
progressbar = ProgressBar.create title: target, total: response.header.content_length
File.open target, 'w' do |io|
write_chunk response, checksum, progressbar, io
end
progressbar.finish
checksum
end
private_class_method def self.start_download(uri, target, http)
request = Net::HTTP::Get.new uri
http.request request do |response|
case response
when Net::HTTPRedirection
return redirect_download response['location'], target
else
return write_download target, response
end
end
end
private_class_method def self.upload_command(local_path, remote_path) private_class_method def self.upload_command(local_path, remote_path)
['scp', "slackbuilds/#{local_path}", CONFIG[:remote_path] + remote_path] ['scp', "slackbuilds/#{local_path}", CONFIG[:remote_path] + remote_path]
end end