{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

module Repology where

import Data.Aeson
import Data.HashMap.Strict
import Data.List
import Data.Proxy
import qualified Data.Text as T
import qualified Data.Text.IO
import qualified Data.Vector as V
import GHC.Generics
import Network.HTTP.Client.TLS (newTlsManager)
import OurPrelude
import Servant.API
import Servant.Client (BaseUrl (..), mkClientEnv, ClientM, Scheme (..), client, runClientM)
import System.IO

baseUrl :: BaseUrl
baseUrl :: BaseUrl
baseUrl = Scheme -> String -> Int -> String -> BaseUrl
BaseUrl Scheme
Https String
"repology.org" Int
443 String
"/api/v1"

type Metapackage = Vector Package

compareMetapackage :: Metapackage -> Metapackage -> Ordering
compareMetapackage :: Metapackage -> Metapackage -> Ordering
compareMetapackage Metapackage
ps1 Metapackage
ps2 = Maybe Package -> Maybe Package -> Ordering
compareMetapackage' (Metapackage
ps1 Metapackage -> Int -> Maybe Package
forall a. Vector a -> Int -> Maybe a
V.!? Int
0) (Metapackage
ps2 Metapackage -> Int -> Maybe Package
forall a. Vector a -> Int -> Maybe a
V.!? Int
0)
  where
    compareMetapackage' :: Maybe Package -> Maybe Package -> Ordering
compareMetapackage' (Just Package
p1) (Just Package
p2) = Maybe Text -> Maybe Text -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Package -> Maybe Text
name Package
p1) (Package -> Maybe Text
name Package
p2)
    compareMetapackage' Maybe Package
Nothing (Just Package
_) = Ordering
LT
    compareMetapackage' (Just Package
_) Maybe Package
Nothing = Ordering
GT
    compareMetapackage' Maybe Package
_ Maybe Package
_ = Ordering
EQ

type Metapackages = HashMap Text Metapackage

type API =
  "metapackage" :> Capture "metapackage_name" Text :> Get '[JSON] Metapackage :<|> "metapackages" :> QueryParam "search" Text :> QueryParam "maintainers" Text :> QueryParam "category" Text :> QueryParam "inrepo" Text :> QueryParam "outdated" Bool :> QueryParam "notinrepo" Text :> QueryParam "minspread" Integer :> QueryParam "maxspread" Integer :> Get '[JSON] Metapackages :<|> "metapackages" :> Capture "name" Text :> QueryParam "search" Text :> QueryParam "maintainers" Text :> QueryParam "category" Text :> QueryParam "inrepo" Text :> QueryParam "outdated" Bool :> QueryParam "notinrepo" Text :> QueryParam "minspread" Integer :> QueryParam "maxspread" Integer :> Get '[JSON] Metapackages

data Package = Package
  { Package -> Text
repo :: Text,
    Package -> Maybe Text
name :: Maybe Text,
    Package -> Text
version :: Text,
    Package -> Maybe Text
origversion :: Maybe Text,
    Package -> Maybe Text
status :: Maybe Text,
    Package -> Maybe Text
summary :: Maybe Text,
    Package -> Maybe (Vector Text)
categories :: Maybe (Vector Text),
    Package -> Maybe (Vector Text)
licenses :: Maybe (Vector Text),
    Package -> Maybe (Vector Text)
www :: Maybe (Vector Text),
    Package -> Maybe (Vector Text)
downloads :: Maybe (Vector Text)
  }
  deriving (Package -> Package -> Bool
(Package -> Package -> Bool)
-> (Package -> Package -> Bool) -> Eq Package
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Package -> Package -> Bool
$c/= :: Package -> Package -> Bool
== :: Package -> Package -> Bool
$c== :: Package -> Package -> Bool
Eq, Int -> Package -> ShowS
[Package] -> ShowS
Package -> String
(Int -> Package -> ShowS)
-> (Package -> String) -> ([Package] -> ShowS) -> Show Package
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Package] -> ShowS
$cshowList :: [Package] -> ShowS
show :: Package -> String
$cshow :: Package -> String
showsPrec :: Int -> Package -> ShowS
$cshowsPrec :: Int -> Package -> ShowS
Show, (forall x. Package -> Rep Package x)
-> (forall x. Rep Package x -> Package) -> Generic Package
forall x. Rep Package x -> Package
forall x. Package -> Rep Package x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Package x -> Package
$cfrom :: forall x. Package -> Rep Package x
Generic, Value -> Parser [Package]
Value -> Parser Package
(Value -> Parser Package)
-> (Value -> Parser [Package]) -> FromJSON Package
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Package]
$cparseJSONList :: Value -> Parser [Package]
parseJSON :: Value -> Parser Package
$cparseJSON :: Value -> Parser Package
FromJSON)

