{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ViewPatterns #-}

-- | Copyright: (c) 2021-2022 berberman
-- SPDX-License-Identifier: MIT
-- Maintainer: berberman <berberman@yandex.com>
-- Stability: experimental
-- Portability: portable
--
-- 'NixFetcher' is used to describe how to fetch package sources.
--
-- There are three types of fetchers overall:
--
-- 1. 'FetchGit' -- nix-prefetch fetchgit
-- 2. 'FetchGitHub' -- nix-prefetch fetchFromGitHub
-- 3. 'FetchUrl' -- nix-prefetch fetchurl
--
-- As you can see the type signature of 'prefetch':
-- a fetcher will be filled with the fetch result (hash) after the prefetch.
module NvFetcher.NixFetcher
  ( -- * Types
    RunFetch (..),
    ForceFetch (..),
    NixFetcher (..),
    FetchStatus (..),
    FetchResult,

    -- * Rules
    prefetchRule,
    prefetch,

    -- * Functions
    gitHubFetcher,
    pypiFetcher,
    gitHubReleaseFetcher,
    gitHubReleaseFetcher',
    gitFetcher,
    urlFetcher,
    openVsxFetcher,
    vscodeMarketplaceFetcher,
    tarballFetcher,
  )
where

import Control.Monad (void, when)
import qualified Data.Aeson as A
import Data.Coerce (coerce)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import Development.Shake
import GHC.Generics (Generic)
import NeatInterpolation (trimming)
import NvFetcher.Types
import NvFetcher.Types.ShakeExtras
import Prettyprinter (pretty, (<+>))

--------------------------------------------------------------------------------

runFetcher :: NixFetcher Fresh -> Action (NixFetcher Fetched)
runFetcher :: NixFetcher 'Fresh -> Action (NixFetcher 'Fetched)
runFetcher = \case
  FetchGit {Bool
Maybe Text
Text
FetchResult Checksum 'Fresh
Version
_sha256 :: forall (k :: FetchStatus). NixFetcher k -> FetchResult Checksum k
_name :: forall (k :: FetchStatus). NixFetcher k -> Maybe Text
_leaveDotGit :: forall (k :: FetchStatus). NixFetcher k -> Bool
_fetchSubmodules :: forall (k :: FetchStatus). NixFetcher k -> Bool
_deepClone :: forall (k :: FetchStatus). NixFetcher k -> Bool
_rev :: forall (k :: FetchStatus). NixFetcher k -> Version
_furl :: forall (k :: FetchStatus). NixFetcher k -> Text
_sha256 :: FetchResult Checksum 'Fresh
_name :: Maybe Text
_leaveDotGit :: Bool
_fetchSubmodules :: Bool
_deepClone :: Bool
_rev :: Version
_furl :: Text
..} -> do
    (CmdTime Double
t, Stdout (ByteString -> Text
T.decodeUtf8 -> Text
out), CmdLine String
c) <-
      forall a. Action a -> Action a
quietly forall a b. (a -> b) -> a -> b
$
        forall r.
(Partial, CmdResult r) =>
[CmdOption] -> String -> [String] -> Action r
command [Bool -> CmdOption
EchoStderr Bool
False] String
"nix-prefetch" forall a b. (a -> b) -> a -> b
$
          [String
"fetchgit"]
            forall a. Semigroup a => a -> a -> a
<> [String
"--url", Text -> String
T.unpack Text
_furl]
            forall a. Semigroup a => a -> a -> a
<> [String
"--rev", Text -> String
T.unpack forall a b. (a -> b) -> a -> b
$ coerce :: forall a b. Coercible a b => a -> b
coerce Version
_rev]
            forall a. Semigroup a => a -> a -> a
<> [String
"--fetchSubmodules" | Bool
_fetchSubmodules]
            forall a. Semigroup a => a -> a -> a
<> [String
"--deepClone" | Bool
_deepClone]
            forall a. Semigroup a => a -> a -> a
<> [String
"--leaveDotGit" | Bool
_leaveDotGit]
    String -> Action ()
