at master 4.7 kB view raw
1{ 2 lib, 3 repoRevToNameMaybe, 4 fetchgit, 5 fetchzip, 6}: 7 8lib.makeOverridable ( 9 { 10 owner, 11 repo, 12 tag ? null, 13 rev ? null, 14 name ? repoRevToNameMaybe repo (lib.revOrTag rev tag) "github", 15 fetchSubmodules ? false, 16 leaveDotGit ? null, 17 deepClone ? false, 18 private ? false, 19 forceFetchGit ? false, 20 fetchLFS ? false, 21 sparseCheckout ? [ ], 22 githubBase ? "github.com", 23 varPrefix ? null, 24 meta ? { }, 25 ... # For hash agility 26 }@args: 27 28 assert ( 29 lib.assertMsg (lib.xor (tag == null) ( 30 rev == null 31 )) "fetchFromGitHub requires one of either `rev` or `tag` to be provided (not both)." 32 ); 33 34 let 35 36 position = ( 37 if args.meta.description or null != null then 38 builtins.unsafeGetAttrPos "description" args.meta 39 else if tag != null then 40 builtins.unsafeGetAttrPos "tag" args 41 else 42 builtins.unsafeGetAttrPos "rev" args 43 ); 44 baseUrl = "https://${githubBase}/${owner}/${repo}"; 45 newMeta = 46 meta 47 // { 48 homepage = meta.homepage or baseUrl; 49 } 50 // lib.optionalAttrs (position != null) { 51 # to indicate where derivation originates, similar to make-derivation.nix's mkDerivation 52 position = "${position.file}:${toString position.line}"; 53 }; 54 passthruAttrs = removeAttrs args [ 55 "owner" 56 "repo" 57 "tag" 58 "rev" 59 "fetchSubmodules" 60 "forceFetchGit" 61 "private" 62 "githubBase" 63 "varPrefix" 64 ]; 65 varBase = "NIX${lib.optionalString (varPrefix != null) "_${varPrefix}"}_GITHUB_PRIVATE_"; 66 useFetchGit = 67 fetchSubmodules 68 || (leaveDotGit == true) 69 || deepClone 70 || forceFetchGit 71 || fetchLFS 72 || (sparseCheckout != [ ]); 73 # We prefer fetchzip in cases we don't need submodules as the hash 74 # is more stable in that case. 75 fetcher = 76 if useFetchGit then 77 fetchgit 78 # fetchzip may not be overridable when using external tools, for example nix-prefetch 79 else if fetchzip ? override then 80 fetchzip.override { withUnzip = false; } 81 else 82 fetchzip; 83 privateAttrs = lib.optionalAttrs private { 84 netrcPhase = 85 # When using private repos: 86 # - Fetching with git works using https://github.com but not with the GitHub API endpoint 87 # - Fetching a tarball from a private repo requires to use the GitHub API endpoint 88 let 89 machineName = if githubBase == "github.com" && !useFetchGit then "api.github.com" else githubBase; 90 in 91 '' 92 if [ -z "''$${varBase}USERNAME" -o -z "''$${varBase}PASSWORD" ]; then 93 echo "Error: Private fetchFromGitHub requires the nix building process (nix-daemon in multi user mode) to have the ${varBase}USERNAME and ${varBase}PASSWORD env vars set." >&2 94 exit 1 95 fi 96 cat > netrc <<EOF 97 machine ${machineName} 98 login ''$${varBase}USERNAME 99 password ''$${varBase}PASSWORD 100 EOF 101 ''; 102 netrcImpureEnvVars = [ 103 "${varBase}USERNAME" 104 "${varBase}PASSWORD" 105 ]; 106 }; 107 108 gitRepoUrl = "${baseUrl}.git"; 109 110 revWithTag = if tag != null then "refs/tags/${tag}" else rev; 111 112 fetcherArgs = 113 ( 114 if useFetchGit then 115 { 116 inherit 117 tag 118 rev 119 deepClone 120 fetchSubmodules 121 sparseCheckout 122 fetchLFS 123 ; 124 url = gitRepoUrl; 125 } 126 // lib.optionalAttrs (leaveDotGit != null) { inherit leaveDotGit; } 127 else 128 { 129 # Use the API endpoint for private repos, as the archive URI doesn't 130 # support access with GitHub's fine-grained access tokens. 131 # 132 # Use the archive URI for non-private repos, as the API endpoint has 133 # relatively restrictive rate limits for unauthenticated users. 134 url = 135 if private then 136 let 137 endpoint = "/repos/${owner}/${repo}/tarball/${revWithTag}"; 138 in 139 if githubBase == "github.com" then 140 "https://api.github.com${endpoint}" 141 else 142 "https://${githubBase}/api/v3${endpoint}" 143 else 144 "${baseUrl}/archive/${revWithTag}.tar.gz"; 145 extension = "tar.gz"; 146 147 passthru = { 148 inherit gitRepoUrl; 149 }; 150 } 151 ) 152 // privateAttrs 153 // passthruAttrs 154 // { 155 inherit name; 156 }; 157 in 158 159 fetcher fetcherArgs 160 // { 161 meta = newMeta; 162 inherit owner repo tag; 163 rev = revWithTag; 164 } 165)