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.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 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 = getAndLogLatest package >>= mapM_ (updatePackage package) getAndLogLatest Package{ latest = Package.Updater getLatest _, name } = liftIO (putStrLn $ Text.unpack name <> ": Retreiving the latest version.") >> getLatest 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 repository' <- SlackBuilderT $ asks repository uri' <- liftIO $ Package.renderDownloadWithVersion downloadTemplate version let relativeTarball = Text.replace "#{version}" version "development/universal-ctags/ctags-#{version}.tar.gz" tarball = repository' Text.unpack relativeTarball liftIO $ putStrLn $ "Downloading " <> Text.unpack (URI.render uri') <> " to " <> tarball <> "." 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" 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 liftIO $ putStrLn $ "Upload the source tarball " <> Text.unpack relativeTarball uploadCommand relativeTarball "/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