105 lines
3.5 KiB
Haskell
105 lines
3.5 KiB
Haskell
module SlackBuilder.Package
|
|
( DownloadPlaceholder(..)
|
|
, Download(..)
|
|
, PackageInfo(..)
|
|
, Maintainer(..)
|
|
, Updater(..)
|
|
, infoTemplate
|
|
) where
|
|
|
|
import Data.List.NonEmpty (NonEmpty)
|
|
import Data.Text (Text)
|
|
import qualified Data.Text as Text
|
|
import Text.URI (URI(..))
|
|
import qualified Text.URI as URI
|
|
import Crypto.Hash (Digest, MD5)
|
|
import GHC.Records (HasField(..))
|
|
import System.FilePath (takeBaseName)
|
|
import Data.List (partition)
|
|
import SlackBuilder.Trans
|
|
|
|
-- | Download URI with the MD5 checksum of the target.
|
|
data Download = Download
|
|
{ download :: URI
|
|
, md5sum :: Digest MD5
|
|
, is64 :: Bool
|
|
} deriving (Eq, Show)
|
|
|
|
-- | Data used to generate an .info file.
|
|
data PackageInfo = PackageInfo
|
|
{ path :: FilePath
|
|
, version :: Text
|
|
, homepage :: Text
|
|
, requires :: [Text]
|
|
, maintainer :: Maintainer
|
|
} deriving (Eq, Show)
|
|
|
|
-- | Package maintainer information.
|
|
data Maintainer = Maintainer
|
|
{ name :: Text
|
|
, email :: Text
|
|
} deriving (Eq, Show)
|
|
|
|
-- | Appears in the download URI template and specifies which part of the URI
|
|
-- should be replaced with the package version.
|
|
data DownloadPlaceholder
|
|
= StaticPlaceholder Text
|
|
| VersionPlaceholder
|
|
deriving Eq
|
|
|
|
instance Show DownloadPlaceholder
|
|
where
|
|
show (StaticPlaceholder staticPlaceholder) = Text.unpack staticPlaceholder
|
|
show VersionPlaceholder = "{version}"
|
|
|
|
-- | List of URI components, including version placeholders.
|
|
newtype DownloadTemplate = DownloadTemplate (NonEmpty DownloadPlaceholder)
|
|
deriving Eq
|
|
|
|
instance Show DownloadTemplate
|
|
where
|
|
show (DownloadTemplate components) = concatMap show components
|
|
|
|
-- | Function used to get the latest version of a source.
|
|
newtype Updater = Updater (SlackBuilderT (Maybe Text))
|
|
|
|
packageName :: PackageInfo -> Text
|
|
packageName PackageInfo{ path } = Text.pack $ takeBaseName path
|
|
|
|
infoTemplate :: PackageInfo -> [Download] -> Text
|
|
infoTemplate package downloads =
|
|
let (downloads64, downloads32) = partition (getField @"is64") downloads
|
|
(download32, md5sum32, download64, md5sum64) = downloadEntries downloads64 downloads32
|
|
|
|
in Text.unlines
|
|
[ "PRGNAM=\"" <> packageName package <> "\""
|
|
, "VERSION=\"" <> getField @"version" package <> "\""
|
|
, "HOMEPAGE=\"" <> getField @"homepage" package <> "\""
|
|
, "DOWNLOAD=\"" <> download32 <> "\""
|
|
, "MD5SUM=\"" <> md5sum32 <> "\""
|
|
, "DOWNLOAD_x86_64=\"" <> download64 <> "\""
|
|
, "MD5SUM_x86_64=\"" <> md5sum64 <> "\""
|
|
, "REQUIRES=\"" <> Text.unwords (getField @"requires" package) <> "\""
|
|
, "MAINTAINER=\"" <> getField @"name" (getField @"maintainer" package) <> "\""
|
|
, "EMAIL=\"" <> getField @"email" (getField @"maintainer" package) <> "\""
|
|
]
|
|
|
|
downloadEntries :: [Download] -> [Download] -> (Text, Text, Text, Text)
|
|
downloadEntries downloads64 downloads32 =
|
|
let download32 =
|
|
if null downloads32 && not (null downloads64)
|
|
then
|
|
"UNSUPPORTED"
|
|
else
|
|
Text.intercalate " \\\n "
|
|
$ URI.render . getField @"download" <$> downloads32
|
|
|
|
md5sum32 = Text.intercalate " \\\n "
|
|
$ Text.pack . show . getField @"md5sum" <$> downloads32
|
|
download64 = Text.intercalate " \\\n "
|
|
$ URI.render . getField @"download" <$> downloads64
|
|
md5sum64 = Text.intercalate " \\\n "
|
|
$ Text.pack . show . getField @"md5sum" <$> downloads64
|
|
|
|
in (download32, md5sum32, download64, md5sum64)
|