putVerbose forall a b. (a -> b) -> a -> b
$ String
"Finishing running " forall a. Semigroup a => a -> a -> a
<> String
c forall a. Semigroup a => a -> a -> a
<> String
", took " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Double
t forall a. Semigroup a => a -> a -> a
<> String
"s"
    case forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null) forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ Text -> [Text]
T.lines Text
out of
      [Text
x] -> forall (f :: * -> *) a. Applicative f => a -> f a
pure FetchGit {_sha256 :: FetchResult Checksum 'Fetched
_sha256 = coerce :: forall a b. Coercible a b => a -> b
coerce Text
x, Bool
Maybe Text
Text
Version
_name :: Maybe Text
_leaveDotGit :: Bool
_fetchSubmodules :: Bool
_deepClone :: Bool
_rev :: Version
_furl :: Text
_name :: Maybe Text
_leaveDotGit :: Bool
_fetchSubmodules :: Bool
_deepClone :: Bool
_rev :: Version
_furl :: Text
..}
      [Text]
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Failed to parse output from nix-prefetch: " forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
out
  FetchGitHub {Bool
Maybe Text
Text
FetchResult Checksum 'Fresh
Version
_frepo :: forall (k :: FetchStatus). NixFetcher k -> Text
_fowner :: forall (k :: FetchStatus). NixFetcher k -> Text
_sha256 :: FetchResult Checksum 'Fresh
_name :: Maybe Text
_leaveDotGit :: Bool
_fetchSubmodules :: Bool
_deepClone :: Bool
_rev :: Version
_frepo :: Text
_fowner :: Text
_sha256 :: forall (k :: FetchStatus). NixFetcher k -> FetchResult Checksum k
_name :: forall (k :: FetchStatus). NixFetcher k -> Maybe Text
_leaveDotGit :: forall (k :: FetchStatus). NixFetcher k -> Bool
_fetchSubmodules :: forall (k :: FetchStatus). NixFetcher k -> Bool
_deepClone :: forall (k :: FetchStatus). NixFetcher k -> Bool
_rev :: forall (k :: FetchStatus). NixFetcher k -> Version
..} -> do
    (CmdTime Double
t, Stdout (ByteString -> Text
T.decodeUtf8 -> Text
out), CmdLine String
c) <-
      forall a. Action a -> Action a
quietly forall a b. (a -> b) -> a -> b
$
        forall r.
(Partial, CmdResult r) =>
[CmdOption] -> String -> [String] -> Action r
command [Bool -> CmdOption
EchoStderr Bool
False] String
"nix-prefetch" forall a b. (a -> b) -> a -> b
$
          [String
"fetchFromGitHub"]
            forall a. Semigroup a => a -> a -> a
<> [String
"--owner", Text -> String
T.unpack Text
_fowner]
            forall a. Semigroup a => a -> a -> a
<> [String
"--repo", Text -> String
T.unpack Text
_frepo]
            forall a. Semigroup a => a -> a -> a
<> [String
"--rev", Text -> String
T.unpack forall a b. (a -> b) -> a -> b
$ coerce :: forall a b. Coercible a b => a -> b
coerce Version
_rev]
            forall a. Semigroup a => a -> a -> a
<> [String
"--fetchSubmodules" | Bool
_fetchSubmodules]
            forall a. Semigroup a => a -> a -> a
<> [String
"--deepClone" | Bool
_deepClone]
            forall a. Semigroup a => a -> a -> a
<> [String
"--leaveDotGit" | Bool
_leaveDotGit]
    String -> Action ()
putVerbose forall a b. (a -> b) -> a -> b
$ String
"Finishing running " forall a. Semigroup a => a -> a -> a
<> String
c forall a. Semigroup a => a -> a -> a
<> String
", took " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Double
t forall a. Semigroup a => a -> a -> a
<> String
"s"
    case forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null) forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ Text -> [Text]
