{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

-- | Copyright: (c) 2021-2022 berberman
-- SPDX-License-Identifier: MIT
-- Maintainer: berberman <[email protected]>
-- Stability: experimental
-- Portability: portable
--
-- [nvchecker](https://github.com/lilydjwg/nvchecker) is a program checking new versions of packages.
-- We encode the checking process into shake build system, generating configuration of nvchecker and calling it externally.
-- Now we call nvchecker for each 'VersionSource', which seems not to be efficient, but it's tolerable when running in parallel.
--
-- Meanwhile, we lose the capabilities of tracking version updates, i.e. normally nvchecker will help us maintain a list of old versions,
-- so that we are able to know which package's version is updated in this run. Fortunately, we can reimplement this in shake,
-- see 'nvcheckerRule' for details.
module NvFetcher.Nvchecker
  ( -- * Types
    VersionSortMethod (..),
    ListOptions (..),
    CheckVersion (..),
    NvcheckerOptions (..),
    VersionSource (..),
    NvcheckerResult (..),

    -- * Rules
    nvcheckerRule,

    -- * Functions
    checkVersion,
    checkVersion',
  )
where

import Control.Monad (void)
import Control.Monad.Extra (fromMaybeM)
import Control.Monad.Trans.Writer.CPS
import qualified Data.Aeson as A
import qualified Data.ByteString.Char8 as BS
import Data.Coerce (coerce)
import Data.Maybe (fromJust)
import Data.Text (Text)
import qualified Data.Text as T
import Development.Shake
import Development.Shake.Rule
import NvFetcher.Types
import NvFetcher.Types.ShakeExtras
import NvFetcher.Utils
import Prettyprinter (pretty, (<+>))

-- | Rules of nvchecker
nvcheckerRule :: Rules ()
nvcheckerRule :: Rules ()
nvcheckerRule = do
  Rules ()
persistedRule
  Rules ()
oneShotRule

-- | Nvchecker rule for packages, which is aware of version changes and supports using stale version.
-- nvchecker will be called at most one time given a package key. Follow-up using of this rule will return cached result.
-- 'PackageKey' is required for caching.
-- Run this rule by calling 'checkVersion'
persistedRule :: Rules ()
persistedRule :: Rules ()
persistedRule = BuiltinLint (WithPackageKey CheckVersion) NvcheckerResult
-> BuiltinIdentity (WithPackageKey CheckVersion) NvcheckerResult
-> BuiltinRun (WithPackageKey CheckVersion) NvcheckerResult
-> Rules ()
forall key value.
(RuleResult key ~ value, ShakeValue key, Typeable value,
 NFData value, Show value, Partial) =>
BuiltinLint key value
-> BuiltinIdentity key value -> BuiltinRun key value -> Rules ()
addBuiltinRule BuiltinLint (WithPackageKey CheckVersion) NvcheckerResult
forall key value. BuiltinLint key value
noLint BuiltinIdentity (WithPackageKey CheckVersion) NvcheckerResult
forall key value. BuiltinIdentity key value
noIdentity (BuiltinRun (WithPackageKey CheckVersion) NvcheckerResult
 -> Rules ())
-> BuiltinRun (WithPackageKey CheckVersion) NvcheckerResult
-> Rules ()
forall a b. (a -> b) -> a -> b
$ \(WithPackageKey (key :: CheckVersion
key@(CheckVersion VersionSource
versionSource NvcheckerOptions
options), PackageKey
pkg)) Maybe ByteString
_old RunMode
_mode -> do
  String -> Action ()
putInfo (String -> Action ())
-> (Doc Any -> String) -> Doc Any -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Any -> String
forall a. Show a => a -> String
show (Doc Any -> Action ()) -> Doc Any -> Action ()
forall a b. (a -> b) -> a -> b
$ Doc Any
"#" Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> CheckVersion -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. CheckVersion -> Doc ann
pretty CheckVersion
key
  Maybe Version
oldVer <- PackageKey -> Action (Maybe Version)
getRecentLastVersion PackageKey
pkg
  UseStaleVersion
useStaleVersion <- Package -> UseStaleVersion
_ppinned (Package -> UseStaleVersion)
-> (Maybe Package -> Package) -> Maybe Package -> UseStaleVersion
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Package -> Package
forall a. Partial => Maybe a -> a
fromJust (Maybe Package -> UseStaleVersion)
-> Action (Maybe Package) -> Action UseStaleVersion
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PackageKey -> Action (Maybe Package)
lookupPackage PackageKey
pkg
  let useStale :: Bool
useStale = case UseStaleVersion
useStaleVersion of
        UseStaleVersion
PermanentStale -> Bool
True
        UseStaleVersion
TemporaryStale -> Bool
True
        UseStaleVersion
_ -> Bool
False
  case Bool
useStale of
    Bool
True
      | Just Version
oldVer' <- Maybe Version
oldVer -> do
          -- use the stale version if we have
          String -> Action ()
putInfo (String -> Action ()) -> String -> Action ()
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text
"Skip running nvchecker, use stale version " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Version -> Text
forall a b. Coercible a b => a -> b
coerce Version
oldVer' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" for " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> PackageKey -> Text
forall a b. Coercible a b => a -> b
coerce PackageKey
pkg
          let result :: NvcheckerResult
result = NvcheckerResult {nvNow :: Version
nvNow = Version
oldVer', nvOld :: Maybe Version
nvOld = Maybe Version
oldVer, nvStale :: Bool
nvStale = Bool
True}
          RunResult NvcheckerResult -> Action (RunResult NvcheckerResult)
forall a. a -> Action a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RunResult NvcheckerResult -> Action (RunResult NvcheckerResult))
-> RunResult NvcheckerResult -> Action (RunResult NvcheckerResult)
forall a b. (a -> b) -> a -> b
$ RunChanged
-> ByteString -> NvcheckerResult -> RunResult NvcheckerResult
forall value. RunChanged -> ByteString -> value -> RunResult value
RunResult RunChanged
ChangedRecomputeSame (NvcheckerResult -> ByteString
forall a. Binary a => a -> ByteString
encode' NvcheckerResult
result) NvcheckerResult
result

    -- run nvchecker
    Bool
_ -> do
      -- if we already run this rule for a package, we can recover the last result from getLastVersionUpdated
      -- (when cacheNvchecker is enabled)
      Bool
useCache <- Action Bool
nvcheckerCacheEnabled
      Version
now <- Action Version -> Action (Maybe Version) -> Action Version
forall (m :: * -> *) a. Monad m => m a -> m (Maybe a) -> m a
fromMaybeM (Version -> Version
forall a b. Coercible a b => a -> b
coerce (Version -> Version) -> Action Version -> Action Version
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PackageKey -> NvcheckerOptions -> VersionSource -> Action Version
runNvchecker PackageKey
pkg NvcheckerOptions
options VersionSource
versionSource) (if Bool
useCache then PackageKey -> Action (Maybe Version)
getLastVersionUpdated PackageKey
pkg else Maybe Version -> Action (Maybe Version)
forall a. a -> Action a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Version
forall a. Maybe a
Nothing)
      let runChanged :: RunChanged
runChanged = case Maybe Version
oldVer of
            Just Version
oldVer'
              | Version
oldVer' Version -> Version -> Bool
forall a. Eq a => a -> a -> Bool
== Version
now -> RunChanged
ChangedRecomputeSame
            Maybe Version
_ -> RunChanged
ChangedRecomputeDiff
          result :: NvcheckerResult
result = NvcheckerResult {nvNow :: Version
nvNow = Version
now, nvOld :: Maybe Version
nvOld = Maybe Version
oldVer, nvStale :: Bool
nvStale = Bool
False}
      -- always update
      PackageKey -> Version -> Action ()
updateLastVersion PackageKey
pkg Version
now
      RunResult NvcheckerResult -> Action (RunResult NvcheckerResult)
forall a. a -> Action a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RunResult NvcheckerResult -> Action (RunResult NvcheckerResult))
-> RunResult NvcheckerResult -> Action (RunResult NvcheckerResult)
forall a b. (a -> b) -> a -> b
$ RunChanged
-> ByteString -> NvcheckerResult -> RunResult NvcheckerResult
forall value. RunChanged -> ByteString -> value -> RunResult value
RunResult RunChanged
runChanged ByteString
forall a. Monoid a => a
mempty NvcheckerResult
result

