nvfetcher-0.2.0.0: src/NvFetcher/Types.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
-- | Copyright: (c) 2021 berberman
-- SPDX-License-Identifier: MIT
-- Maintainer: berberman <berberman@yandex.com>
-- Stability: experimental
-- Portability: portable
--
-- Types used in this program.
module NvFetcher.Types
( -- * Common types
Version (..),
SHA256 (..),
NixExpr,
VersionChange (..),
WithPackageKey (..),
Core (..),
-- * Nvchecker types
VersionSource (..),
NvcheckerResult (..),
-- * Nix fetcher types
NixFetcher (..),
Prefetch (..),
PrefetchResult,
-- * Package types
PackageName,
PackageFetcher,
Package (..),
PackageKey (..),
)
where
import qualified Data.Aeson as A
import Data.Coerce (coerce)
import Data.Maybe (fromMaybe)
import Data.String (IsString)
import Data.Text (Text)
import qualified Data.Text as T
import Development.Shake
import Development.Shake.Classes
import GHC.Generics (Generic)
--------------------------------------------------------------------------------
-- | Package version
newtype Version = Version Text
deriving newtype (Eq, Show, Ord, IsString, Semigroup, Monoid, A.FromJSON, A.ToJSON)
deriving stock (Typeable, Generic)
deriving anyclass (Hashable, Binary, NFData)
-- | SHA 256 sum
newtype SHA256 = SHA256 Text
deriving newtype (Show, Eq)
deriving stock (Typeable, Generic)
deriving anyclass (Hashable, Binary, NFData)
-- | Version change of a package
--
-- >>> VersionChange "foo" Nothing "2.3.3"
-- foo: ∅ → 2.3.3
--
-- >>> VersionChange "bar" (Just "2.2.2") "2.3.3"
-- bar: 2.2.2 → 2.3.3
data VersionChange = VersionChange
{ vcName :: PackageName,
vcOld :: Maybe Version,
vcNew :: Version
}
deriving (Eq)
instance Show VersionChange where
show VersionChange {..} =
T.unpack $ vcName <> ": " <> fromMaybe "∅" (coerce vcOld) <> " → " <> coerce vcNew
-- | Nix expression
type NixExpr = Text
--------------------------------------------------------------------------------
-- | The input of nvchecker
data VersionSource
= GitHubRelease {_owner :: Text, _repo :: Text}
| Git {_vurl :: Text}
| Pypi {_pypi :: Text}
| ArchLinux {_archpkg :: Text}
| Aur {_aur :: Text}
| Manual {_manual :: Text}
| Repology {_repology :: Text, _repo :: Text}
deriving (Show, Typeable, Eq, Ord, Generic, Hashable, Binary, NFData)
-- | The result of running nvchecker
data NvcheckerResult = NvcheckerResult
{ nvNow :: Version,
-- | nvchecker doesn't give this value, but shake restores it from last run
nvOld :: Maybe Version
}
deriving (Show, Typeable, Eq, Generic, Hashable, Binary, NFData)
instance A.FromJSON NvcheckerResult where
parseJSON = A.withObject "NvcheckerResult" $ \o ->
NvcheckerResult <$> o A..: "version" <*> pure Nothing
type instance RuleResult VersionSource = NvcheckerResult
--------------------------------------------------------------------------------
-- | If the package is prefetched, then we can obtain the SHA256
data NixFetcher (k :: Prefetch)
= FetchGit
{ _furl :: Text,
_rev :: Version,
_branch :: Maybe Text,
_deepClone :: Bool,
_fetchSubmodules :: Bool,
_leaveDotGit :: Bool,
_sha256 :: PrefetchResult k
}
| FetchUrl {_furl :: Text, _sha256 :: PrefetchResult k}
deriving (Typeable, Generic)
-- | Prefetch status
data Prefetch = Fresh | Prefetched
-- | Prefetched fetchers hold hashes
type family PrefetchResult (k :: Prefetch) where
PrefetchResult Fresh = ()
PrefetchResult Prefetched = SHA256
type instance RuleResult (NixFetcher Fresh) = NixFetcher Prefetched
deriving instance Show (PrefetchResult k) => Show (NixFetcher k)
deriving instance Eq (PrefetchResult k) => Eq (NixFetcher k)
deriving instance Ord (PrefetchResult k) => Ord (NixFetcher k)
deriving instance Hashable (PrefetchResult k) => Hashable (NixFetcher k)
deriving instance Binary (PrefetchResult k) => Binary (NixFetcher k)
deriving instance NFData (PrefetchResult k) => NFData (NixFetcher k)
--------------------------------------------------------------------------------
-- | Package name, used in generating nix expr
type PackageName = Text
-- | How to create package source fetcher given a version
type PackageFetcher = Version -> NixFetcher Fresh
-- | A package is defined with:
--
-- 1. its name
-- 2. how to track its version
-- 3. how to fetch it as we have the version
--
-- /INVARIANT: 'Version' passed to 'PackageFetcher' MUST be used textually,/
-- /i.e. can only be concatenated with other strings,/
-- /in case we can't check the equality between fetcher functions./
data Package = Package
{ _pname :: PackageName,
_pversion :: VersionSource,
_pfetcher :: PackageFetcher
}
-- | Package key is the name of a package.
-- We use this type to index packages.
newtype PackageKey = PackageKey PackageName
deriving newtype (Eq, Show, Ord)
deriving stock (Typeable, Generic)
deriving anyclass (Hashable, Binary, NFData)
-- | The key type of nvfetcher rule. See "NvFetcher.Core"
data Core = Core
deriving (Eq, Show, Ord, Typeable, Generic, Hashable, Binary, NFData)
type instance RuleResult Core = NixExpr
--------------------------------------------------------------------------------
-- | Decorate a rule's key with 'PackageKey'
newtype WithPackageKey k = WithPackageKey (k, PackageKey)
deriving newtype (Eq, Hashable, Binary, NFData)
instance Show k => Show (WithPackageKey k) where
show (WithPackageKey (k, n)) = show k <> " (" <> show n <> ")"
type instance RuleResult (WithPackageKey k) = RuleResult k