Skip to content
Merged
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
5 changes: 4 additions & 1 deletion doc/build-helpers/fetchers.chapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,9 @@ Used with Subversion. Expects `url` to a Subversion directory, `rev`, and `hash`

Used with Git. Expects `url` to a Git repo, `rev`, and `hash`. `rev` in this case can be full the git commit id (SHA1 hash) or a tag name like `refs/tags/v1.0`.

If you want to fetch a tag you should pass the `tag` parameter instead of `rev` which has the same effect as setting `rev = "refs/tags"/${version}"`.
This is safer than just setting `rev = version` w.r.t. possible branch and tag name conflicts.

Additionally, the following optional arguments can be given:

*`fetchSubmodules`* (Boolean)
Expand Down Expand Up @@ -833,7 +836,7 @@ A number of fetcher functions wrap part of `fetchurl` and `fetchzip`. They are m

## `fetchFromGitHub` {#fetchfromgithub}

`fetchFromGitHub` expects four arguments. `owner` is a string corresponding to the GitHub user or organization that controls this repository. `repo` corresponds to the name of the software repository. These are located at the top of every GitHub HTML page as `owner`/`repo`. `rev` corresponds to the Git commit hash or tag (e.g `v1.0`) that will be downloaded from Git. Finally, `hash` corresponds to the hash of the extracted directory. Again, other hash algorithms are also available, but `hash` is currently preferred.
`fetchFromGitHub` expects four arguments. `owner` is a string corresponding to the GitHub user or organization that controls this repository. `repo` corresponds to the name of the software repository. These are located at the top of every GitHub HTML page as `owner`/`repo`. `rev` corresponds to the Git commit hash or tag (e.g `v1.0`) that will be downloaded from Git. If you need to fetch a tag however, you should prefer to use the `tag` parameter which achieves this in a safer way with less boilerplate. Finally, `hash` corresponds to the hash of the extracted directory. Again, other hash algorithms are also available, but `hash` is currently preferred.

To use a different GitHub instance, use `githubBase` (defaults to `"github.com"`).

Expand Down
30 changes: 26 additions & 4 deletions pkgs/build-support/fetchgit/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@ in
lib.makeOverridable (lib.fetchers.withNormalizedHash { } (
# NOTE Please document parameter additions or changes in
# doc/build-helpers/fetchers.chapter.md
{ url, rev ? "HEAD", leaveDotGit ? deepClone
{ url
, tag ? null
, rev ? null
, leaveDotGit ? deepClone
, outputHash ? lib.fakeHash, outputHashAlgo ? null
, fetchSubmodules ? true, deepClone ? false
, branchName ? null
, sparseCheckout ? []
, nonConeMode ? false
, name ? urlToName url rev
, name ? null
, # Shell code executed after the file has been fetched
# successfully. This can do things like check or transform the file.
postFetch ? ""
Expand Down Expand Up @@ -59,12 +62,30 @@ lib.makeOverridable (lib.fetchers.withNormalizedHash { } (
assert deepClone -> leaveDotGit;
assert nonConeMode -> (sparseCheckout != []);

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
stdenvNoCC.mkDerivation {
inherit name;
name = if name != null then name else urlToName url revWithTag;

builder = ./builder.sh;
fetcher = ./nix-prefetch-git;

Expand All @@ -79,7 +100,8 @@ stdenvNoCC.mkDerivation {
# > from standard in as a newline-delimited list instead of from the arguments.
sparseCheckout = builtins.concatStringsSep "\n" sparseCheckout;

inherit url rev leaveDotGit fetchLFS fetchSubmodules deepClone branchName nonConeMode postFetch;
inherit url leaveDotGit fetchLFS fetchSubmodules deepClone branchName nonConeMode postFetch;
rev = revWithTag;

postHook = if netrcPhase == null then null else ''
${netrcPhase}
Expand Down
18 changes: 13 additions & 5 deletions pkgs/build-support/fetchgithub/default.nix
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{ lib, fetchgit, fetchzip }:

lib.makeOverridable (
{ owner, repo, rev, name ? "source"
{ owner, repo
, tag ? null
, rev ? null
, name ? "source"
, fetchSubmodules ? false, leaveDotGit ? null
, deepClone ? false, private ? false, forceFetchGit ? false
, fetchLFS ? false
Expand All @@ -11,11 +14,16 @@ lib.makeOverridable (
, ... # For hash agility
}@args:

assert (lib.assertMsg (lib.xor (tag == null) (rev == null)) "fetchFromGitHub requires one of either `rev` or `tag` to be provided (not both).");

let

position = (if args.meta.description or null != null
then builtins.unsafeGetAttrPos "description" args.meta
else builtins.unsafeGetAttrPos "rev" args
else if tag != null then
builtins.unsafeGetAttrPos "tag" args
else
builtins.unsafeGetAttrPos "rev" args
);
baseUrl = "https://${githubBase}/${owner}/${repo}";
newMeta = meta // {
Expand All @@ -24,7 +32,7 @@ let
# to indicate where derivation originates, similar to make-derivation.nix's mkDerivation
position = "${position.file}:${toString position.line}";
};
passthruAttrs = removeAttrs args [ "owner" "repo" "rev" "fetchSubmodules" "forceFetchGit" "private" "githubBase" "varPrefix" ];
passthruAttrs = removeAttrs args [ "owner" "repo" "tag" "rev" "fetchSubmodules" "forceFetchGit" "private" "githubBase" "varPrefix" ];
varBase = "NIX${lib.optionalString (varPrefix != null) "_${varPrefix}"}_GITHUB_PRIVATE_";
useFetchGit = fetchSubmodules || (leaveDotGit == true) || deepClone || forceFetchGit || fetchLFS || (sparseCheckout != []);
# We prefer fetchzip in cases we don't need submodules as the hash
Expand Down Expand Up @@ -53,10 +61,10 @@ let

fetcherArgs = (if useFetchGit
then {
inherit rev deepClone fetchSubmodules sparseCheckout fetchLFS; url = gitRepoUrl;
inherit tag rev deepClone fetchSubmodules sparseCheckout fetchLFS; url = gitRepoUrl;
} // lib.optionalAttrs (leaveDotGit != null) { inherit leaveDotGit; }
else {
url = "${baseUrl}/archive/${rev}.tar.gz";
url = "${baseUrl}/archive/${if tag != null then "refs/tags/${tag}" else rev}.tar.gz";

passthru = {
inherit gitRepoUrl;
Expand Down