api :: Proxy API
api :: Proxy API
api = Proxy API
forall k (t :: k). Proxy t
Proxy

metapackage :: Text -> ClientM (Vector Package)

metapackages ::
  Maybe Text ->
  Maybe Text ->
  Maybe Text ->
  Maybe Text ->
  Maybe Bool ->
  Maybe Text ->
  Maybe Integer ->
  Maybe Integer ->
  ClientM Metapackages

metapackages' ::
  Text ->
  Maybe Text ->
  Maybe Text ->
  Maybe Text ->
  Maybe Text ->
  Maybe Bool ->
  Maybe Text ->
  Maybe Integer ->
  Maybe Integer ->
  ClientM Metapackages
Text -> ClientM Metapackage
metapackage :<|> Maybe Text
-> Maybe Text
-> Maybe Text
-> Maybe Text
-> Maybe Bool
-> Maybe Text
-> Maybe Integer
-> Maybe Integer
-> ClientM Metapackages
metapackages :<|> Text
-> Maybe Text
-> Maybe Text
-> Maybe Text
-> Maybe Text
-> Maybe Bool
-> Maybe Text
-> Maybe Integer
-> Maybe Integer
-> ClientM Metapackages
metapackages' = Proxy API -> Client ClientM API
forall api.
HasClient ClientM api =>
Proxy api -> Client ClientM api
client Proxy API
api

-- type PagingResult = PagingResult (Vector Metapackage, ClientM PagingResult)
-- metapackages :: Text -> ClientM PagingResult
-- metapackages n = do
--   m <- ms n
--   return (lastMetapackageName m, sortedMetapackages m)
lastMetapackageName :: Metapackages -> Maybe Text
lastMetapackageName :: Metapackages -> Maybe Text
lastMetapackageName = Metapackages -> [Text]
forall k v. HashMap k v -> [k]
keys (Metapackages -> [Text])
-> ([Text] -> Maybe Text) -> Metapackages -> Maybe Text
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> [Text] -> [Text]
forall a. Ord a => [a] -> [a]
sort ([Text] -> [Text])
-> ([Text] -> Maybe Text) -> [Text] -> Maybe Text
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> [Text] -> [Text]
forall a. [a] -> [a]
Prelude.reverse ([Text] -> [Text])
-> ([Text] -> Maybe Text) -> [Text] -> Maybe Text
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> [Text] -> Maybe Text
forall a. [a] -> Maybe a
headMay

sortedMetapackages :: Metapackages -> Vector Metapackage
sortedMetapackages :: Metapackages -> Vector Metapackage
sortedMetapackages = Metapackages -> [Metapackage]
forall k v. HashMap k v -> [v]
elems (Metapackages -> [Metapackage])
-> ([Metapackage] -> Vector Metapackage)
-> Metapackages
-> Vector Metapackage
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (Metapackage -> Metapackage -> Ordering)
-> [Metapackage] -> [Metapackage]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy Metapackage -> Metapackage -> Ordering
compareMetapackage ([Metapackage] -> [Metapackage])
-> ([Metapackage] -> Vector Metapackage)
-> [Metapackage]
-> Vector Metapackage
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> [Metapackage] -> Vector Metapackage
forall a. [a] -> Vector a
V.fromList