-- | Nvchecker rule without cache
-- Rule this rule by calling 'checkVersion''
oneShotRule :: Rules ()
oneShotRule :: Rules ()
oneShotRule = Rules (CheckVersion -> Action NvcheckerResult) -> Rules ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Rules (CheckVersion -> Action NvcheckerResult) -> Rules ())
-> Rules (CheckVersion -> Action NvcheckerResult) -> Rules ()
forall a b. (a -> b) -> a -> b
$
  (CheckVersion -> Action NvcheckerResult)
-> Rules (CheckVersion -> Action NvcheckerResult)
forall q a.
(RuleResult q ~ a, ShakeValue q, ShakeValue a, Partial) =>
(q -> Action a) -> Rules (q -> Action a)
addOracle ((CheckVersion -> Action NvcheckerResult)
 -> Rules (CheckVersion -> Action NvcheckerResult))
-> (CheckVersion -> Action NvcheckerResult)
-> Rules (CheckVersion -> Action NvcheckerResult)
forall a b. (a -> b) -> a -> b
$ \key :: CheckVersion
key@(CheckVersion VersionSource
versionSource NvcheckerOptions
options) -> do
    String -> Action ()
putInfo (String -> Action ())
-> (Doc Any -> String) -> Doc Any -> Action ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Any -> String
forall a. Show a => a -> String
show (Doc Any -> Action ()) -> Doc Any -> Action ()
forall a b. (a -> b) -> a -> b
$ CheckVersion -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. CheckVersion -> Doc ann
pretty CheckVersion
key
    Version
