Skip to content

Commit

Permalink
fetchgit{,hub}: add tag argument
Browse files Browse the repository at this point in the history
It's become a common pattern to use `rev = "refs/tags/${version}"` rather than
just `rev = version` to ensure that the tag gets fetched rather than a branch
that has the same name. This has so far been done using boilerplate though, so
let's add a simple abstraction to fetch a tag instead.
  • Loading branch information
Atemu committed Nov 14, 2024
1 parent f16fe7b commit 1892f03
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 5 deletions.
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. To fetch a tag, you should prefer to use the `tag` parameter however which achieves this in a safer way. 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
5 changes: 4 additions & 1 deletion pkgs/build-support/fetchgit/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ 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 ? if tag != null then tag else "HEAD" # FIXME fetching HEAD by default is problematic at best
, leaveDotGit ? deepClone
, outputHash ? lib.fakeHash, outputHashAlgo ? null
, fetchSubmodules ? true, deepClone ? false
, branchName ? null
Expand Down
11 changes: 8 additions & 3 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 ? if tag != null then "refs/tags/${tag}" else null
, name ? "source"
, fetchSubmodules ? false, leaveDotGit ? null
, deepClone ? false, private ? false, forceFetchGit ? false
, fetchLFS ? false
Expand All @@ -11,6 +14,8 @@ lib.makeOverridable (
, ... # For hash agility
}@args:

assert (lib.assertMsg (rev != null) "You must provide `fetchFromGitHub with a `rev` or `tag`.");

let

position = (if args.meta.description or null != null
Expand All @@ -24,7 +29,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,7 +58,7 @@ 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";
Expand Down

0 comments on commit 1892f03

Please sign in to comment.