NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18.05k stars 14.08k forks source link

fetchurl changes file name #93520

Open davidak opened 4 years ago

davidak commented 4 years ago

Describe the bug When fetchurl get's a single file, it adds it to the nix store with a hash. That makes it hard to work with that file.

When installing it, it will have this messed up name.

To Reproduce Steps to reproduce the behavior:

stdenv.mkDerivation rec {
  pname = "agave";
  version = "16";

  src = fetchurl {
    url = "https://github.com/agarick/agave/releases/download/v${version}/Agave-Regular.ttf";
    sha256 = "0hd5l1d91iwkhdy96yljzjxfgyaszs4a0cnj4gs0181skndfwl87";
  };

...
[davidak@gaming:~]$ tree ~/.nix-profile/share/fonts/
/home/davidak/.nix-profile/share/fonts/
├── opentype -> /nix/store/1sldx0ry67bvr6nk7pblqdyl2yrr6lh1-fira-code-2/share/fonts/opentype
└── truetype
    ├── FiraCode-Bold.ttf -> /nix/store/1sldx0ry67bvr6nk7pblqdyl2yrr6lh1-fira-code-2/share/fonts/truetype/FiraCode-Bold.ttf
    ├── FiraCode-Light.ttf -> /nix/store/1sldx0ry67bvr6nk7pblqdyl2yrr6lh1-fira-code-2/share/fonts/truetype/FiraCode-Light.ttf
    ├── FiraCode-Medium.ttf -> /nix/store/1sldx0ry67bvr6nk7pblqdyl2yrr6lh1-fira-code-2/share/fonts/truetype/FiraCode-Medium.ttf
    ├── FiraCode-Regular.ttf -> /nix/store/1sldx0ry67bvr6nk7pblqdyl2yrr6lh1-fira-code-2/share/fonts/truetype/FiraCode-Regular.ttf
    ├── FiraCode-Retina.ttf -> /nix/store/1sldx0ry67bvr6nk7pblqdyl2yrr6lh1-fira-code-2/share/fonts/truetype/FiraCode-Retina.ttf
    ├── FiraCode-VF.ttf -> /nix/store/1sldx0ry67bvr6nk7pblqdyl2yrr6lh1-fira-code-2/share/fonts/truetype/FiraCode-VF.ttf
    └── g52gpi5z9xy6i40pl20qwiajay2i3rzm-Agave-Regular.ttf -> /nix/store/ybh1bcvfygp3qpg6lxambvzb2cl4gma8-agave-16/share/fonts/truetype/g52gpi5z9xy6i40pl20qwiajay2i3rzm-Agave-Regular.ttf

2 directories, 7 files

Expected behavior It would help if fetchurl creates a folder, even for a single file.

Workaround

  src = fetchurl {
    url = "https://github.com/agarick/agave/releases/download/v${version}/Agave-Regular.ttf";
    downloadToTemp = true;
    recursiveHash = true;
    sha256 = "1d9651khizylqz15ixzyhawyzrl386l1ymsxb76s0j6j2acbhfii";
    postFetch = ''
      install -D $downloadedFile $out/Agave-Regular.ttf
    '';
  };
vcunat commented 4 years ago

If it's no longer a single file, the fixed-output hash of the result changes by definition, so we can't simply change the default there.

It could e.g. be a parameter that you'd pass to the fetchurl call in case you wanted. Perhaps it would be useful to even allow specifying a longer chain of directories (say, share/fonts/opentype in this case).

veprbl commented 4 years ago

There is a relevant stripHash bash function provided by stdenv.

stale[bot] commented 3 years ago

I marked this as stale due to inactivity. → More info

mausch commented 3 years ago

I get bitten by this frequently. Except for backward compatibility arguments is there really any reason to change file names in the first place?

vcunat commented 3 years ago

Simplicity, I'd say.

Not creating a "useless" directory. You can't have completely custom name directly under /nix/store/.

Also, if you put it into a directory, you can no longer use the plain hash you got e.g. from upstream website. At least unless you split it into two derivations: keep the fixed-output download as is and add another wrapper that just copies the file into the desired location, but that's even more complication and expenses.

stale[bot] commented 2 years ago

I marked this as stale due to inactivity. → More info

vimpostor commented 1 month ago

In the workaround, to avoid repeating the filename for postFetch, one can use:

pkgs.fetchurl rec {
    url = "https://github.com/path/to/your/single-file.ttf";
    hash = "sha256-YOURHASH";
    downloadToTemp = true;
    postFetch = "install -D $downloadedFile $out/" + builtins.baseNameOf url;
    recursiveHash = true;
}

Alternatively the same, but with builtins.fetchurl, which has the advantage that the provided hash is identical to the one you would get with sha256sum on the actual file, that you download:

pkgs.stdenv.mkDerivation rec {
    name = "YOURNAME";
    fetchurl = "https://github.com/path/to/your/single-file.ttf";
    src = builtins.fetchurl {
        url = fetchurl;
        name = "fetchurl";
        sha256 = "YOURHASH";
    };
    dontUnpack = true;
    installPhase = "install -D $src $out/" + builtins.baseNameOf fetchurl;
};