now <- PackageKey -> NvcheckerOptions -> VersionSource -> Action Version
runNvchecker (Text -> PackageKey
PackageKey Text
"pkg") NvcheckerOptions
options VersionSource
versionSource
    NvcheckerResult -> Action NvcheckerResult
forall a. a -> Action a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NvcheckerResult -> Action NvcheckerResult)
-> NvcheckerResult -> Action NvcheckerResult
forall a b. (a -> b) -> a -> b
$ Version -> Maybe Version -> Bool -> NvcheckerResult
NvcheckerResult Version
now Maybe Version
forall a. Maybe a
Nothing Bool
False

runNvchecker :: PackageKey -> NvcheckerOptions -> VersionSource -> Action Version
runNvchecker :: PackageKey -> NvcheckerOptions -> VersionSource -> Action Version
runNvchecker PackageKey
pkg NvcheckerOptions
options VersionSource
versionSource = (String -> Action Version) -> Action Version
forall a. (String -> Action a) -> Action a
withTempFile ((String -> Action Version) -> Action Version)
-> (String -> Action Version) -> Action Version
forall a b. (a -> b) -> a -> b
$ \String
config -> Action Version -> Action Version
forall a. Action a -> Action a
withRetry (Action Version -> Action Version)
-> Action Version -> Action Version
forall a b. (a -> b) -> a -> b
$ do
  Maybe String
mKeyfile <- Action (Maybe String)
getKeyfilePath
  let nvcheckerConfig :: String
