Dynamically calculate the value of a string in nixpkgs

My flake starts like this:

{
  inputs = {
    ownpkgs.url = "github:b521f771d8991e6f1d8e65ae05a8d783/nixpkgs/stable";
    nixpkgs.url = "github:NixOS/nixpkgs";
    flake-utils.url = "github:b521f771d8991e6f1d8e65ae05a8d783/flake-utils";
    
    rusty_v8 = {
      url = ("https://github.com/denoland/rusty_v8/releases/download/"
        + (builtins.head (builtins.filter (p: p.name == "v8") ((builtins.fromTOML (builtins.readFile ./Cargo.lock)).package))).version
        + "/librusty_v8_release_x86_64-unknown-linux-gnu.a.gz");
      flake = false;
    };
  };

 ...
}

What I want is to calculate the URL automatically based on the version of rusty_v8 that is used in the Cargo.lock. Currently, I am getting the following error:

error:
       … while evaluating flake attribute 'url'
         at /nix/store/dmm4m3j9cl00pr1fblxz34415lgh3bi1-source/flake.nix:10:7:
            9|     rusty_v8 = {
           10|       url = ("https://github.com/denoland/rusty_v8/releases/download/"
             |       ^
           11|         + (builtins.head (builtins.filter (p: p.name == "v8") ((builtins.fromTOML (builtins.readFile ./Cargo.lock)).package))).version

       error: expected a string or a path but got a thunk at /nix/store/dmm4m3j9cl00pr1fblxz34415lgh3bi1-source/flake.nix:10:7

I understand that flake.nix is just a subset of nix (the code to parse the toml works in REPL). Any suggestions on how to fix this?

As far as I know this is simply not possible in the inputs section of a flake.

1 Like

Correct, so there’s your answer. It’s explicitly disallowed.

Don’t use flakes for this, or write the string out.
Or use some kind of pre-processor to generate the flake.nix, but that just seems atrocious ux-wise.

1 Like

This seems like something you’d rather have outside of the inputs, since it’s entirely dependent on an external lock file. Move it to whatever is using it in outputs.

1 Like

Sure, but then they have to provide a hash in pure-eval mode, so I don’t think it’s workable without preprocessing.

I still say the answer is to just… not use flakes.

1 Like

I thought so too, but as @waffle8946 pointed out, that would only further complicate things

Eh, it’s not that bad. Looks like a perfectly normal github release, you can almost certainly use a normal fetchFromGitHub and nix-update.

Personally I hook these up to passthru.updateScript and just have a script that calls nix run on the updateScript of all my packages outputs.

… does that qualify as “not using flakes”? I guess moving the input URL definition to the outputs section inherently means that.

1 Like