List installed packages from a repository
All checks were successful
Build / audit (push) Successful in 8s
Build / test (push) Successful in 14m18s

This commit is contained in:
Eugen Wissner 2024-11-23 21:07:19 +01:00
parent b5e6e3a2d6
commit dbba29a9c2
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
5 changed files with 54 additions and 9 deletions

View File

@ -5,7 +5,8 @@
-- | Contains data describing packages, methods to update them and to request -- | Contains data describing packages, methods to update them and to request
-- information about them. -- information about them.
module SlackBuilder.Package module SlackBuilder.Package
( Download(..) ( DataBaseEntry(..)
, Download(..)
, DownloadTemplate(..) , DownloadTemplate(..)
, PackageDescription(..) , PackageDescription(..)
, PackageUpdateData(..) , PackageUpdateData(..)
@ -66,3 +67,15 @@ data Updater = Updater
, is64 :: Bool , is64 :: Bool
, getVersion :: Text -> Text -> SlackBuilderT Download , getVersion :: Text -> Text -> SlackBuilderT Download
} }
data DataBaseEntry = DataBaseEntry
{ name :: Text
, version :: Text
, arch :: Text
, build :: Text
} deriving Eq
instance Show DataBaseEntry
where
show DataBaseEntry{..} = Text.unpack
$ Text.intercalate "-" [name, version, arch, build]

View File

@ -17,6 +17,7 @@ import SlackBuilder.LatestVersionCheck
import SlackBuilder.Update import SlackBuilder.Update
import qualified Toml import qualified Toml
import Data.Text (Text) import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.IO as Text import qualified Data.Text.IO as Text
import Control.Monad.Trans.Reader (ReaderT(..), asks) import Control.Monad.Trans.Reader (ReaderT(..), asks)
import SlackBuilder.Package (PackageDescription(..), renderTextWithVersion) import SlackBuilder.Package (PackageDescription(..), renderTextWithVersion)
@ -32,6 +33,8 @@ import System.Console.ANSI
) )
import Data.Maybe (mapMaybe) import Data.Maybe (mapMaybe)
import qualified Text.URI as URI import qualified Text.URI as URI
import System.Directory (listDirectory)
import qualified Data.HashMap.Strict as HashMap
autoUpdatable :: [PackageSettings] -> [PackageDescription] autoUpdatable :: [PackageSettings] -> [PackageDescription]
autoUpdatable = mapMaybe go autoUpdatable = mapMaybe go
@ -97,6 +100,28 @@ check = SlackBuilderT (asks (getField @"packages"))
>>= mapM_ checkUpdateAvailability >>= mapM_ checkUpdateAvailability
>> liftIO (putStrLn "") >> liftIO (putStrLn "")
installed :: SlackBuilderT ()
installed = do
listing <- listRepository
database <- foldr createDataBase HashMap.empty . mapMaybe createEntry
<$> liftIO (listDirectory "/var/lib/pkgtools/packages")
liftIO $ traverse_ print $ HashMap.intersection database listing
where
createDataBase entry@Package.DataBaseEntry{ name } =
HashMap.insert name entry
createEntry filename = createEntryFromChunks
$ Text.split (== '-')
$ Text.reverse
$ Text.pack filename
createEntryFromChunks (build : arch : version : name) = Just
Package.DataBaseEntry
{ arch = Text.reverse arch
, build = Text.reverse build
, version = Text.reverse version
, name = Text.reverse (Text.intercalate "-" name)
}
createEntryFromChunks _ = Nothing
main :: IO () main :: IO ()
main = execParser slackBuilderParser main = execParser slackBuilderParser
>>= handle handleException . withCommandLine >>= handle handleException . withCommandLine
@ -116,3 +141,4 @@ main = execParser slackBuilderParser
executeCommand = \case executeCommand = \case
CheckCommand -> check CheckCommand -> check
Up2DateCommand packageName -> up2Date packageName Up2DateCommand packageName -> up2Date packageName
InstalledCommand -> installed

View File