nvcheckerConfig = Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Writer [Text] () -> [Text]
forall w a. Monoid w => Writer w a -> w
execWriter (Writer [Text] () -> [Text]) -> Writer [Text] () -> [Text]
forall a b. (a -> b) -> a -> b
$ PackageKey
-> NvcheckerOptions
-> Maybe String
-> VersionSource
-> Writer [Text] ()
genNvConfig PackageKey
pkg NvcheckerOptions
options Maybe String
mKeyfile VersionSource
versionSource
  String -> Action ()
putVerbose (String -> Action ()) -> String -> Action ()
forall a b. (a -> b) -> a -> b
$ String
"Generated nvchecker config for " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> PackageKey -> String
forall a. Show a => a -> String
show PackageKey
pkg String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
":" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
nvcheckerConfig
  String -> String -> Action ()
forall (m :: * -> *).
(MonadIO m, Partial) =>
String -> String -> m ()
writeFile' String
config String
nvcheckerConfig
  (CmdTime Double
t, Stdout String
out, CmdLine String
c) <- Action (CmdTime, Stdout String, CmdLine)
-> Action (CmdTime, Stdout String, CmdLine)
forall a. Action a -> Action a
quietly (Action (CmdTime, Stdout String, CmdLine)
 -> Action (CmdTime, Stdout String, CmdLine))
-> (String -> Action (CmdTime, Stdout String, CmdLine))
-> String
-> Action (CmdTime, Stdout String, CmdLine)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Action (CmdTime, Stdout String, CmdLine)
forall args r. (Partial, CmdArguments args) => args
cmd (String -> Action (CmdTime, Stdout String, CmdLine))
-> String -> Action (CmdTime, Stdout String, CmdLine)
forall a b. (a -> b) -> a -> b
$ String
"nvchecker --logger json -c " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
config
  String -> Action ()
putVerbose (String -> Action ()) -> String -> Action ()
forall a b. (a -> b) -> a -> b
$ String
"Finishing running " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
c String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
", took " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Double -> String
forall a. Show a => a -> String
show Double
t String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"s"
  case [String] -> [String]
forall a. [a] -> [a]
reverse ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$ String
out of
    (String
o : [String]
_) | Just NvcheckerRaw
raw <- ByteString -> Maybe NvcheckerRaw
forall a. FromJSON a => ByteString -> Maybe a
A.decodeStrict' (ByteString -> Maybe NvcheckerRaw)
-> ByteString -> Maybe NvcheckerRaw
forall a b. (a -> b) -> a -> b
$ String -> ByteString
BS.pack String
o -> case NvcheckerRaw
raw of
      NvcheckerSuccess Version
x -> Version -> Action Version
forall a. a -> Action a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Version
x
      NvcheckerError Text
err -> String -> Action Version
forall a. String -> Action a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Action Version) -> String -> Action Version
forall a b. (a -> b) -> a -> b
$ String
"Failed to run nvchecker: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
err
    [String]
_ -> String -> Action Version
forall a. String -> Action a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Action Version) -> String -> Action Version
forall a b. (a -> b) -> a -> b
$ String
"Failed to parse output from nvchecker: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
out

type BuildTOML = Writer [Text] ()

genNvConfig :: PackageKey -> NvcheckerOptions -> Maybe FilePath -> VersionSource -> BuildTOML
genNvConfig :: PackageKey
-> NvcheckerOptions
-> Maybe String
-> VersionSource
-> Writer [Text] ()
genNvConfig PackageKey
pkg NvcheckerOptions
options Maybe String
mKeyfile VersionSource
versionSource =
  case Maybe String
mKeyfile of
    Just String
keyfile -> do
      Text -> Writer [Text] () -> Writer [Text] ()
forall {m :: * -> *} {a}.
Monad m =>
Text -> WriterT [Text] m a -> WriterT [Text] m ()
table Text
"__config__" (Writer [Text] () -> Writer [Text] ())
-> Writer [Text] () -> Writer [Text] ()
forall a b. (a -> b) -> a -> b
$
        Text
