slackbuilder/src/Main.hs
Eugen Wissner bc3ba48d85
All checks were successful
Build / audit (push) Successful in 14m54s
Build / test (push) Successful in 14m20s
Recognize + in sematnic tags
2024-03-19 11:34:19 +01:00

293 lines
12 KiB
Haskell

{- This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at https://mozilla.org/MPL/2.0/. -}
module Main
( main
) where
import Data.Char (isNumber)
import Control.Applicative (Applicative(..))
import Data.List.NonEmpty (NonEmpty(..))
import Control.Monad.Catch (MonadThrow(..))
import Control.Monad.IO.Class (MonadIO(..))
import qualified Data.Map as Map
import Options.Applicative (execParser)
import SlackBuilder.CommandLine
import SlackBuilder.Config
import SlackBuilder.Trans
import SlackBuilder.LatestVersionCheck
import SlackBuilder.Update
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(..))
import SlackBuilder.Package (PackageDescription(..))
import qualified SlackBuilder.Package as Package
import Text.URI.QQ (uri)
import Data.Foldable (for_, find)
import GHC.Records (HasField(..))
import System.Process (CmdSpec(..))
autoUpdatable :: [PackageDescription]
autoUpdatable =
[ PackageDescription
{ latest =
let ghArguments = PackageOwner{ owner = "universal-ctags", name = "ctags" }
templateTail =
[ Package.VersionPlaceholder
, 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
{ detectLatest = latestGitHub ghArguments stableTagTransform
, getVersion = reuploadWithTemplate template []
, is64 = False
}
, name = "universal-ctags"
, downloaders = mempty
}
, PackageDescription
{ latest =
let packagistArguments = PackageOwner{ owner = "composer", name = "composer" }
template = Package.DownloadTemplate
$ Package.StaticPlaceholder "https://getcomposer.org/download/"
:| [Package.VersionPlaceholder, Package.StaticPlaceholder "/composer.phar"]
in Package.Updater
{ detectLatest = latestPackagist packagistArguments
, getVersion = downloadWithTemplate template
, is64 = False
}
, name = "composer"
, downloaders = mempty
}
, PackageDescription
{ latest =
let ghArguments = PackageOwner
{ owner = "jitsi"
, name = "jitsi-meet-electron"
}
template = Package.DownloadTemplate
$ Package.StaticPlaceholder "https://github.com/jitsi/jitsi-meet-electron/releases/download/v"
:| Package.VersionPlaceholder
: [Package.StaticPlaceholder "/jitsi-meet-x86_64.AppImage"]
in Package.Updater
{ detectLatest = latestGitHub ghArguments $ Text.stripPrefix "v"
, getVersion = downloadWithTemplate template
, is64 = True
}
, name = "jitsi-meet-desktop"
, downloaders = mempty
}
, PackageDescription
{ latest =
let ghArguments = PackageOwner
{ owner = "php"
, name = "php-src"
}
checkVersion x
| not $ Text.isInfixOf "RC" x
, Text.isPrefixOf "php-8.2." x = Text.stripPrefix "php-" x
| otherwise = Nothing
template = Package.DownloadTemplate
$ Package.StaticPlaceholder "https://www.php.net/distributions/php-"
:| Package.VersionPlaceholder
: [Package.StaticPlaceholder ".tar.xz"]
in Package.Updater
{ detectLatest = latestGitHub ghArguments checkVersion
, getVersion = downloadWithTemplate template
, is64 = False
}
, name = "php82"
, downloaders = mempty
}
, PackageDescription
{ latest =
let ghArguments = PackageOwner
{ owner = "kovidgoyal"
, name = "kitty"
}
templateTail =
[ Package.StaticPlaceholder "/kitty-"
, Package.VersionPlaceholder
, Package.StaticPlaceholder ".tar.xz"
]
template = Package.DownloadTemplate
$ Package.StaticPlaceholder "https://github.com/kovidgoyal/kitty/releases/download/v"
:| Package.VersionPlaceholder
: templateTail
in Package.Updater
{ detectLatest = latestGitHub ghArguments stableTagTransform
, getVersion = reuploadWithTemplate template [RawCommand "go" ["mod", "vendor"]]
, is64 = False
}
, name = "kitty"
, downloaders = mempty
}
, PackageDescription
{ latest =
let ghArguments = PackageOwner
{ owner = "rdiff-backup"
, name = "rdiff-backup"
}
template = Package.DownloadTemplate
$ Package.StaticPlaceholder "https://github.com/rdiff-backup/rdiff-backup/releases/download/v"
:| Package.VersionPlaceholder
: Package.StaticPlaceholder "/rdiff-backup-"
: Package.VersionPlaceholder
: [Package.StaticPlaceholder ".tar.gz"]
in Package.Updater
{ detectLatest = latestGitHub ghArguments stableTagTransform
, getVersion = reuploadWithTemplate template []
, is64 = False
}
, name = "rdiff-backup"
, downloaders = mempty
}
, PackageDescription
{ latest =
let needle = "Linux—"
textArguments = TextArguments
{ textURL = "https://help.webex.com/en-us/article/mqkve8/Webex-App-%7C-Release-notes"
, versionPicker = Text.takeWhile (liftA2 (||) (== '.') isNumber)
. Text.drop (Text.length needle)
. snd
. Text.breakOn needle
}
template = Package.DownloadTemplate $ pure
$ Package.StaticPlaceholder
"https://binaries.webex.com/WebexDesktop-Ubuntu-Official-Package/Webex.deb"
in Package.Updater
{ detectLatest = latestText textArguments
, getVersion = downloadWithTemplate template
, is64 = True
}
, name = "webex"
, downloaders = mempty
}
, PackageDescription
{ latest =
let ghArguments = PackageOwner
{ owner = "librsync"
, name = "librsync"
}
template = Package.DownloadTemplate
$ Package.StaticPlaceholder "https://github.com/librsync/librsync/archive/v"
:| Package.VersionPlaceholder
: Package.StaticPlaceholder "/librsync-"
: Package.VersionPlaceholder
: [Package.StaticPlaceholder ".tar.gz"]
in Package.Updater
{ detectLatest = latestGitHub ghArguments $ Text.stripPrefix "v"
, getVersion = reuploadWithTemplate template []
, is64 = True
}
, name = "librsync"
, downloaders = mempty
}
, PackageDescription
{ latest =
let textArguments = TextArguments
{ textURL = "https://downloads.dlang.org/releases/LATEST"
, versionPicker = Text.strip
}
template = Package.DownloadTemplate
$ Package.StaticPlaceholder "https://downloads.dlang.org/releases/2.x/"
:| Package.VersionPlaceholder
: Package.StaticPlaceholder "/dmd."
: Package.VersionPlaceholder
: [Package.StaticPlaceholder ".linux.tar.xz"]
in Package.Updater
{ detectLatest = latestText textArguments
, getVersion = downloadWithTemplate template
, is64 = False
}
, name = "dmd"
, downloaders = mempty
}
, PackageDescription
{ latest =
let textArguments = TextArguments
{ textURL = "https://downloads.dlang.org/releases/LATEST"
, versionPicker = Text.strip
}
template = Package.DownloadTemplate
$ Package.StaticPlaceholder "https://codeload.github.com/dlang/tools/tar.gz/v"
:| [Package.VersionPlaceholder]
in Package.Updater
{ detectLatest = latestText textArguments
, getVersion = reuploadWithTemplate template []
, is64 = False
}
, name = "d-tools"
, downloaders =
let dubArguments = PackageOwner{ owner = "dlang", name = "dub" }
dscannerArguments = PackageOwner{ owner = "dlang-community", name = "D-Scanner" }
dcdArguments = PackageOwner{ owner = "dlang-community", name = "DCD" }
latestDub = Package.Updater
{ detectLatest = latestGitHub dubArguments stableTagTransform
, getVersion = downloadWithTemplate dubTemplate
, is64 = False
}
latestDscanner = Package.Updater
{ detectLatest = latestGitHub dscannerArguments stableTagTransform
, getVersion = cloneFromGit dscannerURI "v"
, is64 = False
}
dcdURI = [uri|https://github.com/dlang-community/DCD.git|]
latestDcd = Package.Updater
{ detectLatest = latestGitHub dcdArguments stableTagTransform
, getVersion = cloneFromGit dcdURI "v"
, is64 = False
}
dubTemplate = Package.DownloadTemplate
$ Package.StaticPlaceholder "https://codeload.github.com/dlang/dub/tar.gz/v"
:| [Package.VersionPlaceholder]
dscannerURI = [uri|https://github.com/dlang-community/D-Scanner.git|]
in Map.fromList
[ ("DUB", latestDub)
, ("DSCANNER", latestDscanner)
, ("DCD", latestDcd)
]
}
]
up2Date :: Maybe Text -> SlackBuilderT ()
up2Date = \case
Nothing -> for_ autoUpdatable go
Just packageName
| Just foundPackage <- find ((packageName ==) . getField @"name") autoUpdatable ->
go foundPackage
| otherwise -> throwM $ UpdaterNotFound packageName
where
go package = getAndLogLatest package
>>= mapM_ updatePackageIfRequired
>> liftIO (putStrLn "")
check :: SlackBuilderT ()
check = for_ autoUpdatable go
where
go package = getAndLogLatest package
>>= mapM_ checkUpdateAvailability
>> liftIO (putStrLn "")
main :: IO ()
main = do
programCommand <- execParser slackBuilderParser
settings <- Toml.decodeFile settingsCodec "config/config.toml"
latestVersion <- flip runReaderT settings
$ runSlackBuilderT
$ executeCommand programCommand
maybe (pure ()) Text.IO.putStrLn latestVersion
where
executeCommand = \case
CheckCommand -> check >> pure Nothing
Up2DateCommand packageName -> up2Date packageName >> pure Nothing