@ -25,6 +25,7 @@ import Options.Applicative
data SlackBuilderCommand data SlackBuilderCommand
= CheckCommand = CheckCommand
| Up2DateCommand (Maybe Text) | Up2DateCommand (Maybe Text)
| InstalledCommand
slackBuilderParser :: ParserInfo SlackBuilderCommand slackBuilderParser :: ParserInfo SlackBuilderCommand
slackBuilderParser = info slackBuilderCommand fullDesc slackBuilderParser = info slackBuilderCommand fullDesc
@ -33,7 +34,9 @@ slackBuilderCommand :: Parser SlackBuilderCommand
slackBuilderCommand = subparser slackBuilderCommand = subparser
$ command "check" (info checkCommand mempty) $ command "check" (info checkCommand mempty)
<> command "up2date" (info up2DateCommand mempty) <> command "up2date" (info up2DateCommand mempty)
<> command "installed" (info installedCommand mempty)
where where
checkCommand = pure CheckCommand checkCommand = pure CheckCommand
up2DateCommand = Up2DateCommand up2DateCommand = Up2DateCommand
<$> optional (argument str (metavar "PKGNAM")) <$> optional (argument str (metavar "PKGNAM"))
installedCommand = pure InstalledCommand

View File

@ -8,6 +8,7 @@ module SlackBuilder.Update
, downloadWithTemplate , downloadWithTemplate
, getAndLogLatest , getAndLogLatest
, handleException , handleException
, listRepository
, repackageWithTemplate , repackageWithTemplate
, reuploadWithTemplate , reuploadWithTemplate
, updatePackageIfRequired , updatePackageIfRequired
@ -19,6 +20,8 @@ import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Trans.Reader (asks) import Control.Monad.Trans.Reader (asks)
import qualified Data.ByteString as ByteString import qualified Data.ByteString as ByteString
import Data.Foldable (Foldable(..), find) import Data.Foldable (Foldable(..), find)
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
import qualified Data.List.NonEmpty as NonEmpty import qualified Data.List.NonEmpty as NonEmpty
import Data.Maybe (fromJust, fromMaybe) import Data.Maybe (fromJust, fromMaybe)
import Data.Text (Text) import Data.Text (Text)
@ -74,8 +77,7 @@ getAndLogLatest description = do
let PackageDescription{ latest = Package.Updater{ detectLatest }, name } = description let PackageDescription{ latest = Package.Updater{ detectLatest }, name } = description
liftIO (putStrLn $ Text.unpack name <> ": Retreiving the latest version.") liftIO (putStrLn $ Text.unpack name <> ": Retreiving the latest version.")
detectedVersion <- detectLatest detectedVersion <- detectLatest
category <- fmap Text.pack category <- HashMap.lookup name <$> listRepository
<$> findCategory (Text.unpack name)
pure $ PackageUpdateData description pure $ PackageUpdateData description
<$> category <$> category
<*> detectedVersion <*> detectedVersion
@ -252,19 +254,20 @@ updatePackage PackageUpdateData{..} info = do
commit packagePath version commit packagePath version
findCategory :: FilePath -> SlackBuilderT (Maybe FilePath) listRepository :: SlackBuilderT (HashMap Text Text)
findCategory packageName = do listRepository = do
repository' <- SlackBuilderT $ asks repository repository' <- SlackBuilderT $ asks repository
go repository' [] "" <&> fmap fst . find ((packageName ==) . snd) listing <- go repository' [] ""
pure $ HashMap.fromList $ bimap Text.pack Text.pack <$> listing
where where
go currentDirectory found accumulatedDirectory = do go currentDirectory found accumulatedDirectory = do
let fullDirectory = currentDirectory </> accumulatedDirectory let fullDirectory = currentDirectory </> accumulatedDirectory
contents <- liftIO $ listDirectory fullDirectory contents <- liftIO $ listDirectory fullDirectory
case find (isSuffixOf ".info") contents of case find (isSuffixOf ".info") contents of
Just _ -> Just _ ->
let result = first dropTrailingPathSeparator let (category, packageName) = first dropTrailingPathSeparator
$ splitFileName accumulatedDirectory $ splitFileName accumulatedDirectory
in pure $ result : found in pure $ (packageName, category) : found
Nothing -> Nothing ->
let accumulatedDirectories = (accumulatedDirectory </>) let accumulatedDirectories = (accumulatedDirectory </>)
<$> filter (not . isPrefixOf ".") contents <$> filter (not . isPrefixOf ".") contents