"keyfile" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: String -> Text
T.pack String
keyfile
    Maybe String
_ -> () -> Writer [Text] ()
forall a. a -> WriterT [Text] Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    Writer [Text] () -> Writer [Text] () -> Writer [Text] ()
forall a b.
WriterT [Text] Identity a
-> WriterT [Text] Identity b -> WriterT [Text] Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Writer [Text] () -> Writer [Text] ()
forall {m :: * -> *} {a}.
Monad m =>
Text -> WriterT [Text] m a -> WriterT [Text] m ()
table
      (PackageKey -> Text
forall a b. Coercible a b => a -> b
coerce PackageKey
pkg)
      ( do
          VersionSource -> Writer [Text] ()
genVersionSource VersionSource
versionSource
          NvcheckerOptions -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
NvcheckerOptions -> WriterT [Text] m ()
genOptions NvcheckerOptions
options
      )
  where
    Text
key =: :: Text -> Text -> WriterT [Text] m ()
=: Text
x = [Text] -> WriterT [Text] m ()
forall w (m :: * -> *). (Monoid w, Monad m) => w -> WriterT w m ()
tell [Text
key Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" = " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quote Text
x]
    Text
key =:? :: Text -> Maybe Text -> WriterT [Text] m ()
=:? (Just Text
x) = Text
key Text -> Text -> WriterT [Text] m ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
x
    Text
_ =:? Maybe Text
_ = () -> WriterT [Text] m ()
forall a. a -> WriterT [Text] m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    table :: Text -> WriterT [Text] m a -> WriterT [Text] m ()
table Text
t WriterT [Text] m a
m = [Text] -> WriterT [Text] m ()
forall w (m :: * -> *). (Monoid w, Monad m) => w -> WriterT w m ()
tell [Text
"[" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
quote Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"]"] WriterT [Text] m () -> WriterT [Text] m a -> WriterT [Text] m a
forall a b.
WriterT [Text] m a -> WriterT [Text] m b -> WriterT [Text] m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> WriterT [Text] m a
m WriterT [Text] m a -> WriterT [Text] m () -> WriterT [Text] m ()
forall a b.
WriterT [Text] m a -> WriterT [Text] m b -> WriterT [Text] m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Text] -> WriterT [Text] m ()
forall w (m :: * -> *). (Monoid w, Monad m) => w -> WriterT w m ()
tell [Text
""]
    genVersionSource :: VersionSource -> Writer [Text] ()
