Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

builtins.fetchGit’s return value should have a url attribute #11222

Open
Jayman2000 opened this issue Jul 30, 2024 · 3 comments
Open

builtins.fetchGit’s return value should have a url attribute #11222

Jayman2000 opened this issue Jul 30, 2024 · 3 comments
Labels
feature Feature request or proposal fetching Networking with the outside (non-Nix) world, input locking

Comments

@Jayman2000
Copy link
Contributor

Is your feature request related to a problem? Please describe.

  1. Create a file named package.nix that contains this:

    let
      pkgs = import <nixpkgs> { };
      url = "https://github.com/commonmark/cmark";
    in
    
    pkgs.stdenv.mkDerivation (finalAttrs: {
      pname = "cmark";
      version = "0.30.3";
      src = builtins.fetchGit {
        inherit url;
        ref = "refs/tags/${finalAttrs.version}";
      };
      nativeBuildInputs = [ pkgs.cmake ];
    })
  2. Create a file named default.nix that contains this:

    { }:
    
    {
      cmark = import ./package.nix;
    }
  3. Try running nix-update:

    nix-shell -p nix-update --run 'nix-update cmark'

    It will fail with this error:

    nix_update.errors.UpdateError: Could not find a url in the derivations src attribute
    

Describe the solution you'd like
It would be nice if the return value of builtins.fetchGit had a url attribute. That would allow downstream processors of Nix expressions to do things with the Git repo’s URL.

Describe alternatives you've considered
Here’s a workaround:

let
  pkgs = import <nixpkgs> { };
  url = "https://github.com/commonmark/cmark";
in

pkgs.stdenv.mkDerivation (finalAttrs: {
  pname = "cmark";
  version = "0.30.3";
  src = (builtins.fetchGit {
    inherit url;
    ref = "refs/tags/${finalAttrs.version}";
  }) // {
    inherit url;
  };
  nativeBuildInputs = [ pkgs.cmake ];
})

Additional context
I’m currently working on a nixpkgs PR that’s related to vcpkg. In order for certain features of vcpkg to work properly, we need to know the commit hash for the version of vcpkg that we’re building. I proposed using builtins.fetchGit for this purpose because its return value has a rev attribute that contains the commit hash. Another contributor was concerned that automatic updates might stop working if we switched to builtins.fetchGit. I’m submitting this feature request because I want automatic updates to work regardless of whether or not we’re using builtins.fetchGit.

Priorities

Add 👍 to issues you find important.

@Jayman2000 Jayman2000 added the feature Feature request or proposal label Jul 30, 2024
@roberth
Copy link
Member

roberth commented Jul 31, 2024

Sources are generally best fetched with a fixed output derivation, such as produced by pkgs.fetchgit.
They have the benefit that they don't block evaluation, and they're optimized away entirely when the outputs of the actual build are available in a binary cache.

We do make exceptions for sources that contain Nix expressions we need to evaluate (to avoid blocking on builds (IFD); a reason why Flakes also uses this mechanism) or when the remote requires authentication.

I think the reason the URL is not present is to avoid accidental dependencies on "implementation details", but personally I'm not opposed to adding it.

@roberth roberth added the fetching Networking with the outside (non-Nix) world, input locking label Jul 31, 2024
@Jayman2000
Copy link
Contributor Author

Sources are generally best fetched with a fixed output derivation, such as produced by pkgs.fetchgit.

Hmmm. I would use pkgs.fetchgit, but I don’t really know how to make it work in the case of vcpkg. Specifically, this expression:

(builtins.fetchGit {
  url = "https://github.com/microsoft/vcpkg";
  ref = "refs/tags/2024.07.12";
}).rev

evaluates to "1de2026f28ead93ff1773e6e680387643e914ea1", but this expression:

(pkgs.fetchgit {
  url = "https://github.com/microsoft/vcpkg";
  rev = "refs/tags/2024.07.12";
}).rev

evaluates to "refs/tags/2024.07.12". Is there any way to use a fixed output derivation in order to convert a version number into a hash?

Also, why does one of the two functions produce a fixed output derivation but not the other?

@Qyriad
Copy link
Member

Qyriad commented Aug 1, 2024

Also, why does one of the two functions produce a fixed output derivation but not the other?

From Nixpkgs Manual § Fetchers:

Nix provides built-in fetchers such as builtins.fetchTarball. Nixpkgs provides its own fetchers, which work differently:

  • A built-in fetcher will download and cache files at evaluation time and produce a store path. A Nixpkgs fetcher will create a (fixed-output) derivation, and files are downloaded at build time.

builtins.fetchGit is a builtin fetcher, and all builtin fetchers do their fetch inside the Nix interpreter and during evaluation of the Nix expression, whereas fixed-output derivations are mostly like any other derivation: a description of commands to run when the derivation is built. nix eval --impure --expr 'builtins.fetchGit { … }' will fetch something, but nix eval --impure --expr 'with import <nixpkgs> { }; fetchgit { … }' will instantiate a derivation, but not fetch anything yet.

@roberth roberth changed the title builtins.fetcGit’s return value should have a url attribute builtins.fetchGit’s return value should have a url attribute Oct 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Feature request or proposal fetching Networking with the outside (non-Nix) world, input locking
Projects
None yet
Development

No branches or pull requests

3 participants