T.lines Text
out of
      [Text
x] -> forall (f :: * -> *) a. Applicative f => a -> f a
pure FetchGitHub {_sha256 :: FetchResult Checksum 'Fetched
_sha256 = coerce :: forall a b. Coercible a b => a -> b
coerce Text
x, Bool
Maybe Text
Text
Version
_frepo :: Text
_fowner :: Text
_name :: Maybe Text
_leaveDotGit :: Bool
_fetchSubmodules :: Bool
_deepClone :: Bool
_rev :: Version
_frepo :: Text
_fowner :: Text
_name :: Maybe Text
_leaveDotGit :: Bool
_fetchSubmodules :: Bool
_deepClone :: Bool
_rev :: Version
..}
      [Text]
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Failed to parse output from nix-prefetch: " forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
out
  FetchUrl {Maybe Text
Text
FetchResult Checksum 'Fresh
_sha256 :: FetchResult Checksum 'Fresh
_name :: Maybe Text
_furl :: Text
_sha256 :: forall (k :: FetchStatus). NixFetcher k -> FetchResult Checksum k
_name :: forall (k :: FetchStatus). NixFetcher k -> Maybe Text
_furl :: forall (k :: FetchStatus). NixFetcher k -> Text
..} -> do
    (CmdTime Double
t, Stdout (ByteString -> Text
T.decodeUtf8 -> Text
out), CmdLine String
c) <-
      forall a. Action a -> Action a
quietly forall a b. (a -> b) -> a -> b
$
        forall r.
(Partial, CmdResult r) =>
[CmdOption] -> String -> [String] -> Action r
command [Bool -> CmdOption
EchoStderr Bool
False] String
"nix-prefetch" [String
"fetchurl", String
"--url", Text -> String
T.unpack Text
_furl]
    String -> Action ()
putVerbose forall a b. (a -> b) -> a -> b
$ String
"Finishing running " forall a. Semigroup a => a -> a -> a
<> String
c forall a. Semigroup a => a -> a -> a
<> String
", took " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Double
t forall a. Semigroup a => a -> a -> a
<> String
"s"
    case forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null) forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ Text -> [Text]
T.lines Text
out of
      [Text
x] -> forall (f :: * -> *) a. Applicative f => a -> f a
pure FetchUrl {_sha256 :: FetchResult Checksum 'Fetched
_sha256 = coerce :: forall a b. Coercible a b => a -> b
coerce Text
x, Maybe Text
Text
_name :: Maybe Text
_furl :: Text
_name :: Maybe Text
_furl :: Text
..}
      [Text]
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Failed to parse output from nix-prefetch: " forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
out
  FetchTarball {Text
FetchResult Checksum 'Fresh
_sha256 :: FetchResult Checksum 'Fresh
_furl :: Text
_sha256 :: forall (k :: FetchStatus). NixFetcher k -> FetchResult Checksum k
_furl :: forall (k :: FetchStatus). NixFetcher k -> Text
..} -> do
    (CmdTime Double
t, Stdout (ByteString -> Text
T.decodeUtf8 -> Text
out), CmdLine String
c) <-
      forall a. Action a -> Action a
quietly forall a b. (a -> b) -> a -> b
$
        forall r.
(Partial, CmdResult r) =>
[CmdOption] -> String -> [String] -> Action r
command [Bool -> CmdOption
EchoStderr Bool
False] String
"nix-prefetch" [String
"fetchTarball", String
"--url", Text -> String
T.unpack Text
_furl]
    String -> Action ()
putVerbose forall a b. (a -> b) -> a -> b
$ String
"Finishing running " forall a. Semigroup a => a -> a -> a
<> String
c forall a. Semigroup a => a -> a -> a
<> String
", took " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Double
t forall a. Semigroup a => a -> a -> a
<> String
"s"
    case forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null) forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ Text -> [Text]
