From cf666635344035021d13d70de8409d52bf69fbcb Mon Sep 17 00:00:00 2001 From: Toast Date: Tue, 10 Dec 2024 00:27:15 +0100 Subject: [PATCH] Flake: add nixpkgs pr --- flake.nix | 1 + nixpkgs-patches/pr355973.patch | 213 +++++++++++++++++++++++++++++++++ 2 files changed, 214 insertions(+) create mode 100644 nixpkgs-patches/pr355973.patch diff --git a/flake.nix b/flake.nix index f705a0d..6d54e22 100644 --- a/flake.nix +++ b/flake.nix @@ -101,6 +101,7 @@ patches = [ ./nixpkgs-patches/pr359282.patch ./nixpkgs-patches/pr361364.patch + ./nixpkgs-patches/pr355973.patch ]; }; nixpkgs-patched = nixpkgs-raw.legacyPackages.x86_64-linux.applyPatches { diff --git a/nixpkgs-patches/pr355973.patch b/nixpkgs-patches/pr355973.patch new file mode 100644 index 0000000..579b9d2 --- /dev/null +++ b/nixpkgs-patches/pr355973.patch @@ -0,0 +1,213 @@ +From cb9f9a1e5a51a87d59b373db7016cee1608debd5 Mon Sep 17 00:00:00 2001 +From: Atemu +Date: Thu, 14 Nov 2024 20:07:25 +0100 +Subject: [PATCH 1/2] fetchgit{,hub}: add tag argument + +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. +--- + doc/build-helpers/fetchers.chapter.md | 5 ++++- + pkgs/build-support/fetchgit/default.nix | 5 ++++- + pkgs/build-support/fetchgithub/default.nix | 11 ++++++++--- + 3 files changed, 16 insertions(+), 5 deletions(-) + +diff --git a/doc/build-helpers/fetchers.chapter.md b/doc/build-helpers/fetchers.chapter.md +index d37a2fecaccda..567d47a1499be 100644 +--- a/doc/build-helpers/fetchers.chapter.md ++++ b/doc/build-helpers/fetchers.chapter.md +@@ -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) +@@ -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"`). + +diff --git a/pkgs/build-support/fetchgit/default.nix b/pkgs/build-support/fetchgit/default.nix +index 4c40cbcef7e16..6f4cbba982a0e 100644 +--- a/pkgs/build-support/fetchgit/default.nix ++++ b/pkgs/build-support/fetchgit/default.nix +@@ -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 "refs/tags/${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 +diff --git a/pkgs/build-support/fetchgithub/default.nix b/pkgs/build-support/fetchgithub/default.nix +index d27a3df7d3df7..de9912465a937 100644 +--- a/pkgs/build-support/fetchgithub/default.nix ++++ b/pkgs/build-support/fetchgithub/default.nix +@@ -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 +@@ -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 +@@ -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 +@@ -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"; + +From e9a31f51468e43aaf8df79d10dca5a3d6447877b Mon Sep 17 00:00:00 2001 +From: Atemu +Date: Wed, 4 Dec 2024 01:37:01 +0100 +Subject: [PATCH 2/2] fetchgit{,hub}: assert illegal tag + rev combinations + +It's quite a bit more complex due to this but this was asked for during review +--- + pkgs/build-support/fetchgit/default.nix | 27 ++++++++++++++++++---- + pkgs/build-support/fetchgithub/default.nix | 11 +++++---- + 2 files changed, 30 insertions(+), 8 deletions(-) + +diff --git a/pkgs/build-support/fetchgit/default.nix b/pkgs/build-support/fetchgit/default.nix +index 6f4cbba982a0e..f2b4726fef09d 100644 +--- a/pkgs/build-support/fetchgit/default.nix ++++ b/pkgs/build-support/fetchgit/default.nix +@@ -15,14 +15,14 @@ lib.makeOverridable (lib.fetchers.withNormalizedHash { } ( + # doc/build-helpers/fetchers.chapter.md + { url + , tag ? null +-, rev ? if tag != null then "refs/tags/${tag}" else "HEAD" # FIXME fetching HEAD by default is problematic at best ++, 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 ? "" +@@ -62,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; + +@@ -82,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} +diff --git a/pkgs/build-support/fetchgithub/default.nix b/pkgs/build-support/fetchgithub/default.nix +index de9912465a937..f80e012955336 100644 +--- a/pkgs/build-support/fetchgithub/default.nix ++++ b/pkgs/build-support/fetchgithub/default.nix +@@ -3,7 +3,7 @@ + lib.makeOverridable ( + { owner, repo + , tag ? null +-, rev ? if tag != null then "refs/tags/${tag}" else null ++, rev ? null + , name ? "source" + , fetchSubmodules ? false, leaveDotGit ? null + , deepClone ? false, private ? false, forceFetchGit ? false +@@ -14,13 +14,16 @@ lib.makeOverridable ( + , ... # For hash agility + }@args: + +-assert (lib.assertMsg (rev != null) "You must provide `fetchFromGitHub with a `rev` or `tag`."); ++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 // { +@@ -61,7 +64,7 @@ let + 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;