fetchFromGitHub: pass owner, repo, rev, tag to mkDerivation and make rev and tag overridable with <pkg>.overrideAttrs (#456751)

This commit is contained in:
Matt Sturgeon
2025-11-05 01:00:57 +00:00
committed by GitHub
4 changed files with 91 additions and 39 deletions
+33 -23
View File
@@ -20,6 +20,21 @@ let
appendShort = lib.optionalString ((builtins.match "[a-f0-9]*" rev) != null) "-${shortRev}";
in
"${lib.sources.urlToName url}${if append == "" then appendShort else append}";
getRevWithTag =
{
rev ? null,
tag ? null,
}:
if tag != null && rev != null then
throw "fetchgit requires one of either `rev` or `tag` to be provided (not both)."
else if tag != null then
"refs/tags/${tag}"
else if rev != null then
rev
else
# FIXME fetching HEAD if no rev or tag is provided is problematic at best
"HEAD";
in
lib.makeOverridable (
@@ -27,8 +42,8 @@ lib.makeOverridable (
constructDrv = stdenvNoCC.mkDerivation;
excludeDrvArgNames = [
# Passed via `passthru`
"tag"
# Additional stdenv.mkDerivation arguments from derived fetchers.
"derivationArgs"
# Hashes, handled by `lib.fetchers.withNormalizedHash`
# whose outputs contain outputHash* attributes.
@@ -47,7 +62,7 @@ lib.makeOverridable (
rev ? null,
name ? urlToName {
inherit url;
rev = lib.revOrTag rev tag;
rev = lib.revOrTag finalAttrs.revCustom finalAttrs.tag;
# when rootDir is specified, avoid invalidating the result when rev changes
append = if rootDir != "" then "-${lib.strings.sanitizeDerivationName rootDir}" else "";
},
@@ -84,6 +99,10 @@ lib.makeOverridable (
rootDir ? "",
# GIT_CONFIG_GLOBAL (as a file)
gitConfigFile ? config.gitConfigFile,
# Additional stdenvNoCC.mkDerivation arguments.
# It is typically for derived fetchers to pass down additional arguments,
# and the specified arguments have lower precedence than other mkDerivation arguments.
derivationArgs ? { },
}:
/*
@@ -113,29 +132,13 @@ lib.makeOverridable (
assert fetchTags -> leaveDotGit;
assert rootDir != "" -> !leaveDotGit;
let
revWithTag =
let
warningMsg = "fetchgit requires one of either `rev` or `tag` to be provided (not both).";
otherIsNull = other: lib.assertMsg (other == null) warningMsg;
in
if tag != null then
assert (otherIsNull rev);
"refs/tags/${tag}"
else if rev != null then
assert (otherIsNull tag);
rev
else
# FIXME fetching HEAD if no rev or tag is provided is problematic at best
"HEAD";
in
if builtins.isString sparseCheckout then
# Changed to throw on 2023-06-04
throw
"Please provide directories/patterns for sparse checkout as a list of strings. Passing a (multi-line) string is not supported any more."
else
{
derivationArgs
// {
inherit name;
builder = ./builder.sh;
@@ -170,7 +173,12 @@ lib.makeOverridable (
rootDir
gitConfigFile
;
rev = revWithTag;
inherit tag;
revCustom = rev;
rev = getRevWithTag {
inherit (finalAttrs) tag;
rev = finalAttrs.revCustom;
};
postHook =
if netrcPhase == null then
@@ -210,7 +218,6 @@ lib.makeOverridable (
passthru = {
gitRepoUrl = url;
inherit tag;
}
// passthru;
}
@@ -220,3 +227,6 @@ lib.makeOverridable (
inheritFunctionArgs = false;
}
)
// {
inherit getRevWithTag;
}
+32 -11
View File
@@ -11,7 +11,8 @@ lib.makeOverridable (
repo,
tag ? null,
rev ? null,
name ? repoRevToNameMaybe repo (lib.revOrTag rev tag) "github",
# TODO(@ShamrockLee): Add back after reconstruction with lib.extendMkDerivation
# name ? repoRevToNameMaybe finalAttrs.repo (lib.revOrTag finalAttrs.revCustom finalAttrs.tag) "github",
fetchSubmodules ? false,
leaveDotGit ? null,
deepClone ? false,
@@ -110,9 +111,8 @@ lib.makeOverridable (
gitRepoUrl = "${baseUrl}.git";
revWithTag = if tag != null then "refs/tags/${tag}" else rev;
fetcherArgs =
finalAttrs:
passthruAttrs
// (
if useFetchGit then
@@ -127,9 +127,19 @@ lib.makeOverridable (
;
url = gitRepoUrl;
inherit passthru;
derivationArgs = {
inherit
githubBase
owner
repo
;
};
}
// lib.optionalAttrs (leaveDotGit != null) { inherit leaveDotGit; }
else
let
revWithTag = finalAttrs.rev;
in
{
# Use the API endpoint for private repos, as the archive URI doesn't
# support access with GitHub's fine-grained access tokens.
@@ -139,7 +149,7 @@ lib.makeOverridable (
url =
if private then
let
endpoint = "/repos/${owner}/${repo}/tarball/${revWithTag}";
endpoint = "/repos/${finalAttrs.owner}/${finalAttrs.repo}/tarball/${revWithTag}";
in
if githubBase == "github.com" then
"https://api.github.com${endpoint}"
@@ -148,7 +158,19 @@ lib.makeOverridable (
else
"${baseUrl}/archive/${revWithTag}.tar.gz";
extension = "tar.gz";
derivationArgs = {
inherit
githubBase
owner
repo
tag
;
rev = fetchgit.getRevWithTag {
inherit (finalAttrs) tag;
rev = finalAttrs.revCustom;
};
revCustom = rev;
};
passthru = {
inherit gitRepoUrl;
}
@@ -157,14 +179,13 @@ lib.makeOverridable (
)
// privateAttrs
// {
inherit name;
# TODO(@ShamrockLee): Change back to `inherit name;` after reconstruction with lib.extendMkDerivation
name =
args.name
or (repoRevToNameMaybe finalAttrs.repo (lib.revOrTag finalAttrs.revCustom finalAttrs.tag) "github");
meta = newMeta;
};
in
fetcher fetcherArgs
// {
meta = newMeta;
inherit owner repo tag;
rev = revWithTag;
}
)
+10 -1
View File
@@ -60,6 +60,9 @@ lib.extendMkDerivation {
# Passed via passthru
"url"
# Additional stdenv.mkDerivation arguments from derived fetchers.
"derivationArgs"
# Hash attributes will be map to the corresponding outputHash*
"hash"
"sha1"
@@ -139,6 +142,11 @@ lib.extendMkDerivation {
# Additional packages needed as part of a fetch
nativeBuildInputs ? [ ],
# Additional stdenvNoCC.mkDerivation arguments.
# It is typically for derived fetchers to pass down additional arguments,
# and the specified arguments have lower precedence than other mkDerivation arguments.
derivationArgs ? { },
}@args:
let
@@ -228,7 +236,8 @@ lib.extendMkDerivation {
"${lib.head mirrorList}${lib.elemAt mirrorSplit 1}";
in
{
derivationArgs
// {
name =
if pname != null && version != null then
"${finalAttrs.pname}-${finalAttrs.version}"
+16 -4
View File
@@ -20,7 +20,7 @@ lib.extendMkDerivation {
excludeDrvArgNames = [
"extraPostFetch"
# TODO(@ShamrockLee): Move these arguments to derivationArgs when available.
# Pass via derivationArgs
"extension"
"stripRoot"
];
@@ -42,14 +42,19 @@ lib.extendMkDerivation {
# an appropriate unpacking tool.
extension ? null,
# Additional stdenvNoCC.mkDerivation arguments.
# It is typically for derived fetchers to pass down additional arguments,
# and the specified arguments have lower precedence than other mkDerivation arguments.
derivationArgs ? { },
# the rest are given to fetchurl as is
...
}@args:
let
tmpFilename =
if extension != null then
"download.${extension}"
if finalAttrs.extension != null then
"download.${finalAttrs.extension}"
else
baseNameOf (if url != "" then url else builtins.head urls);
in
@@ -81,7 +86,7 @@ lib.extendMkDerivation {
chmod -R +w "$unpackDir"
''
+ (
if stripRoot then
if finalAttrs.stripRoot then
''
if [ $(ls -A "$unpackDir" | wc -l) != 1 ]; then
echo "error: zip file must contain a single file or directory."
@@ -109,5 +114,12 @@ lib.extendMkDerivation {
'';
# ^ Remove non-owner write permissions
# Fixes https://github.com/NixOS/nixpkgs/issues/38649
derivationArgs = derivationArgs // {
inherit
extension
stripRoot
;
};
};
}