T.lines Text
out of
      [Text
x] -> forall (f :: * -> *) a. Applicative f => a -> f a
pure FetchTarball {_sha256 :: FetchResult Checksum 'Fetched
_sha256 = coerce :: forall a b. Coercible a b => a -> b
coerce Text
x, Text
_furl :: Text
_furl :: Text
..}
      [Text]
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Failed to parse output from nix-prefetch: " forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
out
  FetchDocker {Maybe Bool
Maybe Text
Text
FetchResult ContainerDigest 'Fresh
FetchResult Checksum 'Fresh
_tlsVerify :: forall (k :: FetchStatus). NixFetcher k -> Maybe Bool
_finalImageTag :: forall (k :: FetchStatus). NixFetcher k -> Maybe Text
_finalImageName :: forall (k :: FetchStatus). NixFetcher k -> Maybe Text
_farch :: forall (k :: FetchStatus). NixFetcher k -> Maybe Text
_fos :: forall (k :: FetchStatus). NixFetcher k -> Maybe Text
_imageDigest :: forall (k :: FetchStatus).
NixFetcher k -> FetchResult ContainerDigest k
_imageTag :: forall (k :: FetchStatus). NixFetcher k -> Text
_imageName :: forall (k :: FetchStatus). NixFetcher k -> Text
_tlsVerify :: Maybe Bool
_finalImageTag :: Maybe Text
_finalImageName :: Maybe Text
_farch :: Maybe Text
_fos :: Maybe Text
_sha256 :: FetchResult Checksum 'Fresh
_imageDigest :: FetchResult ContainerDigest 'Fresh
_imageTag :: Text
_imageName :: Text
_sha256 :: forall (k :: FetchStatus). NixFetcher k -> FetchResult Checksum k
..} -> do
    (CmdTime Double
t, Stdout ByteString
out, CmdLine String
c) <-
      forall a. Action a -> Action a
quietly forall a b. (a -> b) -> a -> b
$
        forall r.
(Partial, CmdResult r) =>
[CmdOption] -> String -> [String] -> Action r
command [Bool -> CmdOption
EchoStderr Bool
False] String
"nix-prefetch-docker" forall a b. (a -> b) -> a -> b
$
          [ String
"--json",
            Text -> String
T.unpack Text
_imageName,
            Text -> String
T.unpack Text
_imageTag
          ]
            forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[String
"--os", Text -> String
T.unpack Text
os] | Just Text
os <- [Maybe Text
_fos]]
            forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[String
"--arch", Text -> String
T.unpack Text
arch] | Just Text
arch <- [Maybe Text
_farch]]
    String -> Action ()
putVerbose forall a b. (a -> b) -> a -> b
$ String
"Finishing running " forall a. Semigroup a => a -> a -> a
<> String
c forall a. Semigroup a => a -> a -> a
<> String
",, took " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Double
t forall a. Semigroup a => a -> a -> a
<> String
"s"
    case forall a. FromJSON a => ByteString -> Either String a
A.eitherDecode ByteString
out of
      Right FetchedContainer {ContainerDigest
Checksum
sha256 :: FetchedContainer -> Checksum
imageDigest :: FetchedContainer -> ContainerDigest
sha256 :: Checksum
imageDigest :: ContainerDigest
..} ->
        forall (f :: * -> *) a. Applicative f => a -> f a
pure FetchDocker {_sha256 :: FetchResult Checksum 'Fetched
_sha256 = Checksum
sha256, _imageDigest :: FetchResult ContainerDigest 'Fetched
_imageDigest = ContainerDigest
imageDigest, Maybe Bool
Maybe Text
Text
_tlsVerify :: Maybe Bool
_finalImageTag :: Maybe Text
_finalImageName :: Maybe Text
_farch :: Maybe Text
_fos :: Maybe Text
_imageTag :: Text
_imageName :: Text
_tlsVerify :: Maybe Bool
_finalImageTag :: Maybe Text
_finalImageName :: Maybe Text
_farch :: Maybe Text
_fos :: Maybe Text
_imageTag :: Text
_imageName :: Text
..}
      Left String
e -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Failed to parse output from nix-prefetch-docker as JSON: " forall a. Semigroup a => a -> a -> a
<> String
e

