aura 2.0.6 → 2.1.0
raw patch · 19 files changed
+122/−90 lines, 19 filesdep −compactabledep ~algebraic-graphsdep ~megaparsecdep ~prettyprinterPVP ok
version bump matches the API change (PVP)
Dependencies removed: compactable
Dependency ranges changed: algebraic-graphs, megaparsec, prettyprinter
API changes (from Hackage documentation)
+ Aura.Commands.A: fetchTarball :: NESet PkgName -> RIO Env ()
+ Aura.Utils: fmapEither :: (a -> Either b c) -> [a] -> ([b], [c])
+ Aura.Utils: traverseEither :: Applicative f => (a -> f (Either b c)) -> [a] -> f ([b], [c])
+ Aura.Utils: traverseMaybe :: Applicative f => (a -> f (Maybe b)) -> [a] -> f [b]
Files
- CHANGELOG.md +4/−0
- aura.cabal +4/−5
- exec/Flags.hs +5/−3
- exec/Settings.hs +0/−1
- exec/aura.hs +2/−1
- lib/Aura/Build.hs +1/−3
- lib/Aura/Commands/A.hs +22/−5
- lib/Aura/Commands/B.hs +3/−3
- lib/Aura/Commands/C.hs +8/−8
- lib/Aura/Commands/L.hs +3/−4
- lib/Aura/Core.hs +3/−6
- lib/Aura/Dependencies.hs +1/−2
- lib/Aura/Install.hs +7/−9
- lib/Aura/Languages.hs +22/−19
- lib/Aura/MakePkg.hs +1/−1
- lib/Aura/Packages/AUR.hs +4/−7
- lib/Aura/Packages/Repository.hs +1/−3
- lib/Aura/State.hs +8/−10
- lib/Aura/Utils.hs +23/−0
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Aura Changelog +## 2.1.0 (2020-02-17)++- Reinstated `-Aw`, which downloads a snapshot tarball of an AUR package.+ ## 2.0.6 (2020-02-16) - Fixed the broken `-S`.
aura.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: aura-version: 2.0.6+version: 2.1.0 synopsis: A secure package manager for Arch Linux and the AUR, written in Haskell. @@ -48,7 +48,7 @@ , errors ^>=2.3 , http-client >=0.5 && <0.7 , nonempty-containers ^>=0.3- , prettyprinter >=1.2 && <1.6+ , prettyprinter >=1.2 && <1.7 , prettyprinter-ansi-terminal ^>=1.1 , transformers ^>=0.5 , typed-process ^>=0.2@@ -89,14 +89,13 @@ build-depends: , aeson >=1.2 && <1.5 , aeson-pretty ^>=0.8- , algebraic-graphs >=0.1 && <0.5+ , algebraic-graphs >=0.1 && <0.6 , aur ^>=6.3- , compactable ^>=0.1 , filepath ^>=1.4 , generic-lens >=1.1 && <1.3 , http-types >=0.9 && <0.13 , language-bash ^>=0.8- , megaparsec ^>=7+ , megaparsec >=7 && <9 , microlens-ghc ^>=0.4 , mwc-random ^>=0.14 , network-uri ^>=2.6
exec/Flags.hs view
@@ -11,13 +11,13 @@ import Aura.Pacman (defaultLogFile, pacmanConfFile) import Aura.Settings import Aura.Types-import qualified Data.List.NonEmpty as NEL import Data.Set.NonEmpty (NESet) import qualified Data.Set.NonEmpty as NES-import Lens.Micro+import Lens.Micro (Traversal') import Options.Applicative import RIO hiding (exp, log) import RIO.List.Partial (foldr1)+import qualified RIO.NonEmpty.Partial as NEL import qualified RIO.Set as S import qualified RIO.Text as T import System.Path (Absolute, Path, fromAbsoluteFilePath, toFilePath)@@ -227,6 +227,7 @@ | AurSearch Text | AurUpgrade (Set PkgName) | AurJson (NESet PkgName)+ | AurTarball (NESet PkgName) deriving (Show) data AurSwitch = AurIgnore (Set PkgName)@@ -268,13 +269,14 @@ <*> (S.fromList <$> many switches) ) where bigA = flag' () (long "aursync" <> short 'A' <> help "Install packages from the AUR.")- mods = ds <|> ainfo <|> pkgb <|> search <|> upgrade <|> aur+ mods = ds <|> ainfo <|> pkgb <|> search <|> upgrade <|> aur <|> tarball ds = AurDeps <$> (flag' () (long "deps" <> short 'd' <> hidden <> help "View dependencies of an AUR package.") *> somePkgs') ainfo = AurInfo <$> (flag' () (long "info" <> short 'i' <> hidden <> help "View AUR package information.") *> somePkgs') pkgb = AurPkgbuild <$> (flag' () (long "pkgbuild" <> short 'p' <> hidden <> help "View an AUR package's PKGBUILD file.") *> somePkgs') search = AurSearch <$> strOption (long "search" <> short 's' <> metavar "STRING" <> hidden <> help "Search the AUR via a search string.") upgrade = AurUpgrade <$> (flag' () (long "sysupgrade" <> short 'u' <> hidden <> help "Upgrade all installed AUR packages.") *> fmap (S.map PkgName) manyArgs') aur = AurJson <$> (flag' () (long "json" <> hidden <> help "Retrieve package JSON straight from the AUR.") *> somePkgs')+ tarball = AurTarball <$> (flag' () (long "downloadonly" <> short 'w' <> hidden <> help "Download a package tarball.") *> somePkgs') switches = ign <|> igg ign = AurIgnore . S.fromList . map PkgName . T.split (== ',') <$> strOption (long "ignore" <> metavar "PKG(,PKG,...)" <> hidden <> help "Ignore given packages.")
exec/Settings.hs view
@@ -27,7 +27,6 @@ import Aura.Types import Aura.Utils import Control.Error.Util (failWith)-import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Except import Data.Bifunctor (Bifunctor(..)) import qualified Data.Set.NonEmpty as NES
exec/aura.hs view
@@ -117,6 +117,7 @@ Left (AurSearch s) -> A.aurPkgSearch s Left (AurUpgrade ps) -> bool (trueRoot . sudo) id (switch ss DryRun) $ A.upgradeAURPkgs ps Left (AurJson ps) -> A.aurJson ps+ Left (AurTarball ps) -> A.fetchTarball ps Right (Backup o) -> case o of Nothing -> sudo . liftIO $ B.saveState ss@@ -157,4 +158,4 @@ viewConfFile :: RIO Env () viewConfFile = do pth <- asks (either id id . configPathOf . commonConfigOf . settings)- liftIO . void . runProcess @IO $ proc "less" [toFilePath pth]+ void . runProcess $ proc "less" [toFilePath pth]
lib/Aura/Build.hs view
@@ -25,16 +25,14 @@ import Aura.Settings import Aura.Types import Aura.Utils-import Control.Compactable (traverseMaybe)-import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Except import Data.Generics.Product (field)-import qualified Data.List.NonEmpty as NEL import Data.Semigroup.Foldable (fold1) import Data.Set.NonEmpty (NESet) import qualified Data.Set.NonEmpty as NES import RIO import RIO.Directory (setCurrentDirectory)+import qualified RIO.NonEmpty as NEL import qualified RIO.Set as S import qualified RIO.Text as T import System.Path
lib/Aura/Commands/A.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE MonoLocalBinds #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE OverloadedStrings #-}@@ -24,6 +25,7 @@ , I.displayPkgDeps , displayPkgbuild , aurJson+ , fetchTarball ) where import Aura.Colour@@ -39,7 +41,6 @@ import Control.Error.Util (hush) import Data.Aeson.Encode.Pretty (encodePretty) import Data.Generics.Product (field)-import qualified Data.List.NonEmpty as NEL import Data.Set.NonEmpty (NESet) import qualified Data.Set.NonEmpty as NES import Data.Text.Prettyprint.Doc@@ -51,8 +52,9 @@ import RIO import qualified RIO.ByteString as B import qualified RIO.ByteString.Lazy as BL-import RIO.List (intersperse)+import qualified RIO.List as L import RIO.List.Partial (maximum)+import qualified RIO.NonEmpty as NEL import qualified RIO.Set as S import qualified RIO.Text as T import RIO.Text.Partial (splitOn)@@ -158,7 +160,7 @@ verboseInfo = repo <> n <+> v <+> "(" <> l <+> "|" <+> p <> ")" <> (if e then annotate bold " [installed]" else "") <> "\n " <> d repo = magenta "aur/"- n = fold . intersperse (bCyan $ pretty r) . map (annotate bold . pretty) . splitOn r $ aurNameOf i+ n = fold . L.intersperse (bCyan $ pretty r) . map (annotate bold . pretty) . splitOn r $ aurNameOf i d = maybe "(null)" pretty $ aurDescriptionOf i l = yellow . pretty $ aurVotesOf i -- `l` for likes? p = yellow . pretty . T.pack . printf "%0.2f" $ popularityOf i@@ -171,7 +173,7 @@ displayPkgbuild ps = do man <- asks (managerOf . settings) pbs <- catMaybes <$> traverse (liftIO . getPkgbuild man) (toList ps)- liftIO . traverse_ (\p -> B.putStr @IO p >> B.putStr "\n") $ pbs ^.. each . field @"pkgbuild"+ traverse_ (\p -> B.putStr p >> B.putStr "\n") $ pbs ^.. each . field @"pkgbuild" isntMostRecent :: (AurInfo, Versioning) -> Bool isntMostRecent (ai, v) = trueVer > Just v@@ -182,10 +184,25 @@ aurJson ps = do m <- asks (managerOf . settings) infos <- liftMaybeM (Failure connectionFailure_1) . fmap hush . liftIO $ f m ps- liftIO $ traverse_ (BL.putStrLn @IO . encodePretty) infos+ traverse_ (BL.putStrLn . encodePretty) infos where f :: Manager -> NESet PkgName -> IO (Either ClientError [AurInfo]) f m = info m . (^.. each . field @"name") . toList++-- | @https://aur.archlinux.org/cgit/aur.git/snapshot/aura-bin.tar.gz@+fetchTarball :: NESet PkgName -> RIO Env ()+fetchTarball ps = do+ ss <- asks settings+ traverse_ (liftIO . g ss) ps+ where+ f :: PkgName -> String+ f (PkgName p) =+ "https://aur.archlinux.org/cgit/aur.git/snapshot/" <> T.unpack p <> ".tar.gz"++ g :: Settings -> PkgName -> IO ()+ g ss p@(PkgName pn) = urlContents (managerOf ss) (f p) >>= \case+ Nothing -> warn ss . missingPkg_5 p $ langOf ss+ Just bs -> writeFileBinary (T.unpack pn <> ".tar.gz") bs ------------ -- REPORTING
lib/Aura/Commands/B.hs view
@@ -24,9 +24,9 @@ import Aura.Settings import Aura.State import Aura.Utils (optionalPrompt, putTextLn)-import qualified Data.List.NonEmpty as NEL import RIO-import RIO.List (partition)+import qualified RIO.List as L+import qualified RIO.NonEmpty as NEL import qualified RIO.Text as T import System.Path (takeFileName, toFilePath, toUnrootedFilePath) import System.Path.IO (removeFile)@@ -37,7 +37,7 @@ cleanStates :: Settings -> Word -> IO () cleanStates ss (fromIntegral -> n) = do stfs <- reverse <$> getStateFiles- (pinned, others) <- partition p <$> traverse (\sf -> (sf,) <$> readState sf) stfs+ (pinned, others) <- L.partition p <$> traverse (\sf -> (sf,) <$> readState sf) stfs warn ss . cleanStates_4 (length stfs) $ langOf ss unless (null pinned) . warn ss . cleanStates_6 (length pinned) $ langOf ss forM_ (NEL.nonEmpty stfs) $ \stfs' -> do
lib/Aura/Commands/C.hs view
@@ -32,13 +32,13 @@ import Aura.Types import Aura.Utils import Data.Generics.Product (field)-import Data.List.NonEmpty (nonEmpty) import Data.Set.NonEmpty (NESet) import qualified Data.Set.NonEmpty as NES import Lens.Micro ((^?), _Just) import RIO-import RIO.List (groupBy, sort, (\\))+import qualified RIO.List as L import qualified RIO.Map as M+import qualified RIO.NonEmpty as NEL import qualified RIO.Set as S import qualified RIO.Text as T import System.Path@@ -53,7 +53,7 @@ ss <- asks settings let cachePath = either id id . cachePathOf $ commonConfigOf ss reals <- liftIO $ pkgsInCache ss pkgs- traverse_ (report red reportBadDowngradePkgs_1) . nonEmpty . toList $ NES.toSet pkgs S.\\ reals+ traverse_ (report red reportBadDowngradePkgs_1) . NEL.nonEmpty . toList $ NES.toSet pkgs S.\\ reals unless (null reals) $ do cache <- liftIO $ cacheContents cachePath choices <- traverse (getDowngradeChoice cache) $ toList reals@@ -63,7 +63,7 @@ -- downgrade to. getDowngradeChoice :: Cache -> PkgName -> RIO Env PackagePath getDowngradeChoice cache pkg =- case nonEmpty $ getChoicesFromCache cache pkg of+ case NEL.nonEmpty $ getChoicesFromCache cache pkg of Nothing -> throwM . Failure $ reportBadDowngradePkgs_2 pkg Just choices -> do ss <- asks settings@@ -71,14 +71,14 @@ liftIO $ getSelection (T.pack . toFilePath . path) choices getChoicesFromCache :: Cache -> PkgName -> [PackagePath]-getChoicesFromCache (Cache cache) p = sort . M.elems $ M.filterWithKey (\(SimplePkg pn _) _ -> p == pn) cache+getChoicesFromCache (Cache cache) p = L.sort . M.elems $ M.filterWithKey (\(SimplePkg pn _) _ -> p == pn) cache -- | Print all package filenames that match a given `Text`. searchCache :: Text -> RIO Env () searchCache ps = do ss <- asks settings matches <- liftIO $ cacheMatches ss ps- liftIO . traverse_ (putTextLn . T.pack . toFilePath . path) $ sort matches+ liftIO . traverse_ (putTextLn . T.pack . toFilePath . path) $ L.sort matches -- | The destination folder must already exist for the back-up to begin. backupCache :: Path Absolute -> RIO Env ()@@ -135,7 +135,7 @@ (Cache cache) <- liftIO $ cacheContents cachePath let !files = M.elems cache grouped = take toSave . reverse <$> groupByName files- toRemove = files \\ fold grouped+ toRemove = files L.\\ fold grouped liftIO $ traverse_ (removeFile . path) toRemove -- | Only package files with a version not in any PkgState will be@@ -154,6 +154,6 @@ -- | Typically takes the contents of the package cache as an argument. groupByName :: [PackagePath] -> [[PackagePath]]-groupByName pkgs = groupBy sameBaseName $ sort pkgs+groupByName pkgs = L.groupBy sameBaseName $ L.sort pkgs where sameBaseName a b = baseName a == baseName b baseName p = simplepkg p ^? _Just . field @"name"
lib/Aura/Commands/L.hs view
@@ -25,12 +25,11 @@ import Aura.Settings import Aura.Types (PkgName(..)) import Aura.Utils-import Control.Compactable (fmapEither) import Data.Generics.Product (field)-import qualified Data.List.NonEmpty as NEL import Data.Set.NonEmpty (NESet) import Data.Text.Prettyprint.Doc import RIO hiding (FilePath)+import qualified RIO.NonEmpty as NEL import qualified RIO.Text as T import qualified RIO.Text.Partial as T import System.Path (toFilePath)@@ -51,7 +50,7 @@ viewLogFile :: RIO Env () viewLogFile = do pth <- asks (toFilePath . either id id . logPathOf . commonConfigOf . settings)- liftIO . void . runProcess @IO $ proc "less" [pth]+ void . runProcess $ proc "less" [pth] -- | Print all lines in the log file which contain a given `Text`. searchLogFile :: Settings -> Text -> IO ()@@ -65,7 +64,7 @@ logInfoOnPkg pkgs = do ss <- asks settings let pth = toFilePath . either id id . logPathOf $ commonConfigOf ss- logFile <- Log . T.lines . decodeUtf8Lenient <$> liftIO (readFileBinary @IO pth)+ logFile <- Log . T.lines . decodeUtf8Lenient <$> readFileBinary pth let (bads, goods) = fmapEither (logLookup logFile) $ toList pkgs traverse_ (report red reportNotInLog_1) $ NEL.nonEmpty bads liftIO . traverse_ putTextLn $ map (renderEntry ss) goods
lib/Aura/Core.hs view
@@ -39,21 +39,18 @@ import Aura.Settings import Aura.Types import Aura.Utils-import Control.Compactable (fmapEither) import Control.Monad.Trans.Maybe import Data.Bifunctor (bimap) import Data.Generics.Product (field)-import Data.List.NonEmpty (NonEmpty)-import qualified Data.List.NonEmpty as NEL import Data.Set.NonEmpty (NESet) import qualified Data.Set.NonEmpty as NES import Data.Text.Prettyprint.Doc import Data.Text.Prettyprint.Doc.Render.Terminal import Data.These (These(..))-import Lens.Micro ((^.)) import RIO hiding ((<>)) import qualified RIO.ByteString as B-import RIO.List (unzip)+import qualified RIO.List as L+import qualified RIO.NonEmpty as NEL import qualified RIO.Set as S import qualified RIO.Text as T import System.Path.IO (doesFileExist)@@ -94,7 +91,7 @@ -- there is no way to guarantee that the list of `NESet`s will itself be -- non-empty. partitionPkgs :: NonEmpty (NESet Package) -> ([Prebuilt], [NESet Buildable])-partitionPkgs = bimap fold f . unzip . map g . toList+partitionPkgs = bimap fold f . L.unzip . map g . toList where g = fmapEither toEither . toList f = mapMaybe (fmap NES.fromList . NEL.nonEmpty) toEither (FromAUR b) = Right b
lib/Aura/Dependencies.hs view
@@ -31,8 +31,6 @@ import Aura.Utils (maybe', putText) import Control.Error.Util (note) import Data.Generics.Product (field)-import Data.List.NonEmpty (NonEmpty)-import qualified Data.List.NonEmpty as NEL import Data.Semigroup.Foldable (foldMap1) import Data.Set.NonEmpty (pattern IsEmpty, pattern IsNonEmpty, NESet) import qualified Data.Set.NonEmpty as NES@@ -41,6 +39,7 @@ import Lens.Micro import RIO import qualified RIO.Map as M+import qualified RIO.NonEmpty as NEL import qualified RIO.Set as S import qualified RIO.Text as T
lib/Aura/Install.hs view
@@ -35,12 +35,9 @@ import Aura.Pkgbuild.Security import Aura.Settings import Aura.Types-import Aura.Utils (optionalPrompt, putTextLn)-import Control.Compactable (fmapEither)+import Aura.Utils (fmapEither, optionalPrompt, putTextLn) import Control.Scheduler (Comp(..), traverseConcurrently) import Data.Generics.Product (HasField'(..), field, super)-import Data.List.NonEmpty (NonEmpty)-import qualified Data.List.NonEmpty as NEL import Data.Semigroup.Foldable (fold1) import Data.Set.NonEmpty (NESet) import qualified Data.Set.NonEmpty as NES@@ -49,8 +46,9 @@ import Lens.Micro (each, (^..)) import RIO hiding (FilePath) import RIO.Directory (setCurrentDirectory)-import RIO.List (partition, sort)+import qualified RIO.List as L import qualified RIO.Map as M+import qualified RIO.NonEmpty as NEL import qualified RIO.Set as S import qualified RIO.Text as T import System.Path (fromAbsoluteFilePath)@@ -193,17 +191,17 @@ reportPkgsToInstall :: [Prebuilt] -> [NESet Buildable] -> RIO Env () reportPkgsToInstall rps bps = do- let (explicits, ds) = partition isExplicit $ foldMap toList bps+ let (explicits, ds) = L.partition isExplicit $ foldMap toList bps f reportPkgsToInstall_1 rps f reportPkgsToInstall_3 ds f reportPkgsToInstall_2 explicits where- f m xs = traverse_ (report green m) . NEL.nonEmpty . sort $ xs ^.. each . field @"name"+ f m xs = traverse_ (report green m) . NEL.nonEmpty . L.sort $ xs ^.. each . field @"name" reportListOfDeps :: [Prebuilt] -> [NESet Buildable] -> IO () reportListOfDeps rps bps = f rps *> f (foldMap toList bps) where f :: HasField' "name" s PkgName => [s] -> IO ()- f = traverse_ putTextLn . sort . (^.. each . field' @"name" . field' @"name")+ f = traverse_ putTextLn . L.sort . (^.. each . field' @"name" . field' @"name") pkgbuildDiffs :: Set Buildable -> RIO Env () pkgbuildDiffs ps = asks settings >>= check@@ -223,6 +221,6 @@ else liftIO $ do setCurrentDirectory "/tmp" let new = "/tmp/new.pb"- writeFileBinary @IO new $ p ^. field @"pkgbuild" . field @"pkgbuild"+ writeFileBinary new $ p ^. field @"pkgbuild" . field @"pkgbuild" liftIO . warn ss $ reportPkgbuildDiffs_3 pn lang diff ss (pkgbuildPath pn) $ fromAbsoluteFilePath new
lib/Aura/Languages.hs view
@@ -39,12 +39,11 @@ import qualified Aura.Languages.Fields as Fields import Aura.Types import Data.Generics.Product (field)-import Data.List.NonEmpty (NonEmpty) import Data.Ratio ((%)) import Data.Text.Prettyprint.Doc import Data.Text.Prettyprint.Doc.Render.Terminal import RIO-import RIO.List (intersperse)+import qualified RIO.List as L import qualified RIO.Map as M import qualified RIO.Map.Partial as M import qualified RIO.Text as T@@ -324,22 +323,22 @@ getRealPkgConflicts_2 :: PkgName -> Language -> Doc AnsiStyle getRealPkgConflicts_2 (bt . view (field @"name") -> p) = \case- Japanese -> p <> "は無視されるパッケージ!`pacman.conf`を参考に。"- Polish -> p <> " jest ignorowany! Sprawdź plik `pacman.conf`."- Croatian -> p <> " je ignoriran paket! Provjerite svoj `pacman.conf`."- Swedish -> p <> " är ett ignorerat paket! Kolla din `pacman.conf`-fil."- German -> p <> " ist ein ignoriertes Paket! Siehe /etc/pacman.conf."- Spanish -> "¡" <> p <> " es un paquete ignorado! Revisa tu fichero `pacman.conf`."- Portuguese -> p <> " é um pacote ignorado conforme configuração em `pacman.conf`!"- French -> "Le paquet " <> p <> " est ignoré. Vous devriez jeter un œil à votre `pacman.conf`."- Russian -> "Пакет " <> p <> " игнорируется! Проверьте ваш файл `pacman.conf`."- Italian -> p <> " è un pacchetto ignorato, controllare `pacman.conf`."- Serbian -> "Пакет " <> p <> " је игнорисан! Видите ваш фајл „pacman.conf“."- Norwegian -> p <> " er en ignorert pakke! Sjekk din `pacman.conf`-fil."- Indonesia -> p <> " merupakan paket yang diabaikan! Lihat `pacman.conf` anda."- Chinese -> p <> " 是一个被忽略的包!请查看你的 `pacman.conf` 文件。"- Esperanto -> p <> " estas malatenta pakaĵo! Vidu vian `pacman.conf` dosieron."- _ -> p <> " is an ignored package! See your `pacman.conf` file."+ Japanese -> p <> "は無視されるパッケージ!`pacman.conf`を参考に。"+ Polish -> p <> " jest ignorowany! Sprawdź plik `pacman.conf`."+ Croatian -> p <> " je ignoriran paket! Provjerite svoj `pacman.conf`."+ Swedish -> p <> " är ett ignorerat paket! Kolla din `pacman.conf`-fil."+ German -> p <> " ist ein ignoriertes Paket! Siehe /etc/pacman.conf."+ Spanish -> "¡" <> p <> " es un paquete ignorado! Revisa tu fichero `pacman.conf`."+ Portuguese -> p <> " é um pacote ignorado conforme configuração em `pacman.conf`!"+ French -> "Le paquet " <> p <> " est ignoré. Vous devriez jeter un œil à votre `pacman.conf`."+ Russian -> "Пакет " <> p <> " игнорируется! Проверьте ваш файл `pacman.conf`."+ Italian -> p <> " è un pacchetto ignorato, controllare `pacman.conf`."+ Serbian -> "Пакет " <> p <> " је игнорисан! Видите ваш фајл „pacman.conf“."+ Norwegian -> p <> " er en ignorert pakke! Sjekk din `pacman.conf`-fil."+ Indonesia -> p <> " merupakan paket yang diabaikan! Lihat `pacman.conf` anda."+ Chinese -> p <> " 是一个被忽略的包!请查看你的 `pacman.conf` 文件。"+ Esperanto -> p <> " estas malatenta pakaĵo! Vidu vian `pacman.conf` dosieron."+ _ -> p <> " is an ignored package! See your `pacman.conf` file." missingPkg_2 :: [DepError] -> Language -> Doc AnsiStyle missingPkg_2 ps l = vsep $ map (depError l) ps@@ -369,7 +368,11 @@ missingPkg_4 pns = \case Spanish -> vsep $ "Se detectaron los siguientes ciclos de dependencia:" : pns' _ -> vsep $ "The following dependency cycles were detected:" : pns'- where pns' = map (hsep . map pretty . intersperse "=>" . map (view (field @"name")) . toList) pns+ where pns' = map (hsep . map pretty . L.intersperse "=>" . map (view (field @"name")) . toList) pns++missingPkg_5 :: PkgName -> Language -> Doc AnsiStyle+missingPkg_5 (PkgName p) = \case+ _ -> bt p <> " does not exist." ----------------- -- aura functions
lib/Aura/MakePkg.hs view
@@ -20,12 +20,12 @@ import Aura.Types import Aura.Utils (optionalPrompt) import Control.Error.Util (note)-import qualified Data.List.NonEmpty as NEL import Data.Set.NonEmpty (NESet) import qualified Data.Set.NonEmpty as NES import Lens.Micro (_2) import RIO import qualified RIO.ByteString.Lazy as BL+import qualified RIO.NonEmpty as NEL import qualified RIO.Text as T import System.Path (Absolute, Path, fromAbsoluteFilePath, toFilePath, (</>))
lib/Aura/Packages/AUR.hs view
@@ -32,15 +32,11 @@ import Aura.Pkgbuild.Fetch import Aura.Settings import Aura.Types-import Control.Compactable (fmapEither)-import Control.Concurrent.STM.TVar (modifyTVar')+import Aura.Utils (fmapEither) import Control.Error.Util (hush, note)-import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Maybe import Control.Scheduler (Comp(..), traverseConcurrently) import Data.Generics.Product (field)-import Data.List.NonEmpty (NonEmpty)-import qualified Data.List.NonEmpty as NEL import Data.Set.NonEmpty (NESet) import qualified Data.Set.NonEmpty as NES import Data.Versions (versioning)@@ -48,8 +44,9 @@ import Linux.Arch.Aur import Network.HTTP.Client (Manager) import RIO-import RIO.List (sortBy)+import qualified RIO.List as L import qualified RIO.Map as M+import qualified RIO.NonEmpty as NEL import qualified RIO.Set as S import qualified RIO.Text as T import System.Path@@ -140,7 +137,7 @@ -- RPC CALLS ------------ sortAurInfo :: Maybe BuildSwitch -> [AurInfo] -> [AurInfo]-sortAurInfo bs ai = sortBy compare' ai+sortAurInfo bs ai = L.sortBy compare' ai where compare' = case bs of Just SortAlphabetically -> compare `on` aurNameOf _ -> \x y -> compare (aurVotesOf y) (aurVotesOf x)
lib/Aura/Packages/Repository.hs view
@@ -22,12 +22,10 @@ import Aura.Pacman (pacmanLines, pacmanOutput) import Aura.Settings (CommonSwitch(..), Settings(..), shared) import Aura.Types-import Aura.Utils (getSelection)-import Control.Compactable (fmapEither, traverseEither)+import Aura.Utils (fmapEither, getSelection, traverseEither) import Control.Error.Util (hush, note) import Control.Scheduler (Comp(..), traverseConcurrently) import Data.Generics.Product (field)-import Data.List.NonEmpty (NonEmpty(..)) import qualified Data.Set.NonEmpty as NES import Data.Versions import RIO hiding (try)
lib/Aura/State.hs view
@@ -30,19 +30,17 @@ import Aura.Settings import Aura.Types import Aura.Utils-import Control.Compactable (fmapMaybe) import Control.Error.Util (hush) import Data.Aeson import Data.Generics.Product (field)-import Data.List.NonEmpty (NonEmpty, nonEmpty) import Data.Versions-import Lens.Micro ((^.)) import RIO import qualified RIO.ByteString.Lazy as BL-import RIO.List (intercalate, partition, sort)+import qualified RIO.List as L import RIO.List.Partial ((!!)) import qualified RIO.Map as M import qualified RIO.Map.Unchecked as M+import qualified RIO.NonEmpty as NEL import qualified RIO.Text as T import RIO.Time import System.Path@@ -69,7 +67,7 @@ <$> v .: "time" <*> v .: "pinned" <*> fmap f (v .: "packages")- where f = fmapMaybe (hush . versioning)+ where f = M.mapMaybe (hush . versioning) data StateDiff = StateDiff { _toAlter :: ![SimplePkg]@@ -112,7 +110,7 @@ getStateFiles :: IO [Path Absolute] getStateFiles = do createDirectoryIfMissing True stateCache- sort . map (stateCache </>) <$> getDirectoryContents stateCache+ L.sort . map (stateCache </>) <$> getDirectoryContents stateCache -- | Save a package state. -- In writing the first state file, the `states` directory is created automatically.@@ -125,7 +123,7 @@ notify ss . saveState_1 $ langOf ss dotFormat :: ZonedTime -> String-dotFormat (ZonedTime t _) = intercalate "." items+dotFormat (ZonedTime t _) = L.intercalate "." items where items = [ show ye , printf "%02d(%s)" mo (mnths !! (mo - 1)) , printf "%02d" da@@ -139,7 +137,7 @@ -- | Does its best to restore a state chosen by the user. restoreState :: RIO Env () restoreState =- liftIO getStateFiles >>= maybe (throwM $ Failure restoreState_2) f . nonEmpty+ liftIO getStateFiles >>= maybe (throwM $ Failure restoreState_2) f . NEL.nonEmpty where f :: NonEmpty (Path Absolute) -> RIO Env () f sfs = do ss <- asks settings@@ -151,8 +149,8 @@ curr <- liftIO currentState Cache cache <- liftIO $ cacheContents pth let StateDiff rein remo = compareStates past curr- (okay, nope) = partition (`M.member` cache) rein- traverse_ (report red restoreState_1 . fmap (^. field @"name")) $ nonEmpty nope+ (okay, nope) = L.partition (`M.member` cache) rein+ traverse_ (report red restoreState_1 . fmap (^. field @"name")) $ NEL.nonEmpty nope reinstallAndRemove (mapMaybe (`M.lookup` cache) okay) remo selectState :: NonEmpty (Path Absolute) -> IO (Path Absolute)
lib/Aura/Utils.hs view
@@ -32,6 +32,9 @@ , getSelection -- * Misc. , maybe'+ , fmapEither+ , traverseMaybe+ , traverseEither ) where import Aura.Colour@@ -228,3 +231,23 @@ -- | `maybe` with the function at the end. maybe' :: b -> Maybe a -> (a -> b) -> b maybe' zero m f = maybe zero f m++-- | Borrowed from Compactable.+fmapEither :: (a -> Either b c) -> [a] -> ([b], [c])+fmapEither f = foldl' (deal f) ([],[])+ where+ deal :: (a -> Either b c) -> ([b], [c]) -> a -> ([b], [c])+ deal g ~(bs, cs) a = case g a of+ Left b -> (b:bs, cs)+ Right c -> (bs, c:cs)++-- | Borrowed from Compactable.+traverseMaybe :: Applicative f => (a -> f (Maybe b)) -> [a] -> f [b]+traverseMaybe f = go+ where+ go (x:xs) = maybe id (:) <$> f x <*> go xs+ go [] = pure []++-- | Borrowed from Compactable.+traverseEither :: Applicative f => (a -> f (Either b c)) -> [a] -> f ([b], [c])+traverseEither f = fmap partitionEithers . traverse f