slackbuilder/app/Main.hs

207 lines
8.6 KiB
Haskell
Raw Normal View History

module Main
( main
) where
2023-09-03 10:26:43 +02:00
import Data.List.NonEmpty (NonEmpty(..))
2023-10-01 17:19:06 +02:00
import qualified Data.List.NonEmpty as NonEmpty
2023-09-03 10:26:43 +02:00
import Control.Monad.IO.Class (MonadIO(..))
2023-10-01 17:19:06 +02:00
import Data.Maybe (fromJust, fromMaybe)
import Options.Applicative (execParser)
import SlackBuilder.CommandLine
2023-08-09 20:59:42 +02:00
import SlackBuilder.Config
2023-08-15 10:33:19 +02:00
import SlackBuilder.Trans
import SlackBuilder.Updater
2023-08-09 20:59:42 +02:00
import qualified Toml
2023-10-04 22:36:19 +02:00
import qualified Data.ByteString as ByteString
2023-09-03 10:26:43 +02:00
import Data.Text (Text)
2023-08-09 20:59:42 +02:00
import qualified Data.Text as Text
2023-10-05 19:24:42 +02:00
import qualified Data.Text.Encoding as Text.Encoding
2023-09-03 10:26:43 +02:00
import qualified Data.Text.IO as Text.IO
import Control.Monad.Trans.Reader (ReaderT(..), asks)
2023-08-15 10:33:19 +02:00
import SlackBuilder.Download
2023-10-05 19:24:42 +02:00
import SlackBuilder.Package (Package(..))
2023-09-03 10:26:43 +02:00
import qualified SlackBuilder.Package as Package
2023-10-05 19:24:42 +02:00
import Text.URI (mkURI)
2023-09-03 10:26:43 +02:00
import Text.URI.QQ (uri)
import Data.Foldable (for_)
import qualified Text.URI as URI
import System.FilePath ((</>), (<.>))
2023-10-04 22:36:19 +02:00
import SlackBuilder.Info
import Text.Megaparsec (parse, errorBundlePretty)
2023-09-03 10:26:43 +02:00
autoUpdatable :: [Package]
autoUpdatable =
[ Package
{ latest =
let ghArguments = GhArguments{ owner = "universal-ctags", name = "ctags", transform = Nothing}
latest' = latestGitHub ghArguments pure
templateTail =
[ Package.VersionPlaceholder
, Package.StaticPlaceholder "/ctags-"
2023-09-03 10:26:43 +02:00
, Package.VersionPlaceholder
, Package.StaticPlaceholder ".tar.gz"
]
template = Package.DownloadTemplate
2023-10-01 17:19:06 +02:00
$ Package.StaticPlaceholder "https://github.com/universal-ctags/ctags/archive/"
:| templateTail
2023-09-03 10:26:43 +02:00
in Package.Updater latest' template
, category = "development"
, name = "universal-ctags"
2023-10-05 19:24:42 +02:00
, homepage = [uri|https://ctags.io/|]
2023-09-03 10:26:43 +02:00
, requires = pure "%README%"
2023-10-01 17:19:06 +02:00
, reupload = True
}
, Package
{ latest =
let packagistArguments = PackagistArguments{ vendor = "composer", name = "composer" }
latest' = latestPackagist packagistArguments
template = Package.DownloadTemplate
$ Package.StaticPlaceholder "https://getcomposer.org/download/"
:| [Package.VersionPlaceholder, Package.StaticPlaceholder "/composer.phar"]
in Package.Updater latest' template
, category = "development"
, name = "composer"
2023-10-05 19:24:42 +02:00
, homepage = [uri|https://getcomposer.org/|]
2023-10-01 17:19:06 +02:00
, requires = mempty
, reupload = False
2023-09-03 10:26:43 +02:00
}
2023-10-03 18:53:41 +02:00
, Package
{ latest =
let ghArguments = GhArguments
{ owner = "jitsi"
, name = "jitsi-meet-electron"
, transform = Nothing
}
latest' = latestGitHub ghArguments $ Text.stripPrefix "v"
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 latest' template
, category = "network"
, name = "jitsi-meet-desktop"
2023-10-05 19:24:42 +02:00
, homepage = [uri|https://jitsi.org/|]
2023-10-03 18:53:41 +02:00
, requires = mempty
, reupload = False
}
2023-10-04 22:36:19 +02:00
, Package
{ latest =
let ghArguments = GhArguments
{ owner = "php"
, name = "php-src"
, transform = Nothing
}
checkVersion x
| Text.isPrefixOf "php-8.2." x = Text.stripPrefix "php-" x
| otherwise = Nothing
latest' = latestGitHub ghArguments checkVersion
template = Package.DownloadTemplate
$ Package.StaticPlaceholder "https://www.php.net/distributions/php-"
:| Package.VersionPlaceholder
: [Package.StaticPlaceholder ".tar.xz"]
in Package.Updater latest' template
, category = "development"
, name = "php82"
2023-10-05 19:24:42 +02:00
, homepage = [uri|https://www.php.net/|]
2023-10-04 22:36:19 +02:00
, requires = ["postgresql"]
, reupload = False
}
2023-09-03 10:26:43 +02:00
]
up2Date :: SlackBuilderT ()
up2Date = for_ autoUpdatable go
where
2023-10-04 22:36:19 +02:00
go package = getAndLogLatest package >>= mapM_ (updatePackageIfRequired package)
getAndLogLatest Package{ latest = Package.Updater getLatest _, name }
= liftIO (putStrLn $ Text.unpack name <> ": Retreiving the latest version.")
>> getLatest
2023-09-03 10:26:43 +02:00
2023-10-04 22:36:19 +02:00
updatePackageIfRequired :: Package -> Text -> SlackBuilderT ()
updatePackageIfRequired package@Package{..} version = do
let packagePath = Text.unpack category </> Text.unpack name </> (Text.unpack name <.> "info")
repository' <- SlackBuilderT $ asks repository
infoContents <- liftIO $ ByteString.readFile $ repository' </> packagePath
case parse parseInfoFile packagePath infoContents of
2023-10-05 19:24:42 +02:00
Right parsedInfoFile -> updatePackage package parsedInfoFile version
2023-10-04 22:36:19 +02:00
Left errorBundle -> liftIO $ putStr $ errorBundlePretty errorBundle
2023-10-05 19:24:42 +02:00
updatePackage :: Package -> PackageInfo -> Text -> SlackBuilderT ()
updatePackage Package{..} info version = do
2023-09-03 10:26:43 +02:00
let packagePath = category <> "/" <> name
Package.Updater _ downloadTemplate = latest
repository' <- SlackBuilderT $ asks repository
2023-09-03 10:26:43 +02:00
uri' <- liftIO $ Package.renderDownloadWithVersion downloadTemplate version
2023-10-01 17:19:06 +02:00
let downloadFileName = URI.unRText
$ NonEmpty.last $ snd $ fromJust $ URI.uriPath uri'
relativeTarball = packagePath <> "/" <> downloadFileName
tarball = repository' </> Text.unpack relativeTarball
liftIO $ putStrLn
$ "Downloading " <> Text.unpack (URI.render uri') <> " to " <> tarball <> "."
2023-10-01 17:19:06 +02:00
checksum <- fromJust <$> download uri' tarball
download' <- handleReupload uri' relativeTarball downloadFileName
let infoFilePath = repository' </> Text.unpack packagePath
</> (Text.unpack name <.> "info")
2023-10-05 19:24:42 +02:00
package' = info
{ version = version
, requires = Text.Encoding.encodeUtf8 <$> requires
, homepage = URI.render homepage
, downloads = [download']
, checksums = [checksum]
}
2023-09-03 10:26:43 +02:00
2023-10-05 19:24:42 +02:00
liftIO $ Text.IO.writeFile infoFilePath $ generate package'
2023-09-03 10:26:43 +02:00
updateSlackBuildVersion packagePath version
2023-09-03 10:26:43 +02:00
commit packagePath version
2023-10-01 17:19:06 +02:00
where
handleReupload uri' relativeTarball downloadFileName
| reupload =
liftIO (putStrLn $ "Upload the source tarball " <> Text.unpack relativeTarball)
>> uploadCommand relativeTarball ("/" <> name)
>> liftIO (mkURI $ "https://download.dlackware.com/hosted-sources/" <> name <> "/" <> downloadFileName)
| otherwise = pure uri'
main :: IO ()
main = do
programCommand <- execParser slackBuilderParser
2023-08-09 20:59:42 +02:00
settings <- Toml.decodeFile settingsCodec "config/config.toml"
2023-08-15 10:33:19 +02:00
latestVersion <- flip runReaderT settings
$ runSlackBuilderT
$ executeCommand programCommand
Text.IO.putStrLn $ fromMaybe "" latestVersion
2023-08-09 20:59:42 +02:00
where
2023-08-15 10:33:19 +02:00
executeCommand = \case
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
2023-08-25 10:30:24 +02:00
DownloadCommand url target
2023-09-03 10:26:43 +02:00
| Just uri' <- mkURI url -> fmap (Text.pack . show)
<$> download uri' target
2023-08-25 10:30:24 +02:00
| otherwise -> pure Nothing
CloneCommand repo tarball tagPrefix -> fmap (Text.pack . show)
<$> clone repo tarball tagPrefix
2023-09-03 10:26:43 +02:00
DownloadAndDeployCommand uri' tarball -> fmap (Text.pack . show)
<$> downloadAndDeploy uri' tarball
Up2DateCommand -> up2Date >> pure Nothing
2023-08-10 12:47:43 +02:00
chooseTransformFunction (Just "php") = phpTransform
chooseTransformFunction (Just "rdiff-backup") = Text.stripPrefix "v"
chooseTransformFunction _ = stripPrefix "v"
2023-08-09 20:59:42 +02:00
stripPrefix prefix string = Just
$ fromMaybe string
$ Text.stripPrefix prefix string
2023-08-10 12:47:43 +02:00
phpTransform version
2023-08-21 13:38:20 +02:00
| (majorPrefix, _patchVersion) <- Text.breakOnEnd "." version
2023-08-10 12:47:43 +02:00
, majorPrefix == "php-8.2." = Just $ Text.drop (Text.length "php-") version
| otherwise = Nothing