nixで最強パッケージ管理

Location of my configuration file

is ~/.config/nixpkgs/config.nix.

Overriding nix package

Probably you're trying to override a non-existing package.

For example, the following emits the error because emacs26 doesn't exist.

# ~/.config/nixpkgs/config.nix
{ pkgs }:
{
    allowBroken = true;
    allowUnfree = true;

    packageOverrides = pkgs : rec {
   	emacs26 = pkgs.stdenv.lib.overrideDerivation pkgs.emacs26 (oldAttrs : {
	    name = "emacs-26.1.92";
	    version = "26.1.92";
	    src = pkgs.fetchurl {
	        url = "https://alpha.gnu.org/gnu/emacs/pretest/emacs-26.1.92.tar.xz";
		    sha256 = "0aa1dfa39b020feb49b82a388863c8a4b2ee0f1dfc04528f49759dbba4f28d41";
		};
	});
  };
}

By changing the package name to emacs, it works.

UPDATE

overrideDerivation is almost depricated. Here's a better version:

self: super:
{
    emacs26 = super.emacs26.overrideAttrs (attrs: rec {
        name = "emacs-26.1.92";
        version = "26.1.92";
        src = super.fetchurl {
            url = "https://alpha.gnu.org/gnu/emacs/pretest/emacs-26.1.92.tar.xz";
            sha256 = "0aa1dfa39b020feb49b82a388863c8a4b2ee0f1dfc04528f49759dbba4f28d41";
        };
        patches = [];
    });
}

nixファイルの構造

nixファイルはnix式を定義するもの。

そもそもの関数の構文

x : x + 1
{ x, y }: x + y

これは一見、2引数関数のように見えるがコロンの位置からもそうではない。

ということで、例えばlet構文(式)なしで集合型の返値が計算できるなら

{ config, pkgs }:
{
	属性の定義式;
}

となるし、let構文を使いたいなら以下のようになる。

{ config, pkgs }:
let
  x = { ... };
  y = { ... };
  ...
in
  x

なお、2引数関数はoverlayで用いられている。

self: super:
...
with import <nixgkgs> {};   # この;は文を区切るものではなく、withは次の行まで続いている
  ...  # derivationを返すこと

A derivationを返すwith構文が一つあるだけ。with構文については後述。

with import <nixgkgs> {};
{ ... } # 集合を返す

pkgsを更新している?

モジュールとwith構文

ということで多くのファイルは以下の構造で単一の関数が定義されているだけ。

{ 依存するモジュール(カンマ区切り) }:
返値

オーバレイも ~/.config/nixpkgs/config.nix もこんな感じ。

{ pkgs }:
{
	...
}

ここでwith import <nixpkgs>を先頭に置いても問題ないはず。 試してみたところ、下のどちらの書き方でも正しく評価できる。

with import <inxpkgs>; self: super:
  ...
with import <inxpkgs> {}; self: super:
  ...

それどころか以下でも問題ない。

with import <inxpkgs> {} {}; self: super:
  ...

何故ならば、import <nixpkgs>関数:集合 -> 集合。 なので(import <inxpkgs>) {}は関数適用。もちろんその返値は集合を受け付ける関数。なので{}を受け付 ける。 そして評価が終わったimport <inxpkgs> {} {}までを環境として、セミコロン以下の本体を評価するのがwith 構文(式)。

S式で表せばこういうこと。

(with (((import <inxpkgs>) {}) {}) (self: super: ...))

うーん、ヘンタイ。