data FetchedContainer = FetchedContainer
  { FetchedContainer -> ContainerDigest
imageDigest :: ContainerDigest,
    FetchedContainer -> Checksum
sha256 :: Checksum
  }
  deriving (Int -> FetchedContainer -> ShowS
[FetchedContainer] -> ShowS
FetchedContainer -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FetchedContainer] -> ShowS
$cshowList :: [FetchedContainer] -> ShowS
show :: FetchedContainer -> String
$cshow :: FetchedContainer -> String
showsPrec :: Int -> FetchedContainer -> ShowS
$cshowsPrec :: Int -> FetchedContainer -> ShowS
Show, forall x. Rep FetchedContainer x -> FetchedContainer
forall x. FetchedContainer -> Rep FetchedContainer x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep FetchedContainer x -> FetchedContainer
$cfrom :: forall x. FetchedContainer -> Rep FetchedContainer x
Generic, Value -> Parser [FetchedContainer]
Value -> Parser FetchedContainer
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [FetchedContainer]
$cparseJSONList :: Value -> Parser [FetchedContainer]
parseJSON :: Value -> Parser FetchedContainer
$cparseJSON :: Value -> Parser FetchedContainer
A.FromJSON)

pypiUrl :: Text -> Version -> Text
pypiUrl :: Text -> Version -> Text
pypiUrl Text
pypi (coerce :: forall a b. Coercible a b => a -> b
coerce -> Text
ver) =
  let h :: Text
h = Char -> Text -> Text
T.cons (Text -> Char
T.head Text
pypi) Text
""
   in [trimming|https://pypi.io/packages/source/$h/$pypi/$pypi-$ver.tar.gz|]

--------------------------------------------------------------------------------

-- | Rules of nix fetcher
prefetchRule :: Rules ()
prefetchRule :: Rules ()
prefetchRule = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$
  forall q a.
(RuleResult q ~ a, ShakeValue q, ShakeValue a, Partial) =>
(q -> Action a) -> Rules (q -> Action a)
addOracleCache forall a b. (a -> b) -> a -> b
$ \(RunFetch ForceFetch
force NixFetcher 'Fresh
f) -> do
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ForceFetch
force forall a. Eq a => a -> a -> Bool
== ForceFetch
ForceFetch) Action ()
alwaysRerun
    String -> Action ()
putInfo forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ Doc Any
"#" forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Pretty a => a -> Doc ann
pretty NixFetcher 'Fresh
f
    forall a. Action a -> Action a
withRetry forall a b. (a -> b) -> a -> b
$ NixFetcher 'Fresh -> Action (NixFetcher 'Fetched)
runFetcher NixFetcher 'Fresh
f

-- | Run nix fetcher
prefetch :: NixFetcher Fresh -> ForceFetch -> Action (NixFetcher Fetched)
prefetch :: NixFetcher 'Fresh -> ForceFetch -> Action (NixFetcher 'Fetched)
prefetch NixFetcher 'Fresh
f ForceFetch
force = forall q a.
(RuleResult q ~ a, ShakeValue q, ShakeValue a) =>
q -> Action a
askOracle forall a b. (a -> b) -> a -> b
$ ForceFetch -> NixFetcher 'Fresh -> RunFetch
RunFetch ForceFetch
force NixFetcher 'Fresh
f

--------------------------------------------------------------------------------

-- | Create a fetcher from git url
gitFetcher :: Text -> PackageFetcher
gitFetcher :: Text -> PackageFetcher
gitFetcher Text
furl Version
rev = forall (k :: FetchStatus).
Text
-> Version
-> Bool
-> Bool
-> Bool
-> Maybe Text
-> FetchResult Checksum k
-> NixFetcher k
FetchGit Text
furl Version
rev Bool
False Bool
False Bool
False forall a. Maybe a
Nothing ()

-- | Create a fetcher from github repo
gitHubFetcher ::
  -- | owner and repo
  (Text, Text) ->
  PackageFetcher
gitHubFetcher :: (Text, Text) -> PackageFetcher
gitHubFetcher (Text
owner, Text
repo) Version
rev = forall (k :: FetchStatus).
Text
-> Text
-> Version
-> Bool
-> Bool
-> Bool
-> Maybe Text
-> FetchResult Checksum k
-> NixFetcher k
FetchGitHub Text
owner Text
repo Version
rev Bool
False Bool
False Bool
False forall a. Maybe a
Nothing ()