nixRepo :: Text
nixRepo :: Text
nixRepo = Text
"nix_unstable"

nixOutdated :: ClientM Metapackages
nixOutdated :: ClientM Metapackages
nixOutdated =
  Maybe Text
-> Maybe Text
-> Maybe Text
-> Maybe Text
-> Maybe Bool
-> Maybe Text
-> Maybe Integer
-> Maybe Integer
-> ClientM Metapackages
metapackages
    Maybe Text
forall a. Maybe a
Nothing
    Maybe Text
forall a. Maybe a
Nothing
    Maybe Text
forall a. Maybe a
Nothing
    (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
nixRepo)
    (Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True)
    Maybe Text
forall a. Maybe a
Nothing
    Maybe Integer
forall a. Maybe a
Nothing
    Maybe Integer
forall a. Maybe a
Nothing

nextNixOutdated :: Text -> ClientM Metapackages
nextNixOutdated :: Text -> ClientM Metapackages
nextNixOutdated Text
n =
  Text
-> Maybe Text
-> Maybe Text
-> Maybe Text
-> Maybe Text
-> Maybe Bool
-> Maybe Text
-> Maybe Integer
-> Maybe Integer
-> ClientM Metapackages
metapackages'
    Text
n
    Maybe Text
forall a. Maybe a
Nothing
    Maybe Text
forall a. Maybe a
Nothing
    Maybe Text
forall a. Maybe a
Nothing
    (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
nixRepo)
    (Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True)
    Maybe Text
forall a. Maybe a
Nothing
    Maybe Integer
forall a. Maybe a
Nothing
    Maybe Integer
forall a. Maybe a
Nothing

outdatedForRepo :: Text -> Vector Package -> Maybe Package
outdatedForRepo :: Text -> Metapackage -> Maybe Package
outdatedForRepo Text
r =
  (Package -> Bool) -> Metapackage -> Maybe Package
forall a. (a -> Bool) -> Vector a -> Maybe a
V.find (\Package
p -> (Package -> Maybe Text
status Package
p) Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"outdated" Bool -> Bool -> Bool
&& (Package -> Text
repo Package
p) Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
r)

newest :: Vector Package -> Maybe Package
newest :: Metapackage -> Maybe Package
newest = (Package -> Bool) -> Metapackage -> Maybe Package
forall a. (a -> Bool) -> Vector a -> Maybe a
V.find (\Package
p -> (Package -> Maybe Text
status Package
p) Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"newest")

dropMaybes :: [(Maybe Package, Maybe Package)] -> [(Package, Package)]
dropMaybes :: [(Maybe Package, Maybe Package)] -> [(Package, Package)]
dropMaybes = ([(Package, Package)]
 -> (Maybe Package, Maybe Package) -> [(Package, Package)])
-> [(Package, Package)]
-> [(Maybe Package, Maybe Package)]
-> [(Package, Package)]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Data.List.foldl' [(Package, Package)]
-> (Maybe Package, Maybe Package) -> [(Package, Package)]
forall a b. [(a, b)] -> (Maybe a, Maybe b) -> [(a, b)]
twoJusts []
  where
    twoJusts :: [(a, b)] -> (Maybe a, Maybe b) -> [(a, b)]
