summaryrefslogtreecommitdiff
path: root/app/Main.hs
blob: 46256cc0ae095d25f32ec3438d5488a8ef8a4f78 (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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
module Main
    ( main
    ) where

import Data.List.NonEmpty (NonEmpty(..))
import Control.Monad.IO.Class (MonadIO(..))
import Data.Maybe (fromMaybe)
import Options.Applicative (execParser)
import SlackBuilder.CommandLine
import SlackBuilder.Config
import SlackBuilder.Trans
import SlackBuilder.Updater
import qualified Toml
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.IO as Text.IO
import Control.Monad.Trans.Reader (ReaderT(..), asks)
import SlackBuilder.Download
import qualified SlackBuilder.Package as Package
import Text.URI (mkURI, URI)
import Text.URI.QQ (uri)
import Data.Foldable (for_)
import qualified Text.URI as URI
import GHC.Records (HasField(..))
import System.FilePath ((</>), (<.>))

data Package = Package
    { latest :: Package.Updater
    , category :: Text
    , name :: Text
    , homepage :: Maybe URI
    , requires :: [Text]
    }

autoUpdatable :: [Package]
autoUpdatable =
    [ Package
        { latest =
            let ghArguments = GhArguments{ owner = "universal-ctags", name = "ctags", transform = Nothing}
                latest' = latestGitHub ghArguments pure
                templateTail =
                    [ Package.StaticPlaceholder "/ctags-"
                    , Package.VersionPlaceholder
                    , Package.StaticPlaceholder ".tar.gz"
                    ]
                template = Package.DownloadTemplate
                    $ Package.StaticPlaceholder "https://github.com/universal-ctags/ctags/archive/" :| templateTail
             in Package.Updater latest' template
        , category = "development"
        , name = "universal-ctags"
        , homepage = Just [uri|https://ctags.io/|]
        , requires = pure "%README%"
        }
    ]

up2Date :: SlackBuilderT ()
up2Date = for_ autoUpdatable go
  where
    go package@Package{ latest = Package.Updater getLatest _ } =
        getLatest >>= mapM_ (updatePackage package)

updatePackage :: Package -> Text -> SlackBuilderT ()
updatePackage Package{..} version = do
    maintainer' <- SlackBuilderT $ asks maintainer
    let packagePath = category <> "/" <> name
        package' = Package.PackageInfo
            { version = version
            , requires = requires
            , path = Text.unpack packagePath
            , homepage = maybe "" URI.render homepage
            , maintainer = Package.Maintainer
                { name = getField @"name" maintainer'
                , email = getField @"email" maintainer'
                }
            }
        Package.Updater _ downloadTemplate = latest

    uri' <- liftIO $ Package.renderDownloadWithVersion downloadTemplate version
    let tarball = "slackbuilds/development/universal-ctags/ctags-#{version}.tar.gz"
    checksum <- fromMaybe undefined <$> download uri' tarball
    download' <- liftIO
        $ mkURI
        $ Text.replace "#{version}" version
        "https://download.dlackware.com/hosted-sources/universal-ctags/ctags-#{version}.tar.gz"
    repository' <- SlackBuilderT $ asks repository
    let infoFilePath = repository' </> Text.unpack packagePath
            </> (Text.unpack name <.> "info")

    liftIO $ Text.IO.writeFile infoFilePath
        $ Package.infoTemplate package' [Package.Download download' checksum False]
    updateSlackBuildVersion packagePath version

    remotePath' <- SlackBuilderT $ asks remotePath
    uploadCommand (Text.pack tarball) $ remotePath' <> "/universal-ctags"

    commit packagePath version

main :: IO ()
main = do
    programCommand <- execParser slackBuilderParser
    settings <- Toml.decodeFile settingsCodec "config/config.toml"
    latestVersion <- flip runReaderT settings
        $ runSlackBuilderT
        $ executeCommand programCommand

    Text.IO.putStrLn $ fromMaybe "" latestVersion
  where
    executeCommand = \case
        PackagistCommand packagistArguments ->
            latestPackagist packagistArguments
        TextCommand textArguments -> latestText textArguments
        GhCommand ghArguments@GhArguments{ transform }
            -> latestGitHub ghArguments $ chooseTransformFunction transform
        SlackBuildCommand packagePath version ->
            updateSlackBuildVersion packagePath version >> pure Nothing
        CommitCommand packagePath version ->
            commit packagePath version >> pure Nothing
        ExistsCommand urlPath -> pure . Text.pack . show
            <$> remoteFileExists urlPath
        ArchiveCommand repo nameVersion tarball tagPrefix ->
            cloneAndArchive repo nameVersion tarball tagPrefix >> pure Nothing
        DownloadCommand 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
        DownloadAndDeployCommand uri' tarball -> fmap (Text.pack . show)
            <$> downloadAndDeploy uri' tarball
        Up2DateCommand -> up2Date >> pure Nothing
    chooseTransformFunction (Just "php") = phpTransform
    chooseTransformFunction (Just "rdiff-backup") = Text.stripPrefix "v"
    chooseTransformFunction _ = stripPrefix "v"
    stripPrefix prefix string = Just
        $ fromMaybe string
        $ Text.stripPrefix prefix string
    phpTransform version
        | (majorPrefix, _patchVersion) <- Text.breakOnEnd "." version
        , majorPrefix == "php-8.2." = Just $ Text.drop (Text.length "php-") version
        | otherwise = Nothing