Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement builtin for git fetcher #406

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions nix/sources.nix
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ let
else
pkgs.fetchzip { name = name'; inherit (spec) url sha256; };

fetch_git = name: spec:
fetch_git = pkgs: name: spec:
let
ref =
spec.ref or (
Expand Down Expand Up @@ -52,8 +52,9 @@ let
then { inherit submodules; }
else emptyArgWithWarning;
in
builtins.fetchGit
({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg);
if spec.builtin or true
then builtins.fetchGit ({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg)
else pkgs.fetchgit (builtins.removeAttrs spec ["type" "repo" "builtin" "branch" "tag" "ref"] // {url = spec.repo;});

fetch_local = spec: spec.path;

Expand Down Expand Up @@ -105,7 +106,7 @@ let
abort "ERROR: niv spec ${name} does not have a 'type' attribute"
else if spec.type == "file" then fetch_file pkgs name spec
else if spec.type == "tarball" then fetch_tarball pkgs name spec
else if spec.type == "git" then fetch_git name spec
else if spec.type == "git" then fetch_git pkgs name spec
else if spec.type == "local" then fetch_local spec
else if spec.type == "builtin-tarball" then fetch_builtin-tarball name
else if spec.type == "builtin-url" then fetch_builtin-url name
Expand Down
46 changes: 42 additions & 4 deletions src/Niv/Git/Cmd.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import Niv.Sources
import Niv.Update
import qualified Options.Applicative as Opts
import qualified Options.Applicative.Help.Pretty as Opts
import System.Exit (ExitCode (ExitSuccess))
import System.Exit (ExitCode (..))
import System.Process (readProcessWithExitCode)

gitCmd :: Cmd
Expand Down Expand Up @@ -152,18 +152,24 @@ gitUpdate ::
gitUpdate latestRev' defaultBranchAndRev' = proc () -> do
useOrSet "type" -< ("git" :: Box T.Text)
repository <- load "repo" -< ()
discoverRev <+> discoverRefAndRev -< repository
newRev <- discoverRev <+> discoverRefAndRev -< repository
deepClone <- loadDefault "deepClone" -< pure False
leaveDotGit <- loadDefault "leaveDotGit" -< pure False
fetchLfs <- loadDefault "fetchLFS" -< pure False
fetchSubmodules <- loadDefault "fetchDubmodules" -< pure False
hash <- run nixPrefetchGit' -< (,,,,,) <$> repository <*> newRev <*> deepClone <*> leaveDotGit <*> fetchLfs <*> fetchSubmodules
update "hash" -< hash -- TODO: make depend on builtin
returnA -< ()
where
discoverRefAndRev = proc repository -> do
branchAndRev <- run defaultBranchAndRev' -< repository
update "branch" -< fst <$> branchAndRev
update "rev" -< snd <$> branchAndRev
returnA -< ()
discoverRev = proc repository -> do
branch <- load "branch" -< ()
rev <- run' (uncurry latestRev') -< (,) <$> repository <*> branch
update "rev" -< rev
returnA -< ()
nixPrefetchGit' (a, b, c, d, e, f) = nixPrefetchGit a b c d e f -- uncurried version

-- | The "real" (IO) update
gitUpdate' :: Update () ()
Expand Down Expand Up @@ -265,3 +271,35 @@ abortGitBug args msg =
T.unwords ("command:" : "git" : args),
msg
]

nixPrefetchGit :: T.Text -> T.Text -> Bool -> Bool -> Bool -> Bool -> IO T.Text
nixPrefetchGit (T.unpack -> url) (T.unpack -> rev) deepClone leaveDotGit fetchLfs fetchSubmodules = do
(exitCode, stdout, stderr) <- runNixPrefetch
case exitCode of
ExitFailure _ -> abortNixPrefetchGitBug (T.pack <$> args) $ T.unlines ["stdout:" <> T.pack stdout, "stderr:" <> T.pack stderr]
ExitSuccess -> case getHash stdout of
Nothing -> abort "Could not decode output of 'nix-prefetch-git'."
Just hash -> pure hash
where
args =
["--deepClone" | deepClone]
<> ["--leave-dotGit" | leaveDotGit]
<> ["--fetch-lfs" | fetchLfs]
<> ["--fetch-submodules" | fetchSubmodules]
<> [url, rev]
runNixPrefetch = readProcessWithExitCode "nix-prefetch-git" args ""
getHash input = do
obj :: Aeson.Object <- Aeson.decodeStrict $ B8.pack input
case KM.lookup "hash" obj of
Just (Aeson.String hash) -> pure hash
_ -> Nothing

abortNixPrefetchGitBug :: [T.Text] -> T.Text -> IO a
abortNixPrefetchGitBug args msg =
abort $
bug $
T.unlines
[ "Could not read the output of 'git'.",
T.unwords ("command:" : "nix-prefetch-git" : args),
msg
]
13 changes: 9 additions & 4 deletions src/Niv/Update.hs
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,9 @@ runUpdate' attrs = \case
UpdateReady res -> pure res
UpdateNeedMore next' -> next' v
Load k -> pure $
UpdateReady $ do
case HMS.lookup k attrs of
Just (_, v') -> UpdateSuccess attrs v'
Nothing -> UpdateFailed $ FailNoSuchKey k
UpdateReady $ case HMS.lookup k attrs of
Nothing -> UpdateFailed $ FailNoSuchKey k
Just (_, v) -> UpdateSuccess attrs v
First a -> do
runUpdate' attrs a >>= \case
UpdateReady (UpdateFailed e) -> pure $ UpdateReady $ UpdateFailed e
Expand Down Expand Up @@ -316,6 +315,12 @@ check = Check
load :: (FromJSON a) => T.Text -> Update () (Box a)
load k = Load k >>> arr (decodeBox $ "When loading key " <> k)

maybeLoad :: (FromJSON a) => T.Text -> Update () (Box (Maybe a))
maybeLoad k = Plus (load k) $ arr $ const $ pure Nothing

loadDefault :: (FromJSON a) => T.Text -> Update (Box a) (Box a)
loadDefault k = Plus ((arr $ const ()) >>> load k) Id

-- TODO: should input really be Box?
useOrSet :: (JSON a) => T.Text -> Update (Box a) (Box a)
useOrSet k =
Expand Down
Loading