-- | Create a fetcher from pypi
pypiFetcher :: Text -> PackageFetcher
pypiFetcher :: Text -> PackageFetcher
pypiFetcher Text
p Version
v = Text -> NixFetcher 'Fresh
urlFetcher forall a b. (a -> b) -> a -> b
$ Text -> Version -> Text
pypiUrl Text
p Version
v

-- | Create a fetcher from github release
gitHubReleaseFetcher ::
  -- | owner and repo
  (Text, Text) ->
  -- | file name
  Text ->
  PackageFetcher
gitHubReleaseFetcher :: (Text, Text) -> Text -> PackageFetcher
gitHubReleaseFetcher (Text
owner, Text
repo) Text
fp = (Text, Text) -> (Version -> Text) -> PackageFetcher
gitHubReleaseFetcher' (Text
owner, Text
repo) forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const Text
fp

-- | Create a fetcher from github release
gitHubReleaseFetcher' ::
  -- | owner and repo
  (Text, Text) ->
  -- | file name computed from version
  (Version -> Text) ->
  PackageFetcher
gitHubReleaseFetcher' :: (Text, Text) -> (Version -> Text) -> PackageFetcher
gitHubReleaseFetcher' (Text
owner, Text
repo) Version -> Text
f (coerce :: forall a b. Coercible a b => a -> b
coerce -> Text
ver) =
  let fp :: Text
fp = Version -> Text
f forall a b. (a -> b) -> a -> b
$ coerce :: forall a b. Coercible a b => a -> b
coerce Text
ver
   in Text -> NixFetcher 'Fresh
urlFetcher
        [trimming|https://github.com/$owner/$repo/releases/download/$ver/$fp|]

-- | Create a fetcher from url
urlFetcher :: Text -> NixFetcher Fresh
urlFetcher :: Text -> NixFetcher 'Fresh
urlFetcher Text
url = forall (k :: FetchStatus).
Text -> Maybe Text -> FetchResult Checksum k -> NixFetcher k
FetchUrl Text
url forall a. Maybe a
Nothing ()

-- | Create a fetcher from openvsx
openVsxFetcher ::
  -- | publisher and extension name
  (Text, Text) ->
  PackageFetcher
openVsxFetcher :: (Text, Text) -> PackageFetcher
openVsxFetcher (Text
publisher, Text
extName) (coerce :: forall a b. Coercible a b => a -> b
coerce -> Text
ver) =
  forall (k :: FetchStatus).
Text -> Maybe Text -> FetchResult Checksum k -> NixFetcher k
FetchUrl
    [trimming|https://open-vsx.org/api/$publisher/$extName/$ver/file/$publisher.$extName-$ver.vsix|]
    (forall a. a -> Maybe a
Just [trimming|$extName-$ver.zip|])
    ()

-- | Create a fetcher from vscode marketplace
vscodeMarketplaceFetcher ::
  -- | publisher and extension name
  (Text, Text) ->
  PackageFetcher
vscodeMarketplaceFetcher :: (Text, Text) -> PackageFetcher
vscodeMarketplaceFetcher (Text
publisher, Text
extName) (coerce :: forall a b. Coercible a b => a -> b
coerce -> Text
ver) =
  forall (k :: FetchStatus).
Text -> Maybe Text -> FetchResult Checksum k -> NixFetcher k
FetchUrl
    [trimming|https://$publisher.gallery.vsassets.io/_apis/public/gallery/publisher/$publisher/extension/$extName/$ver/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage|]
    (forall a. a -> Maybe a
Just [trimming|$extName-$ver.zip|])
    ()

-- | Create a fetcher from url, using fetchTarball
tarballFetcher :: Text -> NixFetcher Fresh
tarballFetcher :: Text -> NixFetcher 'Fresh
tarballFetcher Text
url = forall (k :: FetchStatus).
Text -> FetchResult Checksum k -> NixFetcher k
FetchTarball Text
url ()