{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ViewPatterns #-}
module NvFetcher
( runNvFetcher,
runNvFetcher',
runNvFetcherNoCLI,
applyCliOptions,
parseLastVersions,
module NvFetcher.PackageSet,
module NvFetcher.Types,
module NvFetcher.Types.ShakeExtras,
)
where
import Control.Monad.Extra (forM_, unless, when, whenJust, whenM)
import qualified Data.Aeson as A
import qualified Data.Aeson.Encode.Pretty as A
import qualified Data.Aeson.Types as A
import qualified Data.ByteString.Lazy.Char8 as LBS
import Data.Default
import Data.List (partition, (\\))
import qualified Data.Map.Strict as Map
import Data.Maybe (catMaybes, fromJust, fromMaybe, isJust)
import Data.Text (Text)
import qualified Data.Text as T
import Development.Shake
import Development.Shake.FilePath
import NeatInterpolation (trimming)
import NvFetcher.Config
import NvFetcher.Core
import NvFetcher.NixExpr (ToNixExpr (toNixExpr))
import NvFetcher.NixFetcher
import NvFetcher.Nvchecker
import NvFetcher.Options
import NvFetcher.PackageSet
import NvFetcher.Types
import NvFetcher.Types.ShakeExtras
import NvFetcher.Utils (aesonKey, getDataDir)
import qualified System.Directory.Extra as D
import Text.Regex.TDFA ((=~))
runNvFetcher :: PackageSet () -> IO ()
runNvFetcher :: PackageSet () -> IO ()
runNvFetcher = Config -> PackageSet () -> IO ()
runNvFetcher' Config
forall a. Default a => a
def
runNvFetcher' :: Config -> PackageSet () -> IO ()
runNvFetcher' :: Config -> PackageSet () -> IO ()
runNvFetcher' Config
config PackageSet ()
packageSet =
Parser CLIOptions -> IO CLIOptions
forall a. Parser a -> IO a
getCLIOptions Parser CLIOptions
cliOptionsParser IO CLIOptions -> (CLIOptions -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CLIOptions
cli ->
Config -> CLIOptions -> IO Config
applyCliOptions Config
config CLIOptions
cli IO Config -> (Config -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Config
o ->
Config -> Target -> PackageSet () -> IO ()
runNvFetcherNoCLI Config
o (CLIOptions -> Target
optTarget CLIOptions
cli) PackageSet ()
packageSet
applyCliOptions :: Config -> CLIOptions -> IO Config
applyCliOptions :: Config -> CLIOptions -> IO Config
applyCliOptions Config
config CLIOptions {Bool
Int
String
Maybe String
Target
optTarget :: CLIOptions -> Target
optBuildDir :: String
optCommit :: Bool
optCommitSummary :: Maybe String
optLogPath :: Maybe String
optThreads :: Int
optRetry :: Int
optTiming :: Bool
optVerbose :: Bool
optPkgNameFilter :: Maybe String
optKeyfile :: Maybe String
optKeepOldFiles :: Bool
optKeepGoing :: Bool
optTarget :: Target
optBuildDir :: CLIOptions -> String
optCommit :: CLIOptions -> Bool
optCommitSummary :: CLIOptions -> Maybe String
optLogPath :: CLIOptions -> Maybe String
optThreads :: CLIOptions -> Int
optRetry :: CLIOptions -> Int
optTiming :: CLIOptions -> Bool
optVerbose :: CLIOptions -> Bool
optPkgNameFilter :: CLIOptions -> Maybe String
optKeyfile :: CLIOptions -> Maybe String
optKeepOldFiles :: CLIOptions -> Bool
optKeepGoing :: CLIOptions -> Bool
..} = do
Maybe String
aKeyfile <- case Maybe String
optKeyfile of
Just String
k -> String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> IO String -> IO (Maybe String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO String
D.makeAbsolute String
k
Maybe String
_ -> Maybe String -> IO (Maybe String)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe String
forall a. Maybe a
Nothing
Config -> IO Config
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Config -> IO Config) -> Config -> IO Config
forall a b. (a -> b) -> a -> b
$
Config
config
{ buildDir = optBuildDir,
actionAfterBuild = do
whenJust optLogPath logChangesToFile
when optCommit (commitChanges (fromMaybe "Update" optCommitSummary))
actionAfterBuild config,
shakeConfig =
(shakeConfig config)
{ shakeTimings = optTiming,
shakeVerbosity = if optVerbose then Verbose else Info,
shakeThreads = optThreads
},
filterRegex = optPkgNameFilter,
retry = optRetry,
keyfile = aKeyfile,
keepOldFiles = optKeepOldFiles,
keepGoing = optKeepGoing
}
logChangesToFile :: FilePath -> Action ()
logChangesToFile :: String -> Action ()
logChangesToFile String
fp = do
[VersionChange]
changes <- Action [VersionChange]
getVersionChanges
String -> String -> Action ()
forall (m :: * -> *).
(MonadIO m, Located) =>
String -> String -> m ()
writeFile' String
fp (String -> Action ()) -> String -> Action ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ VersionChange -> String
forall a. Show a => a -> String
show (VersionChange -> String) -> [VersionChange] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionChange]
changes
commitChanges :: String -> Action ()
commitChanges :: String -> Action ()
commitChanges String
commitSummary = do
[VersionChange]
changes <- Action [VersionChange]
getVersionChanges
let commitMsg :: Maybe String
commitMsg = case [VersionChange]
changes of
[VersionChange
x] -> String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ VersionChange -> String
forall a. Show a => a -> String
show VersionChange
x
xs :: [VersionChange]
xs@(VersionChange
_ : [VersionChange]
_) -> String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ String
commitSummary String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"\n" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [String] -> String
unlines (VersionChange -> String
forall a. Show a => a -> String
show (VersionChange -> String) -> [VersionChange] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionChange]
xs)
[] -> Maybe String
forall a. Maybe a
Nothing
Maybe String -> (String -> Action ()) -> Action ()
forall (m :: * -> *) a.
Applicative m =>
Maybe a -> (a -> m ()) -> m ()
whenJust Maybe String
commitMsg ((String -> Action ()) -> Action ())
-> (String -> Action ()) -> Action ()
forall a b. (a -> b) -> a -> b
$ \String
msg -> do
String -> Action ()
putInfo String
"Commiting changes"
Action String
getBuildDir Action String -> (String -> Action ()) -> Action ()
forall a b. Action a -> (a -> Action b) -> Action b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \String
dir -> Located => [CmdOption] -> String -> [String] -> Action ()
[CmdOption] -> String -> [String] -> Action ()
command_ [] String
"git" [String
"add", String
dir]
Located => [CmdOption] -> String -> [String] -> Action ()
[CmdOption] -> String -> [String] -> Action ()
command_ [] String
"git" [String
"commit", String
"-m", String
msg]
parseLastVersions :: FilePath -> IO (Maybe (Map.Map PackageKey Version))
parseLastVersions :: String -> IO (Maybe (Map PackageKey Version))
parseLastVersions String
jsonFile =
String -> IO Bool
D.doesFileExist String
jsonFile IO Bool
-> (Bool -> IO (Maybe (Map PackageKey Version)))
-> IO (Maybe (Map PackageKey Version))
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
True -> do
Maybe (Map PackageName Object)
objs <- String -> IO (Maybe (Map PackageName Object))
forall a. FromJSON a => String -> IO (Maybe a)
A.decodeFileStrict' String
jsonFile
Maybe (Map PackageKey Version)
-> IO (Maybe (Map PackageKey Version))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (Map PackageKey Version)
-> IO (Maybe (Map PackageKey Version)))
-> Maybe (Map PackageKey Version)
-> IO (Maybe (Map PackageKey Version))
forall a b. (a -> b) -> a -> b
$
((Map PackageName Object -> Map PackageKey Version)
-> Maybe (Map PackageName Object)
-> Maybe (Map PackageKey Version))
-> Maybe (Map PackageName Object)
-> (Map PackageName Object -> Map PackageKey Version)
-> Maybe (Map PackageKey Version)
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Map PackageName Object -> Map PackageKey Version)
-> Maybe (Map PackageName Object) -> Maybe (Map PackageKey Version)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe (Map PackageName Object)
objs ((Map PackageName Object -> Map PackageKey Version)
-> Maybe (Map PackageKey Version))
-> (Map PackageName Object -> Map PackageKey Version)
-> Maybe (Map PackageKey Version)
forall a b. (a -> b) -> a -> b
$
( \[(PackageName, Object)]
xs ->
[(PackageKey, Version)] -> Map PackageKey Version
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
([(PackageKey, Version)] -> Map PackageKey Version)
-> ([Maybe (PackageKey, Version)] -> [(PackageKey, Version)])
-> [Maybe (PackageKey, Version)]
-> Map PackageKey Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe (PackageKey, Version)] -> [(PackageKey, Version)]
forall a. [Maybe a] -> [a]
catMaybes
([Maybe (PackageKey, Version)] -> Map PackageKey Version)
-> [Maybe (PackageKey, Version)] -> Map PackageKey Version
forall a b. (a -> b) -> a -> b
$ [(PackageName -> PackageKey
PackageKey PackageName
k,) (Version -> (PackageKey, Version))
-> Maybe Version -> Maybe (PackageKey, Version)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Object -> Parser Version) -> Object -> Maybe Version
forall a b. (a -> Parser b) -> a -> Maybe b
A.parseMaybe (Object -> Key -> Parser Version
forall a. FromJSON a => Object -> Key -> Parser a
A..: Key
"version") Object
obj | (PackageName
k, Object
obj) <- [(PackageName, Object)]
xs]
)
([(PackageName, Object)] -> Map PackageKey Version)
-> (Map PackageName Object -> [(PackageName, Object)])
-> Map PackageName Object
-> Map PackageKey Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map PackageName Object -> [(PackageName, Object)]
forall k a. Map k a -> [(k, a)]
Map.toList
Bool
_ -> Maybe (Map PackageKey Version)
-> IO (Maybe (Map PackageKey Version))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Map PackageKey Version)
forall a. Monoid a => a
mempty
runNvFetcherNoCLI :: Config -> Target -> PackageSet () -> IO ()
runNvFetcherNoCLI :: Config -> Target -> PackageSet () -> IO ()
runNvFetcherNoCLI config :: Config
config@Config {Bool
Int
String
Maybe String
ShakeOptions
Action ()
Rules ()
buildDir :: Config -> String
actionAfterBuild :: Config -> Action ()
shakeConfig :: Config -> ShakeOptions
filterRegex :: Config -> Maybe String
retry :: Config -> Int
keyfile :: Config -> Maybe String
keepOldFiles :: Config -> Bool
keepGoing :: Config -> Bool
shakeConfig :: ShakeOptions
buildDir :: String
customRules :: Rules ()
actionAfterBuild :: Action ()
actionAfterClean :: Action ()
retry :: Int
filterRegex :: Maybe String
cacheNvchecker :: Bool
keepOldFiles :: Bool
keyfile :: Maybe String
keepGoing :: Bool
customRules :: Config -> Rules ()
actionAfterClean :: Config -> Action ()
cacheNvchecker :: Config -> Bool
..} Target
target PackageSet ()
packageSet = do
Map PackageKey Package
pkgs <- (Package -> Package)
-> Map PackageKey Package -> Map PackageKey Package
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map Package -> Package
pinIfUnmatch (Map PackageKey Package -> Map PackageKey Package)
-> IO (Map PackageKey Package) -> IO (Map PackageKey Package)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PackageSet () -> IO (Map PackageKey Package)
runPackageSet PackageSet ()
packageSet
Maybe (Map PackageKey Version)
lastVersions <- String -> IO (Maybe (Map PackageKey Version))
parseLastVersions (String -> IO (Maybe (Map PackageKey Version)))
-> String -> IO (Maybe (Map PackageKey Version))
forall a b. (a -> b) -> a -> b
$ String
buildDir String -> String -> String
</> String
generatedJsonFileName
String
shakeDir <- IO String
getDataDir
let shakeOptions1 :: ShakeOptions
shakeOptions1 = ShakeOptions
shakeConfig {shakeFiles = shakeDir, shakeVersion = "2"}
ShakeExtras
shakeExtras <- Config
-> Map PackageKey Package
-> Map PackageKey Version
-> IO ShakeExtras
initShakeExtras (Config
config {shakeConfig = shakeOptions1}) Map PackageKey Package
pkgs (Map PackageKey Version -> IO ShakeExtras)
-> Map PackageKey Version -> IO ShakeExtras
forall a b. (a -> b) -> a -> b
$ Map PackageKey Version
-> Maybe (Map PackageKey Version) -> Map PackageKey Version
forall a. a -> Maybe a -> a
fromMaybe Map PackageKey Version
forall a. Monoid a => a
mempty Maybe (Map PackageKey Version)
lastVersions
let shakeOptions2 :: ShakeOptions
shakeOptions2 = ShakeOptions
shakeOptions1 {shakeExtra = addShakeExtra shakeExtras (shakeExtra shakeConfig)}
rules :: Rules ()
rules = Config -> Rules ()
mainRules Config
config
ShakeOptions -> Rules () -> IO ()
shake ShakeOptions
shakeOptions2 (Rules () -> IO ()) -> Rules () -> IO ()
forall a b. (a -> b) -> a -> b
$ Located => [String] -> Rules ()
[String] -> Rules ()
want [Target -> String
forall a. Show a => a -> String
show Target
target] Rules () -> Rules () -> Rules ()
forall a b. Rules a -> Rules b -> Rules b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Rules ()
rules
where
pinIfUnmatch :: Package -> Package
pinIfUnmatch x :: Package
x@Package {Maybe PackageCargoLockFiles
Maybe PackageExtractSrc
PackageName
UseStaleVersion
PackagePassthru
DateFormat
ForceFetch
CheckVersion
PackageFetcher
_pname :: PackageName
_pversion :: CheckVersion
_pfetcher :: PackageFetcher
_pextract :: Maybe PackageExtractSrc
_pcargo :: Maybe PackageCargoLockFiles
_ppassthru :: PackagePassthru
_ppinned :: UseStaleVersion
_pgitdateformat :: DateFormat
_pforcefetch :: ForceFetch
_pname :: Package -> PackageName
_pversion :: Package -> CheckVersion
_pfetcher :: Package -> PackageFetcher
_pextract :: Package -> Maybe PackageExtractSrc
_pcargo :: Package -> Maybe PackageCargoLockFiles
_ppassthru :: Package -> PackagePassthru
_ppinned :: Package -> UseStaleVersion
_pgitdateformat :: Package -> DateFormat
_pforcefetch :: Package -> ForceFetch
..}
| Just String
regex <- Maybe String
filterRegex =
Package
x
{ _ppinned = case _ppinned of
UseStaleVersion
PermanentStale -> UseStaleVersion
PermanentStale
UseStaleVersion
_ ->
if PackageName
_pname PackageName -> String -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
RegexContext Regex source1 target) =>
source1 -> source -> target
=~ String
regex
then UseStaleVersion
NoStale
else UseStaleVersion
TemporaryStale
}
| Bool
otherwise = Package
x
mainRules :: Config -> Rules ()
mainRules :: Config -> Rules ()
mainRules Config {Bool
Int
String
Maybe String
ShakeOptions
Action ()
Rules ()
buildDir :: Config -> String
actionAfterBuild :: Config -> Action ()
shakeConfig :: Config -> ShakeOptions
filterRegex :: Config -> Maybe String
retry :: Config -> Int
keyfile :: Config -> Maybe String
keepOldFiles :: Config -> Bool
keepGoing :: Config -> Bool
customRules :: Config -> Rules ()
actionAfterClean :: Config -> Action ()
cacheNvchecker :: Config -> Bool
shakeConfig :: ShakeOptions
buildDir :: String
customRules :: Rules ()
actionAfterBuild :: Action ()
actionAfterClean :: Action ()
retry :: Int
filterRegex :: Maybe String
cacheNvchecker :: Bool
keepOldFiles :: Bool
keyfile :: Maybe String
keepGoing :: Bool
..} = do
String
"clean" Located => String -> Action () -> Rules ()
String -> Action () -> Rules ()
~> do
Action String
getBuildDir Action String -> (String -> Action ()) -> Action ()
forall a b. Action a -> (a -> Action b) -> Action b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (String -> [String] -> Action ())
-> [String] -> String -> Action ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> [String] -> Action ()
removeFilesAfter [String
"//*"]
Action ()
actionAfterClean
String
"purge" Located => String -> Action () -> Rules ()
String -> Action () -> Rules ()
~> do
String
shakeDir <- ShakeOptions -> String
shakeFiles (ShakeOptions -> String) -> Action ShakeOptions -> Action String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Action ShakeOptions
getShakeOptions
String -> [String] -> Action ()
removeFilesAfter String
shakeDir [String
"//*"]
String
"build" Located => String -> Action () -> Rules ()
String -> Action () -> Rules ()
~> do
Bool -> Action () -> Action ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
keepOldFiles (Action () -> Action ()) -> Action () -> Action ()
forall a b. (a -> b) -> a -> b
$
Action Bool -> Action () -> Action ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (IO Bool -> Action Bool
forall a. IO a -> Action a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> Action Bool) -> IO Bool -> Action Bool
forall a b. (a -> b) -> a -> b
$ String -> IO Bool
D.doesDirectoryExist String
buildDir) (Action () -> Action ()) -> Action () -> Action ()
forall a b. (a -> b) -> a -> b
$ do
[String]
oldFiles <- ([String] -> [String] -> [String]
forall a. Eq a => [a] -> [a] -> [a]
\\ [String
generatedJsonFileName, String
generatedNixFileName]) ([String] -> [String]) -> Action [String] -> Action [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO [String] -> Action [String]
forall a. IO a -> Action a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO [String]
D.listDirectory String
buildDir)
String -> Action ()
putVerbose (String -> Action ()) -> String -> Action ()
forall a b. (a -> b) -> a -> b
$ String
"Removing old files: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [String] -> String
forall a. Show a => a -> String
show [String]
oldFiles
IO () -> Action ()
forall a. IO a -> Action a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Action ()) -> IO () -> Action ()
forall a b. (a -> b) -> a -> b
$ String -> [String] -> IO ()
removeFiles String
buildDir [String]
oldFiles
[PackageKey]
allKeys <- Action [PackageKey]
getAllPackageKeys
[(PackageKey, Maybe PackageResult)]
results <- ([Maybe PackageResult] -> [(PackageKey, Maybe PackageResult)])
-> Action [Maybe PackageResult]
-> Action [(PackageKey, Maybe PackageResult)]
forall a b. (a -> b) -> Action a -> Action b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([PackageKey]
-> [Maybe PackageResult] -> [(PackageKey, Maybe PackageResult)]
forall a b. [a] -> [b] -> [(a, b)]
zip [PackageKey]
allKeys) (Action [Maybe PackageResult]
-> Action [(PackageKey, Maybe PackageResult)])
-> Action [Maybe PackageResult]
-> Action [(PackageKey, Maybe PackageResult)]
forall a b. (a -> b) -> a -> b
$ [Action (Maybe PackageResult)] -> Action [Maybe PackageResult]
forall a. [Action a] -> Action [a]
parallel ([Action (Maybe PackageResult)] -> Action [Maybe PackageResult])
-> [Action (Maybe PackageResult)] -> Action [Maybe PackageResult]
forall a b. (a -> b) -> a -> b
$ PackageKey -> Action (Maybe PackageResult)
runPackage (PackageKey -> Action (Maybe PackageResult))
-> [PackageKey] -> [Action (Maybe PackageResult)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [PackageKey]
allKeys
let (((PackageKey, Maybe PackageResult) -> PackageResult)
-> [(PackageKey, Maybe PackageResult)] -> [PackageResult]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Maybe PackageResult -> PackageResult
forall a. Located => Maybe a -> a
fromJust (Maybe PackageResult -> PackageResult)
-> ((PackageKey, Maybe PackageResult) -> Maybe PackageResult)
-> (PackageKey, Maybe PackageResult)
-> PackageResult
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PackageKey, Maybe PackageResult) -> Maybe PackageResult
forall a b. (a, b) -> b
snd) -> [PackageResult]
successResults, ((PackageKey, Maybe PackageResult) -> PackageKey)
-> [(PackageKey, Maybe PackageResult)] -> [PackageKey]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PackageKey, Maybe PackageResult) -> PackageKey
forall a b. (a, b) -> a
fst -> [PackageKey]
failureKeys) = ((PackageKey, Maybe PackageResult) -> Bool)
-> [(PackageKey, Maybe PackageResult)]
-> ([(PackageKey, Maybe PackageResult)],
[(PackageKey, Maybe PackageResult)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (Maybe PackageResult -> Bool
forall a. Maybe a -> Bool
isJust (Maybe PackageResult -> Bool)
-> ((PackageKey, Maybe PackageResult) -> Maybe PackageResult)
-> (PackageKey, Maybe PackageResult)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PackageKey, Maybe PackageResult) -> Maybe PackageResult
forall a b. (a, b) -> b
snd) [(PackageKey, Maybe PackageResult)]
results
Action (Map PackageKey Version)
getAllOnDiskVersions
Action (Map PackageKey Version)
-> (Map PackageKey Version -> Action ()) -> Action ()
forall a b. Action a -> (a -> Action b) -> Action b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Map PackageKey Version
oldPkgs -> [PackageKey] -> (PackageKey -> Action ()) -> Action ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (Map PackageKey Version -> [PackageKey]
forall k a. Map k a -> [k]
Map.keys Map PackageKey Version
oldPkgs [PackageKey] -> [PackageKey] -> [PackageKey]
forall a. Eq a => [a] -> [a] -> [a]
\\ ([PackageKey]
allKeys [PackageKey] -> [PackageKey] -> [PackageKey]
forall a. Eq a => [a] -> [a] -> [a]
\\ [PackageKey]
failureKeys)) ((PackageKey -> Action ()) -> Action ())
-> (PackageKey -> Action ()) -> Action ()
forall a b. (a -> b) -> a -> b
$
\PackageKey
pkg -> PackageName -> Maybe Version -> Version -> Action ()
recordVersionChange (PackageKey -> PackageName
forall a b. Coercible a b => a -> b
coerce PackageKey
pkg) (Map PackageKey Version
oldPkgs Map PackageKey Version -> PackageKey -> Maybe Version
forall k a. Ord k => Map k a -> k -> Maybe a
Map.!? PackageKey
pkg) Version
"∅"
Action [VersionChange]
getVersionChanges Action [VersionChange]
-> ([VersionChange] -> Action ()) -> Action ()
forall a b. Action a -> (a -> Action b) -> Action b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \[VersionChange]
changes ->
if [VersionChange] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [VersionChange]
changes
then String -> Action ()
putInfo String
"Up to date"
else do
String -> Action ()
putInfo String
"Changes:"
String -> Action ()
putInfo (String -> Action ()) -> String -> Action ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ VersionChange -> String
forall a. Show a => a -> String
show (VersionChange -> String) -> [VersionChange] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VersionChange]
changes
String
buildDir <- Action String
getBuildDir
let generatedNixPath :: String
generatedNixPath = String
buildDir String -> String -> String
</> String
generatedNixFileName
generatedJSONPath :: String
generatedJSONPath = String
buildDir String -> String -> String
</> String
generatedJsonFileName
String -> Action ()
putVerbose (String -> Action ()) -> String -> Action ()
forall a b. (a -> b) -> a -> b
$ String
"Generating " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
generatedNixPath
String -> String -> Action ()
forall (m :: * -> *).
(MonadIO m, Located) =>
String -> String -> m ()
writeFileChanged String
generatedNixPath (String -> Action ()) -> String -> Action ()
forall a b. (a -> b) -> a -> b
$ PackageName -> String
T.unpack (PackageName -> String) -> PackageName -> String
forall a b. (a -> b) -> a -> b
$ PackageName -> PackageName
srouces ([PackageName] -> PackageName
T.unlines ([PackageName] -> PackageName) -> [PackageName] -> PackageName
forall a b. (a -> b) -> a -> b
$ PackageResult -> PackageName
forall a. ToNixExpr a => a -> PackageName
toNixExpr (PackageResult -> PackageName) -> [PackageResult] -> [PackageName]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [PackageResult]
successResults) PackageName -> PackageName -> PackageName
forall a. Semigroup a => a -> a -> a
<> PackageName
"\n"
String -> Action ()
putVerbose (String -> Action ()) -> String -> Action ()
forall a b. (a -> b) -> a -> b
$ String
"Generating " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
generatedJSONPath
String -> String -> Action ()
forall (m :: * -> *).
(MonadIO m, Located) =>
String -> String -> m ()
writeFileChanged String
generatedJSONPath (String -> Action ()) -> String -> Action ()
forall a b. (a -> b) -> a -> b
$ ByteString -> String
LBS.unpack (ByteString -> String) -> ByteString -> String
forall a b. (a -> b) -> a -> b
$ Value -> ByteString
forall a. ToJSON a => a -> ByteString
A.encodePretty (Value -> ByteString) -> Value -> ByteString
forall a b. (a -> b) -> a -> b
$ [Pair] -> Value
A.object [PackageName -> Key
aesonKey (PackageResult -> PackageName
_prname PackageResult
r) Key -> PackageResult -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
A..= PackageResult
r | PackageResult
r <- [PackageResult]
successResults]
Action ()
actionAfterBuild
Rules ()
customRules
Rules ()
coreRules
srouces :: Text -> Text
srouces :: PackageName -> PackageName
srouces PackageName
body =
[trimming|
# This file was generated by nvfetcher, please do not modify it manually.
{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }:
{
$body
}
|]
generatedNixFileName :: String
generatedNixFileName :: String
generatedNixFileName = String
"generated.nix"
generatedJsonFileName :: String
generatedJsonFileName :: String
generatedJsonFileName = String
"generated.json"