twoJusts [(a, b)]
a (Just a
o, Just b
n) = (a
o, b
n) (a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
: [(a, b)]
a
    twoJusts [(a, b)]
a (Maybe a, Maybe b)
_ = [(a, b)]
a

getUpdateInfo :: ClientM (Maybe Text, Bool, Vector (Package, Package))
getUpdateInfo :: ClientM (Maybe Text, Bool, Vector (Package, Package))
getUpdateInfo = do
  Metapackages
outdated <- ClientM Metapackages
nixOutdated
  let ms :: [Metapackage]
ms = Metapackages -> [Metapackage]
forall k v. HashMap k v -> [v]
elems Metapackages
outdated
  let nixPackages :: [Maybe Package]
nixPackages = (Metapackage -> Maybe Package) -> [Metapackage] -> [Maybe Package]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> Metapackage -> Maybe Package
outdatedForRepo Text
nixRepo) [Metapackage]
ms
  let newestPackages :: [Maybe Package]
newestPackages = (Metapackage -> Maybe Package) -> [Metapackage] -> [Maybe Package]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Metapackage -> Maybe Package
newest [Metapackage]
ms
  let nixNew :: [(Package, Package)]
nixNew = [(Maybe Package, Maybe Package)] -> [(Package, Package)]
dropMaybes ([Maybe Package]
-> [Maybe Package] -> [(Maybe Package, Maybe Package)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Maybe Package]
nixPackages [Maybe Package]
newestPackages)
  let mLastName :: Maybe Text
mLastName = Metapackages -> Maybe Text
lastMetapackageName Metapackages
outdated
  IO () -> ClientM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ClientM ()) -> IO () -> ClientM ()
forall a b. (a -> b) -> a -> b
$ Handle -> String -> IO ()
hPutStrLn Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Maybe Text -> String
forall a. Show a => a -> String
show Maybe Text
mLastName
  IO () -> ClientM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ClientM ()) -> IO () -> ClientM ()
forall a b. (a -> b) -> a -> b
$ Handle -> String -> IO ()
hPutStrLn Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show ([Metapackage] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Metapackage]
ms)
  (Maybe Text, Bool, Vector (Package, Package))
-> ClientM (Maybe Text, Bool, Vector (Package, Package))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Text
mLastName, [Metapackage] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Metapackage]
ms Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
1, [(Package, Package)] -> Vector (Package, Package)
forall a. [a] -> Vector a
V.fromList [(Package, Package)]
nixNew)

--  let sorted = sortBy (\(p1,_) (p2,_) -> compare (name p1) (name p2)) nixNew
getNextUpdateInfo ::
  Text -> ClientM (Maybe Text, Bool, Vector (Package, Package))
getNextUpdateInfo :: Text -> ClientM (Maybe Text, Bool, Vector (Package, Package))
getNextUpdateInfo Text
n = do
  Metapackages
outdated <- Text -> ClientM Metapackages
nextNixOutdated Text
n
  let ms :: [Metapackage]
ms = Metapackages -> [Metapackage]
forall k v. HashMap k v -> [v]
elems Metapackages
outdated
  let nixPackages :: [Maybe Package]
nixPackages = (Metapackage -> Maybe Package) -> [Metapackage] -> [Maybe Package]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> Metapackage -> Maybe Package
outdatedForRepo Text
nixRepo) [Metapackage]
ms
  let newestPackages :: [Maybe Package]
newestPackages = (Metapackage -> Maybe Package) -> [Metapackage] -> [Maybe Package]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Metapackage -> Maybe Package
newest [Metapackage]
ms
  let nixNew :: [(Package, Package)]
nixNew = [(Maybe Package, Maybe Package)] -> [(Package, Package)]
dropMaybes ([Maybe Package]
-> [Maybe Package] -> [(Maybe Package, Maybe Package)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Maybe Package]
nixPackages [Maybe Package]
newestPackages)
  let mLastName :: Maybe Text
mLastName = Metapackages -> Maybe Text
lastMetapackageName Metapackages
outdated
  IO () -> ClientM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ClientM ()) -> IO () -> ClientM ()
forall a b. (a -> b) -> a -> b
$ Handle -> String -> IO ()
hPutStrLn Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Maybe Text -> String
forall a. Show a => a -> String
show Maybe Text
mLastName
  IO () -> ClientM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ClientM ()) -> IO () -> ClientM ()