genVersionSource = \case
      GitHubRelease {Text
_owner :: Text
_repo :: Text
_owner :: VersionSource -> Text
_repo :: VersionSource -> Text
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"github"
        Text
"github" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: (Text
_owner Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
_repo)
        Text
"use_latest_release" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"true"
      GitHubTag {Text
ListOptions
_owner :: VersionSource -> Text
_repo :: VersionSource -> Text
_owner :: Text
_repo :: Text
_listOptions :: ListOptions
_listOptions :: VersionSource -> ListOptions
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"github"
        Text
"github" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: (Text
_owner Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
_repo)
        Text
"use_max_tag" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"true"
        ListOptions -> Writer [Text] ()
forall {m :: * -> *}. Monad m => ListOptions -> WriterT [Text] m ()
genListOptions ListOptions
_listOptions
      Git {Text
Branch
_vurl :: Text
_vbranch :: Branch
_vurl :: VersionSource -> Text
_vbranch :: VersionSource -> Branch
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"git"
        Text
"git" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_vurl
        Text
"branch" Text -> Maybe Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Maybe Text -> WriterT [Text] m ()
=:? Branch -> Maybe Text
forall a b. Coercible a b => a -> b
coerce Branch
_vbranch
        Text
"use_commit" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"true"
      Aur {Text
_aur :: Text
_aur :: VersionSource -> Text
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"aur"
        Text
"aur" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_aur
        Text
"strip_release" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"true"
      ArchLinux {Text
_archpkg :: Text
_archpkg :: VersionSource -> Text
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"archpkg"
        Text
"archpkg" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_archpkg
        Text
"strip_release" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"true"
      Pypi {Text
_pypi :: Text
_pypi :: VersionSource -> Text
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"pypi"
        Text
"pypi" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_pypi
      Manual {Text
_manual :: Text
_manual :: VersionSource -> Text
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"manual"
        Text
"manual" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_manual
      Repology {Text
_repo :: VersionSource -> Text
_repology :: Text
_repo :: Text
_repology :: VersionSource -> Text
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"repology"
        Text
"repology" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_repology
        Text
"repo" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_repo
      Webpage {Text
ListOptions
_listOptions :: VersionSource -> ListOptions
_vurl :: VersionSource -> Text
_vurl :: Text
_regex :: Text
_listOptions :: ListOptions
_regex :: VersionSource -> Text
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"regex"
        Text
"url" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_vurl
        Text
"regex" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_regex
        ListOptions -> Writer [Text] ()
forall {m :: * -> *}. Monad m => ListOptions -> WriterT [Text] m ()
genListOptions ListOptions
_listOptions
      HttpHeader {Text
ListOptions
_listOptions :: VersionSource -> ListOptions
_vurl :: VersionSource -> Text
_regex :: VersionSource -> Text
_vurl :: Text
_regex :: Text
_listOptions :: ListOptions
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"httpheader"
        Text
"url" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_vurl
        Text
"regex" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_regex
        ListOptions -> Writer [Text] ()
forall {m :: * -> *}. Monad m => ListOptions -> WriterT [Text] m ()
genListOptions ListOptions
_listOptions
      OpenVsx {Text
_ovPublisher :: Text
_ovExtName :: Text
_ovPublisher :: VersionSource -> Text
_ovExtName :: VersionSource -> Text
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"openvsx"
        Text
"openvsx" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: (Text
_ovPublisher Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
_ovExtName)
      VscodeMarketplace {Text
_vsmPublisher :: Text
_vsmExtName :: Text
_vsmPublisher :: VersionSource -> Text
_vsmExtName :: VersionSource -> Text
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"vsmarketplace"
        Text
"vsmarketplace" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: (Text
_vsmPublisher Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
_vsmExtName)
      Cmd {Text
_vcmd :: Text
_vcmd :: VersionSource -> Text
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"cmd"
        Text
"cmd" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_vcmd
      Container {Text
ListOptions
_listOptions :: VersionSource -> ListOptions
_vcontainer :: Text
_listOptions :: ListOptions
_vcontainer :: VersionSource -> Text
..} -> do
        Text
"source" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
"container"
        Text
"container" Text -> Text -> Writer [Text] ()
forall {m :: * -> *}.
Monad m =>
Text -> Text -> WriterT [Text] m ()
=: Text
_vcontainer
        ListOptions -> Writer [Text] ()
forall {m :: * -> *}. Monad m => ListOptions -> WriterT [Text] m ()
genListOptions ListOptions
_listOptions
    genListOptions :: ListOptions -> WriterT [Text] m ()
genListOptions ListOptions {Maybe Text
Maybe VersionSortMethod
_includeRegex :: Maybe Text
_excludeRegex :: Maybe Text
_sortVersionKey :: Maybe VersionSortMethod
_ignored :: Maybe Text
_includeRegex :: ListOptions -> Maybe Text
_excludeRegex :: ListOptions -> Maybe Text
_sortVersionKey :: ListOptions -> Maybe VersionSortMethod
_ignored :: ListOptions -> Maybe Text
..} = do
      Text
"include_regex" Text -> Maybe Text -> WriterT [Text] m ()
forall {m :: * -> *}.
Monad m =>
Text -> Maybe Text -> WriterT [Text] m ()
=:? Maybe Text
_includeRegex
      Text
"exclude_regex" Text -> Maybe Text -> WriterT [Text] m ()
forall {m :: * -> *}.
Monad m =>
Text -> Maybe Text -> WriterT [Text] m ()
=:? Maybe Text
_excludeRegex
      Text
"sort_version_key" Text -> Maybe Text -> WriterT [Text] m ()
forall {m :: * -> *}.
Monad m =>
Text -> Maybe Text -> WriterT [Text] m ()
=:? (VersionSortMethod -> Text)
-> Maybe VersionSortMethod -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> Text
T.pack (String -> Text)
-> (VersionSortMethod -> String) -> VersionSortMethod -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VersionSortMethod -> String
forall a. Show a => a -> String
show) Maybe VersionSortMethod
_sortVersionKey
      Text
"ignored" Text -> Maybe Text -> WriterT [Text] m ()
forall {m :: * -> *}.
Monad m =>
Text -> Maybe Text -> WriterT [Text] m ()
=:? Maybe Text
_ignored
    genOptions :: NvcheckerOptions -> WriterT [Text] m ()
genOptions NvcheckerOptions {Maybe Text
_stripPrefix :: Maybe Text
_fromPattern :: Maybe Text
_toPattern :: Maybe Text
_stripPrefix :: NvcheckerOptions -> Maybe Text
_fromPattern :: NvcheckerOptions -> Maybe Text
_toPattern :: NvcheckerOptions -> Maybe Text
..} = do
      Text
"prefix" Text -> Maybe Text -> WriterT [Text] m ()
forall {m :: * -> *}.
Monad m =>
Text -> Maybe Text -> WriterT [Text] m ()
=:? Maybe Text
_stripPrefix
      Text
"from_pattern" Text -> Maybe Text -> WriterT [Text] m ()
forall {m :: * -> *}.
Monad m =>
Text -> Maybe Text -> WriterT [Text] m ()
=:? Maybe Text
_fromPattern
      Text
"to_pattern" Text -> Maybe Text -> WriterT [Text] m ()
forall {m :: * -> *}.
Monad m =>
Text -> Maybe Text -> WriterT [Text] m ()
=:? Maybe Text
_toPattern

-- | Run nvchecker given 'PackageKey'
-- Recording version changes and using stale version are available.
checkVersion :: VersionSource -> NvcheckerOptions -> PackageKey -> Action NvcheckerResult
checkVersion :: VersionSource
-> NvcheckerOptions -> PackageKey -> Action NvcheckerResult
checkVersion VersionSource
v NvcheckerOptions
o PackageKey
k = WithPackageKey CheckVersion -> Action NvcheckerResult
forall key value.
(Partial, RuleResult key ~ value, ShakeValue key,
 Typeable value) =>
key -> Action value
apply1 (WithPackageKey CheckVersion -> Action NvcheckerResult)
-> WithPackageKey CheckVersion -> Action NvcheckerResult
forall a b. (a -> b) -> a -> b
$ (CheckVersion, PackageKey) -> WithPackageKey CheckVersion
forall k. (k, PackageKey) -> WithPackageKey k
WithPackageKey (VersionSource -> NvcheckerOptions -> CheckVersion
CheckVersion VersionSource
v NvcheckerOptions
o, PackageKey
k)

-- | Run nvchecker without cache
checkVersion' :: VersionSource -> NvcheckerOptions -> Action NvcheckerResult
checkVersion' :: VersionSource -> NvcheckerOptions -> Action NvcheckerResult
checkVersion' VersionSource
v NvcheckerOptions
o = CheckVersion -> Action NvcheckerResult
forall q a.
(RuleResult q ~ a, ShakeValue q, ShakeValue a) =>
q -> Action a
askOracle (CheckVersion -> Action NvcheckerResult)
-> CheckVersion -> Action NvcheckerResult
forall a b. (a -> b) -> a -> b
$ VersionSource -> NvcheckerOptions -> CheckVersion
CheckVersion VersionSource
v NvcheckerOptions
o