nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 213 lines 6.8 kB view raw
1{ 2 lib, 3 repoRevToNameMaybe, 4 fetchgit, 5 fetchzip, 6}: 7let 8 # Here defines fetchFromGitHub arguments that determines useFetchGit, 9 # The attribute value is their default values. 10 # As fetchFromGitHub prefers fetchzip for hash stability, 11 # `defaultFetchGitArgs` attributes should lead to `useFetchGit = false`. 12 useFetchGitArgsDefault = { 13 deepClone = false; 14 fetchSubmodules = false; # This differs from fetchgit's default 15 fetchLFS = false; 16 forceFetchGit = false; 17 leaveDotGit = null; 18 postCheckout = ""; 19 rootDir = ""; 20 sparseCheckout = null; 21 }; 22 useFetchGitArgsDefaultNullable = { 23 leaveDotGit = false; 24 sparseCheckout = [ ]; 25 }; 26 27 useFetchGitargsDefaultNonNull = useFetchGitArgsDefault // useFetchGitArgsDefaultNullable; 28 29 # useFetchGitArgsWD to exclude from automatic passing. 30 # Other useFetchGitArgsWD will pass down to fetchgit. 31 excludeUseFetchGitArgNames = [ 32 "forceFetchGit" 33 ]; 34 35 faUseFetchGit = lib.mapAttrs (_: _: true) useFetchGitArgsDefault; 36 37 adjustFunctionArgs = f: lib.setFunctionArgs f (faUseFetchGit // lib.functionArgs f); 38 39 decorate = f: lib.makeOverridable (adjustFunctionArgs f); 40in 41decorate ( 42 { 43 owner, 44 repo, 45 tag ? null, 46 rev ? null, 47 # TODO(@ShamrockLee): Add back after reconstruction with lib.extendMkDerivation 48 # name ? repoRevToNameMaybe finalAttrs.repo (lib.revOrTag finalAttrs.revCustom finalAttrs.tag) "github", 49 private ? false, 50 githubBase ? "github.com", 51 varPrefix ? null, 52 passthru ? { }, 53 meta ? { }, 54 ... # For hash agility and additional fetchgit arguments 55 }@args: 56 57 assert ( 58 lib.assertMsg (lib.xor (tag == null) ( 59 rev == null 60 )) "fetchFromGitHub requires one of either `rev` or `tag` to be provided (not both)." 61 ); 62 63 let 64 useFetchGit = 65 lib.mapAttrs ( 66 name: nonNullDefault: 67 if args ? ${name} && (useFetchGitArgsDefaultNullable ? ${name} -> args.${name} != null) then 68 args.${name} 69 else 70 nonNullDefault 71 ) useFetchGitargsDefaultNonNull != useFetchGitargsDefaultNonNull; 72 73 useFetchGitArgsWDPassing = lib.overrideExisting (removeAttrs useFetchGitArgsDefault excludeUseFetchGitArgNames) args; 74 75 position = ( 76 if args.meta.description or null != null then 77 builtins.unsafeGetAttrPos "description" args.meta 78 else if tag != null then 79 builtins.unsafeGetAttrPos "tag" args 80 else 81 builtins.unsafeGetAttrPos "rev" args 82 ); 83 baseUrl = "https://${githubBase}/${owner}/${repo}"; 84 newMeta = 85 meta 86 // { 87 homepage = meta.homepage or baseUrl; 88 } 89 // lib.optionalAttrs (position != null) { 90 # to indicate where derivation originates, similar to make-derivation.nix's mkDerivation 91 position = "${position.file}:${toString position.line}"; 92 }; 93 passthruAttrs = removeAttrs args ( 94 [ 95 "owner" 96 "repo" 97 "tag" 98 "rev" 99 "private" 100 "githubBase" 101 "varPrefix" 102 ] 103 ++ (if useFetchGit then excludeUseFetchGitArgNames else lib.attrNames faUseFetchGit) 104 ); 105 varBase = "NIX${lib.optionalString (varPrefix != null) "_${varPrefix}"}_GITHUB_PRIVATE_"; 106 # We prefer fetchzip in cases we don't need submodules as the hash 107 # is more stable in that case. 108 fetcher = 109 if useFetchGit then 110 fetchgit 111 # fetchzip may not be overridable when using external tools, for example nix-prefetch 112 else if fetchzip ? override then 113 fetchzip.override { withUnzip = false; } 114 else 115 fetchzip; 116 privateAttrs = lib.optionalAttrs private { 117 netrcPhase = 118 # When using private repos: 119 # - Fetching with git works using https://github.com but not with the GitHub API endpoint 120 # - Fetching a tarball from a private repo requires to use the GitHub API endpoint 121 let 122 machineName = if githubBase == "github.com" && !useFetchGit then "api.github.com" else githubBase; 123 in 124 '' 125 if [ -z "''$${varBase}USERNAME" -o -z "''$${varBase}PASSWORD" ]; then 126 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 127 exit 1 128 fi 129 cat > netrc <<EOF 130 machine ${machineName} 131 login ''$${varBase}USERNAME 132 password ''$${varBase}PASSWORD 133 EOF 134 ''; 135 netrcImpureEnvVars = [ 136 "${varBase}USERNAME" 137 "${varBase}PASSWORD" 138 ]; 139 }; 140 141 gitRepoUrl = "${baseUrl}.git"; 142 143 fetcherArgs = 144 finalAttrs: 145 passthruAttrs 146 // ( 147 if useFetchGit then 148 useFetchGitArgsWDPassing 149 // { 150 inherit tag rev; 151 url = gitRepoUrl; 152 inherit passthru; 153 derivationArgs = { 154 inherit 155 githubBase 156 owner 157 repo 158 ; 159 }; 160 } 161 else 162 let 163 revWithTag = finalAttrs.rev; 164 in 165 { 166 # Use the API endpoint for private repos, as the archive URI doesn't 167 # support access with GitHub's fine-grained access tokens. 168 # 169 # Use the archive URI for non-private repos, as the API endpoint has 170 # relatively restrictive rate limits for unauthenticated users. 171 url = 172 if private then 173 let 174 endpoint = "/repos/${finalAttrs.owner}/${finalAttrs.repo}/tarball/${revWithTag}"; 175 in 176 if githubBase == "github.com" then 177 "https://api.github.com${endpoint}" 178 else 179 "https://${githubBase}/api/v3${endpoint}" 180 else 181 "${baseUrl}/archive/${revWithTag}.tar.gz"; 182 extension = "tar.gz"; 183 derivationArgs = { 184 inherit 185 githubBase 186 owner 187 repo 188 tag 189 ; 190 rev = fetchgit.getRevWithTag { 191 inherit (finalAttrs) tag; 192 rev = finalAttrs.revCustom; 193 }; 194 revCustom = rev; 195 }; 196 passthru = { 197 inherit gitRepoUrl; 198 } 199 // passthru; 200 } 201 ) 202 // privateAttrs 203 // { 204 # TODO(@ShamrockLee): Change back to `inherit name;` after reconstruction with lib.extendMkDerivation 205 name = 206 args.name 207 or (repoRevToNameMaybe finalAttrs.repo (lib.revOrTag finalAttrs.revCustom finalAttrs.tag) "github"); 208 meta = newMeta; 209 }; 210 in 211 212 fetcher fetcherArgs 213)