forall a b. (a -> b) -> a -> b
$ Handle -> String -> IO ()
hPutStrLn Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show ([Metapackage] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Metapackage]
ms)
  (Maybe Text, Bool, Vector (Package, Package))
-> ClientM (Maybe Text, Bool, Vector (Package, Package))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Text
mLastName, [Metapackage] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Metapackage]
ms Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
1, [(Package, Package)] -> Vector (Package, Package)
forall a. [a] -> Vector a
V.fromList [(Package, Package)]
nixNew)

repologyUrl :: Text -> Text
repologyUrl :: Text -> Text
repologyUrl Text
pname = Text
"https://repology.org/metapackage/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
pname Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/versions"

--  let sorted = sortBy (\(p1,_) (p2,_) -> compare (name p1) (name p2)) nixNew
updateInfo :: (Package, Package) -> Maybe Text
updateInfo :: (Package, Package) -> Maybe Text
updateInfo (Package
outdated, Package
newestP) = do
  Text
pname <- Package -> Maybe Text
name Package
outdated
  Text -> Maybe Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.unwords [Text
pname, Package -> Text
version Package
outdated, Package -> Text
version Package
newestP, Text -> Text
repologyUrl Text
pname]

justs :: Vector (Maybe a) -> Vector a
justs :: Vector (Maybe a) -> Vector a
justs = (Maybe a -> Vector a) -> Vector (Maybe a) -> Vector a
forall a b. (a -> Vector b) -> Vector a -> Vector b
V.concatMap (Maybe a -> [a]
forall a. Maybe a -> [a]
maybeToList (Maybe a -> [a]) -> ([a] -> Vector a) -> Maybe a -> Vector a
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> [a] -> Vector a
forall a. [a] -> Vector a
V.fromList)

moreNixUpdateInfo ::
  (Maybe Text, Vector (Package, Package)) ->
  ClientM (Vector (Package, Package))
moreNixUpdateInfo :: (Maybe Text, Vector (Package, Package))
-> ClientM (Vector (Package, Package))
moreNixUpdateInfo (Maybe Text
Nothing, Vector (Package, Package)
acc) = do
  (Maybe Text
mLastName, Bool
moreWork, Vector (Package, Package)
newNix) <- ClientM (Maybe Text, Bool, Vector (Package, Package))
getUpdateInfo
  IO () -> ClientM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ClientM ()) -> IO () -> ClientM ()
forall a b. (a -> b) -> a -> b
$
    Vector (IO ()) -> IO ()
