diff --git a/app/Main.hs b/app/Main.hs index e8cd335..7766959 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -12,6 +12,7 @@ import SlackBuilder.Config import SlackBuilder.Trans import SlackBuilder.Updater import qualified Toml +import qualified Data.ByteString as ByteString import Data.Text (Text) import qualified Data.Text as Text import qualified Data.Text.IO as Text.IO @@ -24,6 +25,8 @@ import Data.Foldable (for_) import qualified Text.URI as URI import GHC.Records (HasField(..)) import System.FilePath ((), (<.>)) +import SlackBuilder.Info +import Text.Megaparsec (parse, errorBundlePretty) data Package = Package { latest :: Package.Updater @@ -89,19 +92,51 @@ autoUpdatable = , requires = mempty , reupload = False } + , 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" + , homepage = Just [uri|https://www.php.net/|] + , requires = ["postgresql"] + , reupload = False + } ] up2Date :: SlackBuilderT () up2Date = for_ autoUpdatable go where - go package = getAndLogLatest package >>= mapM_ (updatePackage package) + go package = getAndLogLatest package >>= mapM_ (updatePackageIfRequired package) getAndLogLatest Package{ latest = Package.Updater getLatest _, name } = liftIO (putStrLn $ Text.unpack name <> ": Retreiving the latest version.") >> getLatest +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 + Right _parsedInfoFile -> updatePackage package version + Left errorBundle -> liftIO $ putStr $ errorBundlePretty errorBundle + updatePackage :: Package -> Text -> SlackBuilderT () updatePackage Package{..} version = do - maintainer' <- SlackBuilderT $ asks maintainer + maintainer' <- SlackBuilderT $ asks $ getField @"maintainer" let packagePath = category <> "/" <> name package' = Package.PackageInfo { version = version diff --git a/lib/SlackBuilder/Info.hs b/lib/SlackBuilder/Info.hs index bedbc48..ed5957c 100644 --- a/lib/SlackBuilder/Info.hs +++ b/lib/SlackBuilder/Info.hs @@ -6,6 +6,7 @@ module SlackBuilder.Info , updateDownloadVersion ) where +import Control.Applicative (Alternative(..)) import Control.Monad.Combinators (sepBy) import qualified Data.ByteArray as ByteArray import Data.ByteString (ByteString) @@ -33,6 +34,7 @@ import Text.URI , render , unRText ) +import qualified Data.Word8 as Word8 type GenParser = Parsec Void ByteString @@ -42,6 +44,11 @@ data PackageInfo = PackageInfo , homepage :: Text , downloads :: [URI] , checksums :: [Digest MD5] + , downloadX64 :: [URI] + , checksumX64 :: [Digest MD5] + , requires :: [ByteString] + , maintainer :: Text + , email :: Text } deriving (Eq, Show) variableEntry :: ByteString -> GenParser ByteString @@ -52,8 +59,8 @@ variableEntry variable = string (Char8.append variable "=\"") variableSeparator :: GenParser () variableSeparator = string " \\" *> space -packageDownloads :: GenParser [URI] -packageDownloads = string "DOWNLOAD=\"" +packageDownloads :: ByteString -> GenParser [URI] +packageDownloads variableName = string (variableName <> "=\"") *> sepBy parserBs variableSeparator <* string "\"\n" @@ -65,19 +72,41 @@ hexDigit = packageChecksum :: GenParser ByteString packageChecksum = ByteString.pack <$> count 16 hexDigit -packageChecksums :: GenParser [ByteString] -packageChecksums = string "MD5SUM=\"" +packageChecksums :: ByteString -> GenParser [ByteString] +packageChecksums variableName = string (variableName <> "=\"") *> sepBy packageChecksum variableSeparator <* string "\"\n" +packageRequires :: GenParser [ByteString] +packageRequires = string "REQUIRES=\"" + *> sepBy packageName space + <* string "\"\n" + +packageName :: GenParser ByteString +packageName = takeWhile1P Nothing isNameToken + where + isNameToken x = Word8.isAlphaNum x + || x == Word8._hyphen + || x == Word8._underscore + parseInfoFile :: GenParser PackageInfo parseInfoFile = PackageInfo - <$> (Char8.unpack <$> variableEntry "PKGNAM") + <$> (Char8.unpack <$> packagePrgnam) <*> (Text.decodeUtf8 <$> variableEntry "VERSION") <*> (Text.decodeUtf8 <$> variableEntry "HOMEPAGE") - <*> packageDownloads - <*> (mapMaybe digestFromByteString <$> packageChecksums) + <*> packageDownloads "DOWNLOAD" + <*> (mapMaybe digestFromByteString <$> packageChecksums "MD5SUM") + <*> packageDownloads "DOWNLOAD_x86_64" + <*> (mapMaybe digestFromByteString <$> packageChecksums "MD5SUM_x86_64") + <*> packageRequires + <*> (Text.decodeUtf8 <$> variableEntry "MAINTAINER") + <*> (Text.decodeUtf8 <$> variableEntry "EMAIL") <* eof + where + packagePrgnam = (string "PKGNAM" <|> string "PRGNAM") + >> string "=\"" + *> packageName + <* "\"\n" updateDownloadVersion :: PackageInfo -> Text -> Maybe String -> [URI] updateDownloadVersion package toVersion gnomeVersion diff --git a/slackbuilder.cabal b/slackbuilder.cabal index 0a7cdb5..6d6139c 100644 --- a/slackbuilder.cabal +++ b/slackbuilder.cabal @@ -27,7 +27,8 @@ common dependencies parser-combinators ^>= 1.3, text ^>= 2.0, tomland ^>= 1.3.3, - transformers ^>= 0.5.6 + transformers ^>= 0.5.6, + word8 ^>= 0.1.3 default-language: Haskell2010 default-extensions: DataKinds