summaryrefslogtreecommitdiff
path: root/app/SlackBuilder/Package.hs
blob: cc07cc581f06cc58703c5e0a9eb695aa77eb4594 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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)