forall (m :: * -> *) a. Monad m => Vector (m a) -> m ()
V.sequence_ (Vector (IO ()) -> IO ()) -> Vector (IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$
      (Text -> IO ()) -> Vector Text -> Vector (IO ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> IO ()
Data.Text.IO.putStrLn (Vector Text -> Vector (IO ())) -> Vector Text -> Vector (IO ())
forall a b. (a -> b) -> a -> b
$
        Vector (Maybe Text) -> Vector Text
forall a. Vector (Maybe a) -> Vector a
justs (Vector (Maybe Text) -> Vector Text)
-> Vector (Maybe Text) -> Vector Text
forall a b. (a -> b) -> a -> b
$
          ((Package, Package) -> Maybe Text)
-> Vector (Package, Package) -> Vector (Maybe Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Package, Package) -> Maybe Text
updateInfo Vector (Package, Package)
newNix
  if Bool
moreWork
    then (Maybe Text, Vector (Package, Package))
-> ClientM (Vector (Package, Package))
moreNixUpdateInfo (Maybe Text
mLastName, Vector (Package, Package)
newNix Vector (Package, Package)
-> Vector (Package, Package) -> Vector (Package, Package)
forall a. Vector a -> Vector a -> Vector a
V.++ Vector (Package, Package)
acc)
    else Vector (Package, Package) -> ClientM (Vector (Package, Package))
forall (m :: * -> *) a. Monad m => a -> m a
return Vector (Package, Package)
acc
moreNixUpdateInfo (Just Text
pname, Vector (Package, Package)
acc) = do
  (Maybe Text
mLastName, Bool
moreWork, Vector (Package, Package)
newNix) <- Text -> ClientM (Maybe Text, Bool, Vector (Package, Package))
getNextUpdateInfo Text
pname
  IO () -> ClientM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ClientM ()) -> IO () -> ClientM ()
forall a b. (a -> b) -> a -> b
$
    Vector (IO ()) -> IO ()
forall (m :: * -> *) a. Monad m => Vector (m a) -> m ()
V.sequence_ (Vector (IO ()) -> IO ()) -> Vector (IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$
      (Text -> IO ()) -> Vector Text -> Vector (IO ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> IO ()
Data.Text.IO.putStrLn (Vector Text -> Vector (IO ())) -> Vector Text -> Vector (IO ())
forall a b. (a -> b) -> a -> b
$
        Vector (Maybe Text) -> Vector Text
forall a. Vector (Maybe a) -> Vector a
justs (Vector (Maybe Text) -> Vector Text)
-> Vector (Maybe Text) -> Vector Text
forall a b. (a -> b) -> a -> b
$
          ((Package, Package) -> Maybe Text)
-> Vector (Package, Package) -> Vector (Maybe Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Package, Package) -> Maybe Text
updateInfo Vector (Package, Package)
newNix
  if Bool
moreWork
    then (Maybe Text, Vector (Package, Package))
-> ClientM (Vector (Package, Package))
moreNixUpdateInfo (Maybe Text
mLastName, Vector (Package, Package)
newNix Vector (Package, Package)
-> Vector (Package, Package) -> Vector (Package, Package)
forall a. Vector a -> Vector a -> Vector a
V.++ Vector (Package, Package)
acc)
    else Vector (Package, Package) -> ClientM (Vector (Package, Package))
forall (m :: * -> *) a. Monad m => a -> m a
return Vector (Package, Package)
acc

allNixUpdateInfo :: ClientM (Vector (Package, Package))
allNixUpdateInfo :: ClientM (Vector (Package, Package))
allNixUpdateInfo = (Maybe Text, Vector (Package, Package))
-> ClientM (Vector (Package, Package))
moreNixUpdateInfo (Maybe Text
forall a. Maybe a
Nothing, Vector (Package, Package)
forall a. Vector a
V.empty)

fetch :: IO ()
fetch :: IO ()
fetch = do
  Handle -> BufferMode -> IO ()
hSetBuffering Handle
stdout BufferMode
LineBuffering
  Handle -> BufferMode -> IO ()
hSetBuffering Handle
stderr BufferMode
LineBuffering
  IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Handle -> String -> IO ()
hPutStrLn Handle
stderr String
"starting"
  Manager
manager' <- IO Manager
forall (m :: * -> *). MonadIO m => m Manager
newTlsManager
  Either ClientError (Vector (Package, Package))
e <- ClientM (Vector (Package, Package))
-> ClientEnv -> IO (Either ClientError (Vector (Package, Package)))
forall a. ClientM a -> ClientEnv -> IO (Either ClientError a)
runClientM ClientM (Vector (Package, Package))
allNixUpdateInfo (Manager -> BaseUrl -> ClientEnv
mkClientEnv Manager
manager' BaseUrl
baseUrl)
  case Either ClientError (Vector (Package, Package))
e of
    Left ClientError
ce -> IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Handle -> String -> IO ()
hPutStrLn Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ ClientError -> String
forall a. Show a => a -> String
show ClientError
ce
    Right Vector (Package, Package)
_ -> IO () -> IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Handle -> String -> IO ()
hPutStrLn Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"done"
  () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()