How to import fetchurl without an argument?

I have been trying to update an old package of mine, Marvin. This is my default.nix file for building it:

{
  lib,
  stdenv,
  fetchurl,
  dpkg,
  makeWrapper,
  coreutils,
  gawk,
  gnugrep,
  gnused,
  openjdk17,
}:

stdenv.mkDerivation rec {
  pname = "marvin";
  version = "24.3.126";

  src = fetchurl {
    name = "marvin-${version}.deb";
    url = "https://download.chemaxon.com/download?dl=%2Fdata%2Fdownload%2Fmarvinpro%2F${version}%2Fmarvinws_linux_${version}.deb";
    hash = "sha256-zE/9EaOsNJwzE4Doasm9N8QG4t7wDOxqpV/Nhc4p7Ws=";
  };

  nativeBuildInputs = [
    dpkg
    makeWrapper
  ];

  unpackPhase = ''
    dpkg-deb -x $src opt
  '';

  installPhase = ''
    wrapBin() {
      makeWrapper $1 $out/bin/$(basename $1) \
        --set INSTALL4J_JAVA_HOME "${openjdk17}" \
        --prefix PATH : ${
          lib.makeBinPath [
            coreutils
            gawk
            gnugrep
            gnused
          ]
        }
    }
    cp -r opt $out
    mkdir -p $out/bin $out/share/pixmaps $out/share/applications
    for name in LicenseManager MarvinSketch MarvinView; do
      wrapBin $out/opt/chemaxon/marvinsuite/$name
      ln -s {$out/opt/chemaxon/marvinsuite/.install4j,$out/share/pixmaps}/$name.png
    done
    for name in cxcalc cxtrain evaluate molconvert mview msketch; do
      wrapBin $out/opt/chemaxon/marvinsuite/bin/$name
    done
    ${lib.concatStrings (
      map
        (name: ''
          substitute ${./. + "/${name}.desktop"} $out/share/applications/${name}.desktop --subst-var out
        '')
        [
          "LicenseManager"
          "MarvinSketch"
          "MarvinView"
        ]
    )}
  '';

  meta = with lib; {
    description = "Chemical modelling, analysis and structure drawing program";
    homepage = "https://chemaxon.com/products/marvin";
    maintainers = with maintainers; [ fusion809 ];
    license = licenses.unfree;
    platforms = platforms.linux;
  };
}

This used to build fine, granted this was years ago that I last built it. From Update sha256 checksums in copied nixpkgs folder, I know that running nix-build -A marvin.fetch-deps should be part of how I update the sha256 checksums in this file. Unfortunately, running nix-build -A marvin.fetch-deps returns the error:

error: cannot evaluate a function that has an argument without a value ('fetchurl')
       Nix attempted to evaluate a function as a top level expression; in
       this case it must have its arguments supplied either by default
       values, or passed explicitly with '--arg' or '--argstr'. See
       https://nixos.org/manual/nix/stable/language/constructs.html#functions.
       at /home/fusion809/NixOS-configs/nixpkgs/marvin/default.nix:4:3:
            3|   stdenv,
            4|   fetchurl,
             |   ^
            5|   dpkg,

But if I omit this line, I get an error that fetchurl is undefined. So I’m kind of lost what I’m meant to do here.

You’re meant to callPackage the file, as I mentioned last time. Did you do so?

callPackage is part of my overlays.nix file. Given my default.nix file is actually the file that specifies how the package is built, I didn’t think it needed to callPackage in it. I thought it’d suffice to do so in overlays.nix. If you’re wondering what I mean, I just committed the changes I’ve made to my NixOS configs, so you can view them here.

callPackage passes in the attributes of pkgs into that function, so yes, you always need to callPackage it. nix otherwise has no idea what to pass into that function, which has several required arguments.

Okay. So which line of my default.nix file should I add callPackage? The RuneScape package in my overlay doesn’t have a callPackage line it and installs fine (can’t use nix-build on it though as it has no default.nix file), so this is surprising to me.

Not in the default.nix; you use callPackage in the file where you want to use it (or if you want to build it on the CLI, provide it there).

Okay, I need you to be more explicit as to what I do. I have tried renaming default.nix to package.nix and creating this default.nix file as it sounds like what you’re talking about:

let
  pkgs = import <nixpkgs> {};
in 
  marvin = pkgs.callPackage ./package.nix { };

(where did I get this code? I adapted it from the callPackage tutorial) but that just gives the error:

error: syntax error, unexpected '=', expecting end of file
       at /home/fusion809/NixOS-configs/nixpkgs/marvin/default.nix:4:10:
            3| in
            4|   marvin = pkgs.callPackage ./package.nix { };

I know it’s bad practice to use import <nixpkgs>, so I’ve also tried using import pkgs instead and that gave the same error.

I’ve also tried going to the top level of my NixOS-configs repo and running nix-build -A marvin.fetch-deps --expr "./overlays.nix" (as that has a callPackage line calling Marvin) but that gave the error:

error: the expression selected by the selection path 'marvin.fetch-deps' should be a set but is a path

I’ve also tried nix-build -A marvin.fetch-deps --expr "import ./overlays.nix" and that returned:

error: the expression selected by the selection path 'marvin.fetch-deps' should be a set but is a list

That’s because that’s not valid nix. Change the file to this:

let
  pkgs = import <nixpkgs> {};
in 
  pkgs.callPackage ./package.nix { };

Or this (and figure out how to build a specific attribute again, I think -A marvin?):

let
  pkgs = import <nixpkgs> {};
in {
  marvin = pkgs.callPackage ./package.nix { };
}

It’s quite possible your repository already contains a better way, but I can’t tell without seeing its contents. Manually running things against an overlay seems inadvisable for nix-build, though, overlays aren’t designed to be used like this.

For the non-flake commands you can instead pass pkgs as an argument to the entrypoint:

{ pkgs, ... }: pkgs.callPackage ./package.nix { };

Okay, I changed my default.nix to:

let
  pkgs = import <nixpkgs> {};
in {
  marvin = pkgs.callPackage ./package.nix { };
}

nix-build -A marvin.fetch-deps returns:

error: attribute 'fetch-deps' in selection path 'marvin.fetch-deps' not found

Here is my package.nix if it helps.

Not -A marvin.fetchdeps, your package doesn’t have a passthru.fetchdeps you could build.

Oh, interesting. So how do I update the checksums in my package.nix? That’s my whole intention in using nix-build -A marvin.fetch-deps.

Ah, right, you’re that post, sorry I got distracted by the message about invalid nix file contents.

fetch-deps is added to the passthru of some nix packages by their maintainers, some ecosystems like the dotnet one have generic implementations in their derivation builders.

stdenv.mkDerivation does not, though, and you didn’t write your own.

As such, you need to do the update manually. I would just replace the hashes with lib.fakeHash and see what nix gives me. You can also use the nix-prefetch scripts available in nixpkgs.

Or, well, I would use nvfetcher.

It’s curious that you stumbled upon fetch-deps, to be honest, afaict that is only used in dotnet packages, presumably to update hashes for packages in the dotnet dependencies. passthru.updateScript is how it’s generally handled, but even that can’t be run with nix-build.