Skip to content

URL cache resolution broken with newer Nix versions #40

Open
@infinisil

Description

@infinisil

Description

nix-zsh-completions substitutes channel: and https:// entries in NIX_PATH with cached versions thereof. To do that it uses this function:

https://github.com/spwhitt/nix-zsh-completions/blob/468d8cf752a62b877eba1a196fbbebb4ce4ebb6f/_nix-common-options#L338-L356

However this function doesn't work anymore, because it relies on ~/.cache/nix/tarballs, which isn't getting populated anymore since Nix version 2.4. Nix now uses an sqlite database instead to store information on cached tarballs, this was changed in this commit: NixOS/nix@462421d

The effect of this is that (with an empty ~/.cache/nix/tarballs), any channel: and https:// entry on NIX_PATH gets replaced with an empty string, breaking evaluation if you depend on those. There is also no error message indicating a failed evaluation.

Reproduction steps

Assuming a zsh with nix-zsh-completions installed

  1. Create a default.nix file containing

    import <nixpkgs> {}
  2. Set NIX_PATH to contain a channel: or https:// entry:

    $ export NIX_PATH=nixpkgs=channel:nixpkgs-unstable
    
  3. Make sure the entry is fetched and cached:

    $ nix-instantiate -A hello
    warning: you did not specify '--add-root'; the result might be removed by the garbage collector
    /nix/store/2nlfpvl89vc9jq2vli9mni3xfylcfqpm-hello-2.12.drv
    
  4. Try to tab complete:

    $ nix-instantiate -A <TAB>
    
  5. Notice that tab completion doesn't work, without printing any error message

Completion trace

+_nix_attr_paths:24> result=          +_nix_attr_paths:24> _nix_eval_stdin
 +_nix_eval_stdin:1> setopt local_options pipefail
 +_nix_eval_stdin:3> local i override=''
 +_nix_eval_stdin:4> i=1
 +_nix_eval_stdin:4> i < 3
 +_nix_eval_stdin:5> case nix-instantiate (-I | --include)
 +_nix_eval_stdin:4> i++
 +_nix_eval_stdin:4> i < 3
 +_nix_eval_stdin:5> case -A (-I | --include)
 +_nix_eval_stdin:4> i++
 +_nix_eval_stdin:4> i < 3
 +_nix_eval_stdin:11> override+='nixpkgs=channel:nixpkgs-unstable' 
 +_nix_eval_stdin:14> [[ 'nixpkgs=channel:nixpkgs-unstable' == *(=|:)channel:* ]]
 +_nix_eval_stdin:15> local channel=nixpkgs-unstable
 +_nix_eval_stdin:16> channel=channel:nixpkgs-unstable 
 +_nix_eval_stdin:17> local url=https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz
 +_nix_eval_stdin:19> override='nixpkgs=https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz' 
 +_nix_eval_stdin:14> [[ 'nixpkgs=https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz' == *(=|:)channel:* ]]
 +_nix_eval_stdin:23> [[ 'nixpkgs=https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz' == *https://* ]]
 +_nix_eval_stdin:25> local url=nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz
 +_nix_eval_stdin:27> url=https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz 
 +_nix_eval_stdin:28> _nix_resolve_url https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz
  +_nix_resolve_url:1> local url=https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz
  +_nix_resolve_url:2> nix-instantiate --version
  +_nix_resolve_url:2> local version='nix-instantiate (Nix) 2.9.0'
  +_nix_resolve_url:3> local input
  +_nix_resolve_url:4> [[ 2.9.0 == 1.11.* ]]
  +_nix_resolve_url:9> input='nixexprs.tar.xz\0https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz' 
  +_nix_resolve_url:11> local sha
  +_nix_resolve_url:12> sha=            +_nix_resolve_url:12> printf 'nixexprs.tar.xz\0https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz'
  +_nix_resolve_url:12> sha=            +_nix_resolve_url:12> nix-hash --flat --base32 --type sha256 /proc/self/fd/27
  +_nix_resolve_url:12> sha=12zgms82w6c4ykwa6bfji5ykg68c5z306lim2qa6ch71zd04p10m 
  +_nix_resolve_url:13> local cache=/home/infinisil/.cache/nix/tarballs
  +_nix_resolve_url:14> local link=/home/infinisil/.cache/nix/tarballs/12zgms82w6c4ykwa6bfji5ykg68c5z306lim2qa6ch71zd04p10m-file
  +_nix_resolve_url:15> [[ -e /home/infinisil/.cache/nix/tarballs/12zgms82w6c4ykwa6bfji5ykg68c5z306lim2qa6ch71zd04p10m-file ]]
 +_nix_eval_stdin:28> local cache=''
 +_nix_eval_stdin:30> override='nixpkgs=' 
 +_nix_eval_stdin:23> [[ 'nixpkgs=' == *https://* ]]
 +_nix_eval_stdin:33> NIX_PATH='nixpkgs=' nix-instantiate --eval -
 +_nix_eval_stdin:33> tr '[]"' ' '
 +_nix_eval_stdin:34> return 1
+_nix_attr_paths:24> result=( ) 
+_nix_attr_paths:48> [[ 1 > 0 ]]
+_nix_attr_paths:49> _message $'Eval failed, can\'t complete (an URL might not be cached):\n'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions