Add fetchgit builtin
The function builtins.fetchgit fetches Git repositories at evaluation
time, similar to builtins.fetchTarball. (Perhaps the name should be
changed, being confusing with respect to Nixpkgs's fetchgit function,
with works at build time.)
Example:
  (import (builtins.fetchgit git://github.com/NixOS/nixpkgs) {}).hello
or
  (import (builtins.fetchgit {
    url = git://github.com/NixOS/nixpkgs-channels;
    rev = "nixos-16.03";
  }) {}).hello
Note that the result does not contain a .git directory.
			
			
This commit is contained in:
		
							parent
							
								
									83258225e6
								
							
						
					
					
						commit
						38539b943a
					
				
					 2 changed files with 78 additions and 1 deletions
				
			
		
							
								
								
									
										77
									
								
								src/libexpr/primops/fetchgit.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/libexpr/primops/fetchgit.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,77 @@ | |||
| #include "primops.hh" | ||||
| #include "eval-inline.hh" | ||||
| #include "download.hh" | ||||
| #include "store-api.hh" | ||||
| 
 | ||||
| namespace nix { | ||||
| 
 | ||||
| static void prim_fetchgit(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||
| { | ||||
|     // FIXME: cut&paste from fetch().
 | ||||
|     if (state.restricted) throw Error("‘fetchgit’ is not allowed in restricted mode"); | ||||
| 
 | ||||
|     std::string url; | ||||
|     std::string rev = "master"; | ||||
| 
 | ||||
|     state.forceValue(*args[0]); | ||||
| 
 | ||||
|     if (args[0]->type == tAttrs) { | ||||
| 
 | ||||
|         state.forceAttrs(*args[0], pos); | ||||
| 
 | ||||
|         for (auto & attr : *args[0]->attrs) { | ||||
|             string name(attr.name); | ||||
|             if (name == "url") | ||||
|                 url = state.forceStringNoCtx(*attr.value, *attr.pos); | ||||
|             else if (name == "rev") | ||||
|                 rev = state.forceStringNoCtx(*attr.value, *attr.pos); | ||||
|             else | ||||
|                 throw EvalError(format("unsupported argument ‘%1%’ to ‘fetchgit’, at %3%") % attr.name % attr.pos); | ||||
|         } | ||||
| 
 | ||||
|         if (url.empty()) | ||||
|             throw EvalError(format("‘url’ argument required, at %1%") % pos); | ||||
| 
 | ||||
|     } else | ||||
|         url = state.forceStringNoCtx(*args[0], pos); | ||||
| 
 | ||||
|     if (!isUri(url)) | ||||
|         throw EvalError(format("‘%s’ is not a valid URI, at %s") % url % pos); | ||||
| 
 | ||||
|     Path cacheDir = getCacheDir() + "/nix/git"; | ||||
| 
 | ||||
|     if (!pathExists(cacheDir)) { | ||||
|         createDirs(cacheDir); | ||||
|         runProgram("git", true, { "init", "--bare", cacheDir }); | ||||
|     } | ||||
| 
 | ||||
|     Activity act(*logger, lvlInfo, format("fetching Git repository ‘%s’") % url); | ||||
| 
 | ||||
|     std::string localRef = "pid-" + std::to_string(getpid()); | ||||
|     Path localRefFile = cacheDir + "/refs/heads/" + localRef; | ||||
| 
 | ||||
|     runProgram("git", true, { "-C", cacheDir, "fetch", url, rev + ":" + localRef }); | ||||
| 
 | ||||
|     std::string commitHash = chomp(readFile(localRefFile)); | ||||
| 
 | ||||
|     unlink(localRefFile.c_str()); | ||||
| 
 | ||||
|     debug(format("got revision ‘%s’") % commitHash); | ||||
| 
 | ||||
|     // FIXME: should pipe this, or find some better way to extract a
 | ||||
|     // revision.
 | ||||
|     auto tar = runProgram("git", true, { "-C", cacheDir, "archive", commitHash }); | ||||
| 
 | ||||
|     Path tmpDir = createTempDir(); | ||||
|     AutoDelete delTmpDir(tmpDir, true); | ||||
| 
 | ||||
|     runProgram("tar", true, { "x", "-C", tmpDir }, tar); | ||||
| 
 | ||||
|     Path storePath = state.store->addToStore("git-export", tmpDir); | ||||
| 
 | ||||
|     mkString(v, storePath, PathSet({storePath})); | ||||
| } | ||||
| 
 | ||||
| static RegisterPrimOp r("__fetchgit", 1, prim_fetchgit); | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue